2 Entrypoint of Opal UEFI Driver and contains all the logic to
3 register for new Opal device instances.
5 Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 // This UEFI driver consumes EFI_STORAGE_SECURITY_PROTOCOL instances and installs an
17 // HII GUI to manage Opal features if the device is Opal capable
18 // If the Opal device is being managed by the UEFI Driver, it shall provide a popup
19 // window during boot requesting a user password
21 #include "OpalDriver.h"
24 EFI_GUID mOpalDeviceAtaGuid
= OPAL_DEVICE_ATA_GUID
;
25 EFI_GUID mOpalDeviceNvmeGuid
= OPAL_DEVICE_NVME_GUID
;
27 BOOLEAN mOpalEndOfDxe
= FALSE
;
28 OPAL_REQUEST_VARIABLE
*mOpalRequestVariable
= NULL
;
29 UINTN mOpalRequestVariableSize
= 0;
30 CHAR16 mPopUpString
[100];
34 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
35 } OPAL_HC_PCI_REGISTER_SAVE
;
38 // To unlock the Intel SATA controller at S3 Resume, restored the following registers.
40 const OPAL_HC_PCI_REGISTER_SAVE mSataHcRegisterSaveTemplate
[] = {
41 {0x9, S3BootScriptWidthUint8
},
42 {0x10, S3BootScriptWidthUint32
},
43 {0x14, S3BootScriptWidthUint32
},
44 {0x18, S3BootScriptWidthUint32
},
45 {0x1C, S3BootScriptWidthUint32
},
46 {0x20, S3BootScriptWidthUint32
},
47 {0x24, S3BootScriptWidthUint32
},
48 {0x3c, S3BootScriptWidthUint8
},
49 {0x3d, S3BootScriptWidthUint8
},
50 {0x40, S3BootScriptWidthUint16
},
51 {0x42, S3BootScriptWidthUint16
},
52 {0x92, S3BootScriptWidthUint16
},
53 {0x94, S3BootScriptWidthUint32
},
54 {0x9C, S3BootScriptWidthUint32
},
55 {0x4, S3BootScriptWidthUint16
},
58 OPAL_DRIVER mOpalDriver
;
63 EFI_DRIVER_BINDING_PROTOCOL gOpalDriverBinding
= {
64 OpalEfiDriverBindingSupported
,
65 OpalEfiDriverBindingStart
,
66 OpalEfiDriverBindingStop
,
74 The function determines the available actions for the OPAL_DISK provided.
76 @param[in] SupportedAttributes The supported attributes for the device.
77 @param[in] LockingFeature The locking status for the device.
78 @param[in] OwnerShip The ownership for the device.
79 @param[out] AvalDiskActions Pointer to fill-out with appropriate disk actions.
84 OpalSupportGetAvailableActions(
85 IN OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
,
86 IN TCG_LOCKING_FEATURE_DESCRIPTOR
*LockingFeature
,
88 OUT OPAL_DISK_ACTIONS
*AvalDiskActions
91 BOOLEAN ExistingPassword
;
93 NULL_CHECK(AvalDiskActions
);
95 AvalDiskActions
->AdminPass
= 1;
96 AvalDiskActions
->UserPass
= 0;
97 AvalDiskActions
->DisableUser
= 0;
98 AvalDiskActions
->Unlock
= 0;
101 // Revert is performed on locking sp, so only allow if locking sp is enabled
103 if (LockingFeature
->LockingEnabled
) {
104 AvalDiskActions
->Revert
= 1;
108 // Psid revert is available for any device with media encryption support or pyrite 2.0 type support.
110 if (SupportedAttributes
->PyriteSscV2
|| SupportedAttributes
->MediaEncryption
) {
113 // Only allow psid revert if media encryption is enabled or pyrite 2.0 type support..
114 // Otherwise, someone who steals a disk can psid revert the disk and the user Data is still
115 // intact and accessible
117 AvalDiskActions
->PsidRevert
= 1;
118 AvalDiskActions
->RevertKeepDataForced
= 0;
121 // Secure erase is performed by generating a new encryption key
122 // this is only available if encryption is supported
124 AvalDiskActions
->SecureErase
= 1;
126 AvalDiskActions
->PsidRevert
= 0;
127 AvalDiskActions
->SecureErase
= 0;
130 // If no media encryption is supported, then a revert (using password) will not
131 // erase the Data (since you can't generate a new encryption key)
133 AvalDiskActions
->RevertKeepDataForced
= 1;
136 if (LockingFeature
->Locked
) {
137 AvalDiskActions
->Unlock
= 1;
139 AvalDiskActions
->Unlock
= 0;
143 // Only allow user to set password if an admin password exists
145 ExistingPassword
= OpalUtilAdminPasswordExists(OwnerShip
, LockingFeature
);
146 AvalDiskActions
->UserPass
= ExistingPassword
;
149 // This will still show up even if there isn't a user, which is fine
151 AvalDiskActions
->DisableUser
= ExistingPassword
;
153 return TcgResultSuccess
;
157 Enable Opal Feature for the input device.
159 @param[in] Session The opal session for the opal device.
161 @param[in] MsidLength Msid Length
162 @param[in] Password Admin password
163 @param[in] PassLength Length of password in bytes
168 OpalSupportEnableOpalFeature (
169 IN OPAL_SESSION
*Session
,
171 IN UINT32 MsidLength
,
180 NULL_CHECK(Password
);
182 Ret
= OpalUtilSetAdminPasswordAsSid(
189 if (Ret
== TcgResultSuccess
) {
191 // Enable global locking range
193 Ret
= OpalUtilSetOpalLockingRange(
197 OPAL_LOCKING_SP_LOCKING_GLOBALRANGE
,
211 Update password for the Opal disk.
213 @param[in, out] OpalDisk The disk to update password.
214 @param[in] Password The input password.
215 @param[in] PasswordLength The input password length.
219 OpalSupportUpdatePassword (
220 IN OUT OPAL_DISK
*OpalDisk
,
222 IN UINT32 PasswordLength
225 CopyMem (OpalDisk
->Password
, Password
, PasswordLength
);
226 OpalDisk
->PasswordLength
= (UINT8
) PasswordLength
;
230 Extract device info from the device path.
232 @param[in] DevicePath Device path info for the device.
233 @param[out] DevInfoLength Device information length needed.
234 @param[out] DevInfo Device information extracted.
240 ExtractDeviceInfoFromDevicePath (
241 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
242 OUT UINT16
*DevInfoLength
,
243 OUT OPAL_DEVICE_COMMON
*DevInfo OPTIONAL
246 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath
;
247 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath2
;
248 PCI_DEVICE_PATH
*PciDevPath
;
251 OPAL_PCI_DEVICE
*PciDevice
;
252 OPAL_DEVICE_ATA
*DevInfoAta
;
253 OPAL_DEVICE_NVME
*DevInfoNvme
;
254 SATA_DEVICE_PATH
*SataDevPath
;
255 NVME_NAMESPACE_DEVICE_PATH
*NvmeDevPath
;
257 ASSERT (DevicePath
!= NULL
);
258 ASSERT (DevInfoLength
!= NULL
);
260 DeviceType
= OPAL_DEVICE_TYPE_UNKNOWN
;
263 TmpDevPath
= DevicePath
;
268 while (!IsDevicePathEnd (TmpDevPath
)) {
269 if (TmpDevPath
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath
->SubType
== MSG_SATA_DP
) {
273 if (DevInfo
!= NULL
) {
274 SataDevPath
= (SATA_DEVICE_PATH
*) TmpDevPath
;
275 DevInfoAta
= (OPAL_DEVICE_ATA
*) DevInfo
;
276 DevInfoAta
->Port
= SataDevPath
->HBAPortNumber
;
277 DevInfoAta
->PortMultiplierPort
= SataDevPath
->PortMultiplierPortNumber
;
279 DeviceType
= OPAL_DEVICE_TYPE_ATA
;
280 *DevInfoLength
= sizeof (OPAL_DEVICE_ATA
);
282 } else if (TmpDevPath
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath
->SubType
== MSG_NVME_NAMESPACE_DP
) {
286 if (DevInfo
!= NULL
) {
287 NvmeDevPath
= (NVME_NAMESPACE_DEVICE_PATH
*) TmpDevPath
;
288 DevInfoNvme
= (OPAL_DEVICE_NVME
*) DevInfo
;
289 DevInfoNvme
->NvmeNamespaceId
= NvmeDevPath
->NamespaceId
;
291 DeviceType
= OPAL_DEVICE_TYPE_NVME
;
292 *DevInfoLength
= sizeof (OPAL_DEVICE_NVME
);
295 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
302 TmpDevPath
= DevicePath
;
303 TmpDevPath2
= NextDevicePathNode (DevicePath
);
304 while (!IsDevicePathEnd (TmpDevPath2
)) {
305 if (TmpDevPath
->Type
== HARDWARE_DEVICE_PATH
&& TmpDevPath
->SubType
== HW_PCI_DP
) {
306 PciDevPath
= (PCI_DEVICE_PATH
*) TmpDevPath
;
307 if ((TmpDevPath2
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath2
->SubType
== MSG_NVME_NAMESPACE_DP
)||
308 (TmpDevPath2
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath2
->SubType
== MSG_SATA_DP
)) {
309 if (DevInfo
!= NULL
) {
310 PciDevice
= &DevInfo
->Device
;
311 PciDevice
->Segment
= 0;
312 PciDevice
->Bus
= BusNum
;
313 PciDevice
->Device
= PciDevPath
->Device
;
314 PciDevice
->Function
= PciDevPath
->Function
;
317 if (DevInfo
!= NULL
) {
318 PciDevice
= (OPAL_PCI_DEVICE
*) ((UINTN
) DevInfo
+ *DevInfoLength
);
319 PciDevice
->Segment
= 0;
320 PciDevice
->Bus
= BusNum
;
321 PciDevice
->Device
= PciDevPath
->Device
;
322 PciDevice
->Function
= PciDevPath
->Function
;
324 *DevInfoLength
+= sizeof (OPAL_PCI_DEVICE
);
325 if (TmpDevPath2
->Type
== HARDWARE_DEVICE_PATH
&& TmpDevPath2
->SubType
== HW_PCI_DP
) {
326 BusNum
= PciRead8 (PCI_LIB_ADDRESS (BusNum
, PciDevPath
->Device
, PciDevPath
->Function
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
331 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
332 TmpDevPath2
= NextDevicePathNode (TmpDevPath2
);
335 ASSERT (DeviceType
!= OPAL_DEVICE_TYPE_UNKNOWN
);
340 Save boot script for ATA OPAL device.
342 @param[in] DevInfo Pointer to ATA Opal device information.
346 OpalDeviceAtaSaveBootScript (
347 IN OPAL_DEVICE_ATA
*DevInfo
357 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
359 OPAL_HC_PCI_REGISTER_SAVE
*HcRegisterSaveListPtr
;
364 Bus
= DevInfo
->Device
.Bus
;
365 Device
= DevInfo
->Device
.Device
;
366 Function
= DevInfo
->Device
.Function
;
368 HcRegisterSaveListPtr
= (OPAL_HC_PCI_REGISTER_SAVE
*) mSataHcRegisterSaveTemplate
;
369 Count
= sizeof (mSataHcRegisterSaveTemplate
) / sizeof (OPAL_HC_PCI_REGISTER_SAVE
);
371 for (Index
= 0; Index
< Count
; Index
++) {
372 Offset
= HcRegisterSaveListPtr
[Index
].Address
;
373 Width
= HcRegisterSaveListPtr
[Index
].Width
;
376 case S3BootScriptWidthUint8
:
377 Data
= (UINT32
)PciRead8 (PCI_LIB_ADDRESS(Bus
,Device
,Function
,Offset
));
379 case S3BootScriptWidthUint16
:
380 Data
= (UINT32
)PciRead16 (PCI_LIB_ADDRESS(Bus
,Device
,Function
,Offset
));
382 case S3BootScriptWidthUint32
:
383 Data
= PciRead32 (PCI_LIB_ADDRESS(Bus
,Device
,Function
,Offset
));
390 Address
= S3_BOOT_SCRIPT_LIB_PCI_ADDRESS (Bus
, Device
, Function
, Offset
);
391 Status
= S3BootScriptSavePciCfgWrite (Width
, Address
, 1, &Data
);
392 ASSERT_EFI_ERROR (Status
);
397 Build ATA OPAL device info and save them to LockBox.
399 @param[in] BarAddr Bar address allocated.
403 BuildOpalDeviceInfoAta (
409 OPAL_DEVICE_ATA
*DevInfoAta
;
410 OPAL_DEVICE_ATA
*TempDevInfoAta
;
411 UINTN DevInfoLengthAta
;
412 UINT16 DevInfoLength
;
413 OPAL_DRIVER_DEVICE
*TmpDev
;
416 // Build ATA OPAL device info and save them to LockBox.
418 DevInfoLengthAta
= 0;
419 TmpDev
= mOpalDriver
.DeviceList
;
420 while (TmpDev
!= NULL
) {
421 DeviceType
= ExtractDeviceInfoFromDevicePath (
422 TmpDev
->OpalDisk
.OpalDevicePath
,
426 if (DeviceType
== OPAL_DEVICE_TYPE_ATA
) {
427 DevInfoLengthAta
+= DevInfoLength
;
430 TmpDev
= TmpDev
->Next
;
433 if (DevInfoLengthAta
== 0) {
437 DevInfoAta
= AllocateZeroPool (DevInfoLengthAta
);
438 ASSERT (DevInfoAta
!= NULL
);
440 TempDevInfoAta
= DevInfoAta
;
441 TmpDev
= mOpalDriver
.DeviceList
;
442 while (TmpDev
!= NULL
) {
443 DeviceType
= ExtractDeviceInfoFromDevicePath (
444 TmpDev
->OpalDisk
.OpalDevicePath
,
448 if (DeviceType
== OPAL_DEVICE_TYPE_ATA
) {
449 ExtractDeviceInfoFromDevicePath (
450 TmpDev
->OpalDisk
.OpalDevicePath
,
452 (OPAL_DEVICE_COMMON
*) TempDevInfoAta
454 TempDevInfoAta
->Length
= DevInfoLength
;
455 TempDevInfoAta
->OpalBaseComId
= TmpDev
->OpalDisk
.OpalBaseComId
;
456 TempDevInfoAta
->BarAddr
= BarAddr
;
458 TempDevInfoAta
->Password
,
459 TmpDev
->OpalDisk
.Password
,
460 TmpDev
->OpalDisk
.PasswordLength
462 TempDevInfoAta
->PasswordLength
= TmpDev
->OpalDisk
.PasswordLength
;
463 OpalDeviceAtaSaveBootScript (TempDevInfoAta
);
464 TempDevInfoAta
= (OPAL_DEVICE_ATA
*) ((UINTN
) TempDevInfoAta
+ DevInfoLength
);
467 TmpDev
= TmpDev
->Next
;
470 Status
= SaveLockBox (
475 ASSERT_EFI_ERROR (Status
);
477 Status
= SetLockBoxAttributes (
479 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
481 ASSERT_EFI_ERROR (Status
);
483 ZeroMem (DevInfoAta
, DevInfoLengthAta
);
484 FreePool (DevInfoAta
);
488 Build NVMe OPAL device info and save them to LockBox.
490 @param[in] BarAddr Bar address allocated.
494 BuildOpalDeviceInfoNvme (
500 OPAL_DEVICE_NVME
*DevInfoNvme
;
501 OPAL_DEVICE_NVME
*TempDevInfoNvme
;
502 UINTN DevInfoLengthNvme
;
503 UINT16 DevInfoLength
;
504 OPAL_DRIVER_DEVICE
*TmpDev
;
507 // Build NVMe OPAL device info and save them to LockBox.
509 DevInfoLengthNvme
= 0;
510 TmpDev
= mOpalDriver
.DeviceList
;
511 while (TmpDev
!= NULL
) {
512 DeviceType
= ExtractDeviceInfoFromDevicePath (
513 TmpDev
->OpalDisk
.OpalDevicePath
,
517 if (DeviceType
== OPAL_DEVICE_TYPE_NVME
) {
518 DevInfoLengthNvme
+= DevInfoLength
;
521 TmpDev
= TmpDev
->Next
;
524 if (DevInfoLengthNvme
== 0) {
528 DevInfoNvme
= AllocateZeroPool (DevInfoLengthNvme
);
529 ASSERT (DevInfoNvme
!= NULL
);
531 TempDevInfoNvme
= DevInfoNvme
;
532 TmpDev
= mOpalDriver
.DeviceList
;
533 while (TmpDev
!= NULL
) {
534 DeviceType
= ExtractDeviceInfoFromDevicePath (
535 TmpDev
->OpalDisk
.OpalDevicePath
,
539 if (DeviceType
== OPAL_DEVICE_TYPE_NVME
) {
540 ExtractDeviceInfoFromDevicePath (
541 TmpDev
->OpalDisk
.OpalDevicePath
,
543 (OPAL_DEVICE_COMMON
*) TempDevInfoNvme
545 TempDevInfoNvme
->Length
= DevInfoLength
;
546 TempDevInfoNvme
->OpalBaseComId
= TmpDev
->OpalDisk
.OpalBaseComId
;
547 TempDevInfoNvme
->BarAddr
= BarAddr
;
549 TempDevInfoNvme
->Password
,
550 TmpDev
->OpalDisk
.Password
,
551 TmpDev
->OpalDisk
.PasswordLength
553 TempDevInfoNvme
->PasswordLength
= TmpDev
->OpalDisk
.PasswordLength
;
554 TempDevInfoNvme
= (OPAL_DEVICE_NVME
*) ((UINTN
) TempDevInfoNvme
+ DevInfoLength
);
557 TmpDev
= TmpDev
->Next
;
560 Status
= SaveLockBox (
561 &mOpalDeviceNvmeGuid
,
565 ASSERT_EFI_ERROR (Status
);
567 Status
= SetLockBoxAttributes (
568 &mOpalDeviceNvmeGuid
,
569 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
571 ASSERT_EFI_ERROR (Status
);
573 ZeroMem (DevInfoNvme
, DevInfoLengthNvme
);
574 FreePool (DevInfoNvme
);
578 Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
580 This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
582 @param Event Event whose notification function is being invoked.
583 @param Context Pointer to the notification function's context.
588 OpalEndOfDxeEventNotify (
594 EFI_PHYSICAL_ADDRESS Address
;
596 OPAL_DRIVER_DEVICE
*TmpDev
;
598 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
600 mOpalEndOfDxe
= TRUE
;
602 if (mOpalRequestVariable
!= NULL
) {
604 // Free the OPAL request variable buffer here
605 // as the OPAL requests should have been processed.
607 FreePool (mOpalRequestVariable
);
608 mOpalRequestVariable
= NULL
;
609 mOpalRequestVariableSize
= 0;
613 // If no any device, return directly.
615 if (mOpalDriver
.DeviceList
== NULL
) {
616 gBS
->CloseEvent (Event
);
621 // Assume 64K size and alignment are enough.
624 Address
= 0xFFFFFFFF;
625 Status
= gDS
->AllocateMemorySpace (
626 EfiGcdAllocateMaxAddressSearchBottomUp
,
627 EfiGcdMemoryTypeMemoryMappedIo
,
628 16, // 2^16: 64K Alignment
634 ASSERT_EFI_ERROR (Status
);
636 BuildOpalDeviceInfoAta ((UINT32
) Address
);
637 BuildOpalDeviceInfoNvme ((UINT32
) Address
);
642 TmpDev
= mOpalDriver
.DeviceList
;
643 while (TmpDev
!= NULL
) {
644 ZeroMem (TmpDev
->OpalDisk
.Password
, TmpDev
->OpalDisk
.PasswordLength
);
645 TmpDev
= TmpDev
->Next
;
648 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
650 gBS
->CloseEvent (Event
);
654 Get Psid input from the popup window.
656 @param[in] Dev The device which need Psid to process Psid Revert
658 @param[in] PopUpString Pop up string.
659 @param[in] PopUpString2 Pop up string in line 2.
661 @param[out] PressEsc Whether user escape function through Press ESC.
663 @retval Psid string if success. NULL if failed.
667 OpalDriverPopUpPsidInput (
668 IN OPAL_DRIVER_DEVICE
*Dev
,
669 IN CHAR16
*PopUpString
,
670 IN CHAR16
*PopUpString2
,
671 OUT BOOLEAN
*PressEsc
674 EFI_INPUT_KEY InputKey
;
676 CHAR16 Mask
[PSID_CHARACTER_LENGTH
+ 1];
677 CHAR16 Unicode
[PSID_CHARACTER_LENGTH
+ 1];
680 ZeroMem(Unicode
, sizeof(Unicode
));
681 ZeroMem(Mask
, sizeof(Mask
));
685 gST
->ConOut
->ClearScreen(gST
->ConOut
);
689 Mask
[InputLength
] = L
'_';
690 if (PopUpString2
== NULL
) {
692 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
695 L
"---------------------",
701 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
705 L
"---------------------",
714 if (InputKey
.ScanCode
== SCAN_NULL
) {
718 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
720 // Add the null terminator.
722 Unicode
[InputLength
] = 0;
723 Mask
[InputLength
] = 0;
725 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
726 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
727 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
732 // delete last key entered
734 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
735 if (InputLength
> 0) {
736 Unicode
[InputLength
] = 0;
737 Mask
[InputLength
] = 0;
742 // add Next key entry
744 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
745 Mask
[InputLength
] = InputKey
.UnicodeChar
;
747 if (InputLength
== PSID_CHARACTER_LENGTH
) {
749 // Add the null terminator.
751 Unicode
[InputLength
] = 0;
752 Mask
[InputLength
] = 0;
762 if (InputKey
.ScanCode
== SCAN_ESC
) {
768 gST
->ConOut
->ClearScreen(gST
->ConOut
);
770 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
771 ZeroMem (Unicode
, sizeof (Unicode
));
772 ZeroMem (Mask
, sizeof (Mask
));
776 Ascii
= AllocateZeroPool (PSID_CHARACTER_LENGTH
+ 1);
778 ZeroMem (Unicode
, sizeof (Unicode
));
779 ZeroMem (Mask
, sizeof (Mask
));
783 UnicodeStrToAsciiStrS (Unicode
, Ascii
, PSID_CHARACTER_LENGTH
+ 1);
784 ZeroMem (Unicode
, sizeof (Unicode
));
785 ZeroMem (Mask
, sizeof (Mask
));
792 Get password input from the popup window.
794 @param[in] Dev The device which need password to unlock or
795 process OPAL request.
796 @param[in] PopUpString1 Pop up string 1.
797 @param[in] PopUpString2 Pop up string 2.
798 @param[out] PressEsc Whether user escape function through Press ESC.
800 @retval Password string if success. NULL if failed.
804 OpalDriverPopUpPasswordInput (
805 IN OPAL_DRIVER_DEVICE
*Dev
,
806 IN CHAR16
*PopUpString1
,
807 IN CHAR16
*PopUpString2
,
808 OUT BOOLEAN
*PressEsc
811 EFI_INPUT_KEY InputKey
;
813 CHAR16 Mask
[OPAL_MAX_PASSWORD_SIZE
+ 1];
814 CHAR16 Unicode
[OPAL_MAX_PASSWORD_SIZE
+ 1];
817 ZeroMem(Unicode
, sizeof(Unicode
));
818 ZeroMem(Mask
, sizeof(Mask
));
822 gST
->ConOut
->ClearScreen(gST
->ConOut
);
826 Mask
[InputLength
] = L
'_';
827 if (PopUpString2
== NULL
) {
829 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
832 L
"---------------------",
838 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
842 L
"---------------------",
851 if (InputKey
.ScanCode
== SCAN_NULL
) {
855 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
857 // Add the null terminator.
859 Unicode
[InputLength
] = 0;
860 Mask
[InputLength
] = 0;
862 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
863 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
864 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
869 // delete last key entered
871 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
872 if (InputLength
> 0) {
873 Unicode
[InputLength
] = 0;
874 Mask
[InputLength
] = 0;
879 // add Next key entry
881 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
882 Mask
[InputLength
] = L
'*';
884 if (InputLength
== OPAL_MAX_PASSWORD_SIZE
) {
886 // Add the null terminator.
888 Unicode
[InputLength
] = 0;
889 Mask
[InputLength
] = 0;
899 if (InputKey
.ScanCode
== SCAN_ESC
) {
905 gST
->ConOut
->ClearScreen(gST
->ConOut
);
907 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
908 ZeroMem (Unicode
, sizeof (Unicode
));
912 Ascii
= AllocateZeroPool (OPAL_MAX_PASSWORD_SIZE
+ 1);
914 ZeroMem (Unicode
, sizeof (Unicode
));
918 UnicodeStrToAsciiStrS (Unicode
, Ascii
, OPAL_MAX_PASSWORD_SIZE
+ 1);
919 ZeroMem (Unicode
, sizeof (Unicode
));
927 @param[in] Dev The OPAL device.
928 @param[in] RequestString Request string.
930 @return Pop up string.
935 IN OPAL_DRIVER_DEVICE
*Dev
,
936 IN CHAR16
*RequestString
939 if (Dev
->Name16
== NULL
) {
940 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s Disk", RequestString
);
942 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s %s", RequestString
, Dev
->Name16
);
949 Check if disk is locked, show popup window and ask for password if it is.
951 @param[in] Dev The device which need to be unlocked.
952 @param[in] RequestString Request string.
956 OpalDriverRequestPassword (
957 IN OPAL_DRIVER_DEVICE
*Dev
,
958 IN CHAR16
*RequestString
966 OPAL_SESSION Session
;
976 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
978 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
982 IsEnabled
= OpalFeatureEnabled (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
984 ZeroMem(&Session
, sizeof(Session
));
985 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
986 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
987 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
989 IsLocked
= OpalDeviceLocked (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
991 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
992 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
996 // Current device in the lock status and
997 // User not input password and press ESC,
998 // keep device in lock status and continue boot.
1002 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1004 L
"Press ENTER to skip the request and continue boot,",
1005 L
"Press ESC to input password again",
1008 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1010 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1011 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1013 // Keep lock and continue boot.
1018 // Let user input password again.
1024 // Current device in the unlock status and
1025 // User not input password and press ESC,
1026 // Shutdown the device.
1030 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1032 L
"Press ENTER to shutdown, Press ESC to input password again",
1035 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1037 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1038 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1041 // Let user input password again.
1048 if (Password
== NULL
) {
1052 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1055 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
1057 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, TRUE
, TRUE
);
1058 if (Ret
== TcgResultSuccess
) {
1059 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
1063 if (Ret
== TcgResultSuccess
) {
1064 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1065 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1067 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1070 if (Password
!= NULL
) {
1071 ZeroMem (Password
, PasswordLen
);
1072 FreePool (Password
);
1075 if (Ret
== TcgResultSuccess
) {
1083 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1085 L
"Invalid password.",
1086 L
"Press ENTER to retry",
1089 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1092 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1095 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1097 L
"Opal password retry count exceeds the limit. Must shutdown!",
1098 L
"Press ENTER to shutdown",
1101 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1103 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1109 Process Enable Feature OPAL request.
1111 @param[in] Dev The device which has Enable Feature OPAL request.
1112 @param[in] RequestString Request string.
1116 ProcessOpalRequestEnableFeature (
1117 IN OPAL_DRIVER_DEVICE
*Dev
,
1118 IN CHAR16
*RequestString
1124 CHAR8
*PasswordConfirm
;
1125 UINT32 PasswordLenConfirm
;
1126 OPAL_SESSION Session
;
1130 CHAR16
*PopUpString
;
1136 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1138 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1142 ZeroMem(&Session
, sizeof(Session
));
1143 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1144 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1145 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1147 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1148 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1152 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1154 L
"Press ENTER to skip the request and continue boot,",
1155 L
"Press ESC to input password again",
1158 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1160 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1161 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1165 // Let user input password again.
1171 if (Password
== NULL
) {
1175 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1177 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1178 if (PasswordConfirm
== NULL
) {
1179 ZeroMem (Password
, PasswordLen
);
1180 FreePool (Password
);
1184 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1185 if ((PasswordLen
!= PasswordLenConfirm
) ||
1186 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1187 ZeroMem (Password
, PasswordLen
);
1188 FreePool (Password
);
1189 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1190 FreePool (PasswordConfirm
);
1193 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1195 L
"Passwords are not the same.",
1196 L
"Press ENTER to retry",
1199 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1204 if (PasswordConfirm
!= NULL
) {
1205 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1206 FreePool (PasswordConfirm
);
1209 Ret
= OpalSupportEnableOpalFeature (&Session
, Dev
->OpalDisk
.Msid
, Dev
->OpalDisk
.MsidLength
, Password
, PasswordLen
);
1210 if (Ret
== TcgResultSuccess
) {
1211 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1212 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1214 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1217 if (Password
!= NULL
) {
1218 ZeroMem (Password
, PasswordLen
);
1219 FreePool (Password
);
1222 if (Ret
== TcgResultSuccess
) {
1230 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1233 L
"Press ENTER to retry",
1236 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1239 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1242 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1244 L
"Opal password retry count exceeds the limit.",
1245 L
"Press ENTER to skip the request and continue boot",
1248 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1249 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1254 Process Disable User OPAL request.
1256 @param[in] Dev The device which has Disable User OPAL request.
1257 @param[in] RequestString Request string.
1261 ProcessOpalRequestDisableUser (
1262 IN OPAL_DRIVER_DEVICE
*Dev
,
1263 IN CHAR16
*RequestString
1269 OPAL_SESSION Session
;
1273 BOOLEAN PasswordFailed
;
1274 CHAR16
*PopUpString
;
1280 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1282 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1286 ZeroMem(&Session
, sizeof(Session
));
1287 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1288 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1289 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1291 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1292 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1296 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1298 L
"Press ENTER to skip the request and continue boot,",
1299 L
"Press ESC to input password again",
1302 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1304 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1305 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1309 // Let user input password again.
1315 if (Password
== NULL
) {
1319 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1321 Ret
= OpalUtilDisableUser(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1322 if (Ret
== TcgResultSuccess
) {
1323 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1324 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1326 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1329 if (Password
!= NULL
) {
1330 ZeroMem (Password
, PasswordLen
);
1331 FreePool (Password
);
1334 if (Ret
== TcgResultSuccess
) {
1342 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1344 L
"Invalid password, request failed.",
1345 L
"Press ENTER to retry",
1348 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1351 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1354 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1356 L
"Opal password retry count exceeds the limit.",
1357 L
"Press ENTER to skip the request and continue boot",
1360 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1361 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1366 Process Psid Revert OPAL request.
1368 @param[in] Dev The device which has Psid Revert OPAL request.
1369 @param[in] RequestString Request string.
1373 ProcessOpalRequestPsidRevert (
1374 IN OPAL_DRIVER_DEVICE
*Dev
,
1375 IN CHAR16
*RequestString
1381 OPAL_SESSION Session
;
1385 CHAR16
*PopUpString
;
1386 CHAR16
*PopUpString2
;
1393 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1395 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1397 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1398 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds, DO NOT power off system during the revert action!");
1399 PopUpString2
= AllocateZeroPool (BufferSize
);
1400 ASSERT (PopUpString2
!= NULL
);
1404 L
"WARNING: Revert action will take about %d seconds, DO NOT power off system during the revert action!",
1405 Dev
->OpalDisk
.EstimateTimeCost
1408 PopUpString2
= NULL
;
1413 ZeroMem(&Session
, sizeof(Session
));
1414 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1415 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1416 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1418 while (Count
< MAX_PSID_TRY_COUNT
) {
1419 Psid
= OpalDriverPopUpPsidInput (Dev
, PopUpString
, PopUpString2
, &PressEsc
);
1423 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1425 L
"Press ENTER to skip the request and continue boot,",
1426 L
"Press ESC to input Psid again",
1429 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1431 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1432 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1436 // Let user input Psid again.
1446 PsidLen
= (UINT32
) AsciiStrLen(Psid
);
1448 Ret
= OpalUtilPsidRevert(&Session
, Psid
, PsidLen
);
1449 if (Ret
== TcgResultSuccess
) {
1450 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1452 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1456 ZeroMem (Psid
, PsidLen
);
1460 if (Ret
== TcgResultSuccess
) {
1468 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1470 L
"Invalid Psid, request failed.",
1471 L
"Press ENTER to retry",
1474 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1477 if (Count
>= MAX_PSID_TRY_COUNT
) {
1480 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1482 L
"Opal Psid retry count exceeds the limit.",
1483 L
"Press ENTER to skip the request and continue boot",
1486 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1487 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1491 if (PopUpString2
!= NULL
) {
1492 FreePool (PopUpString2
);
1497 Process Admin Revert OPAL request.
1499 @param[in] Dev The device which has Revert OPAL request.
1500 @param[in] KeepUserData Whether to keep user data or not.
1501 @param[in] RequestString Request string.
1505 ProcessOpalRequestRevert (
1506 IN OPAL_DRIVER_DEVICE
*Dev
,
1507 IN BOOLEAN KeepUserData
,
1508 IN CHAR16
*RequestString
1514 OPAL_SESSION Session
;
1518 BOOLEAN PasswordFailed
;
1519 CHAR16
*PopUpString
;
1520 CHAR16
*PopUpString2
;
1527 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1529 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1531 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1532 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds, DO NOT power off system during the revert action!");
1533 PopUpString2
= AllocateZeroPool (BufferSize
);
1534 ASSERT (PopUpString2
!= NULL
);
1538 L
"WARNING: Revert action will take about %d seconds, DO NOT power off system during the revert action!",
1539 Dev
->OpalDisk
.EstimateTimeCost
1542 PopUpString2
= NULL
;
1547 ZeroMem(&Session
, sizeof(Session
));
1548 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1549 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1550 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1552 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1553 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, PopUpString2
, &PressEsc
);
1557 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1559 L
"Press ENTER to skip the request and continue boot,",
1560 L
"Press ESC to input password again",
1563 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1565 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1566 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1570 // Let user input password again.
1576 if (Password
== NULL
) {
1580 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1582 if ((Dev
->OpalDisk
.SupportedAttributes
.PyriteSsc
== 1) &&
1583 (Dev
->OpalDisk
.LockingFeature
.MediaEncryption
== 0)) {
1585 // For pyrite type device which does not support media encryption,
1586 // it does not accept "Keep User Data" parameter.
1587 // So here hardcode a FALSE for this case.
1589 Ret
= OpalUtilRevert(
1596 Dev
->OpalDisk
.MsidLength
1599 Ret
= OpalUtilRevert(
1606 Dev
->OpalDisk
.MsidLength
1609 if (Ret
== TcgResultSuccess
) {
1610 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1611 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1613 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1616 if (Password
!= NULL
) {
1617 ZeroMem (Password
, PasswordLen
);
1618 FreePool (Password
);
1621 if (Ret
== TcgResultSuccess
) {
1629 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1631 L
"Invalid password, request failed.",
1632 L
"Press ENTER to retry",
1635 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1638 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1641 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1643 L
"Opal password retry count exceeds the limit.",
1644 L
"Press ENTER to skip the request and continue boot",
1647 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1648 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1652 if (PopUpString2
!= NULL
) {
1653 FreePool (PopUpString2
);
1658 Process Secure Erase OPAL request.
1660 @param[in] Dev The device which has Secure Erase OPAL request.
1661 @param[in] RequestString Request string.
1665 ProcessOpalRequestSecureErase (
1666 IN OPAL_DRIVER_DEVICE
*Dev
,
1667 IN CHAR16
*RequestString
1673 OPAL_SESSION Session
;
1677 BOOLEAN PasswordFailed
;
1678 CHAR16
*PopUpString
;
1684 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1686 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1690 ZeroMem(&Session
, sizeof(Session
));
1691 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1692 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1693 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1695 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1696 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1700 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1702 L
"Press ENTER to skip the request and continue boot,",
1703 L
"Press ESC to input password again",
1706 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1708 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1709 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1713 // Let user input password again.
1719 if (Password
== NULL
) {
1723 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1725 Ret
= OpalUtilSecureErase(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1726 if (Ret
== TcgResultSuccess
) {
1727 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1728 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1730 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1733 if (Password
!= NULL
) {
1734 ZeroMem (Password
, PasswordLen
);
1735 FreePool (Password
);
1738 if (Ret
== TcgResultSuccess
) {
1746 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1748 L
"Invalid password, request failed.",
1749 L
"Press ENTER to retry",
1752 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1755 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1758 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1760 L
"Opal password retry count exceeds the limit.",
1761 L
"Press ENTER to skip the request and continue boot",
1764 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1765 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1770 Process Set Admin Pwd OPAL request.
1772 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1773 @param[in] RequestString Request string.
1777 ProcessOpalRequestSetUserPwd (
1778 IN OPAL_DRIVER_DEVICE
*Dev
,
1779 IN CHAR16
*RequestString
1784 UINT32 OldPasswordLen
;
1787 CHAR8
*PasswordConfirm
;
1788 UINT32 PasswordLenConfirm
;
1789 OPAL_SESSION Session
;
1793 CHAR16
*PopUpString
;
1799 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1801 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1805 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1806 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
1810 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1812 L
"Press ENTER to skip the request and continue boot,",
1813 L
"Press ESC to input password again",
1816 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1818 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1819 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1823 // Let user input password again.
1829 if (OldPassword
== NULL
) {
1833 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1835 ZeroMem(&Session
, sizeof(Session
));
1836 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1837 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1838 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1839 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_USER1_AUTHORITY
);
1840 if (Ret
== TcgResultSuccess
) {
1841 DEBUG ((DEBUG_INFO
, "Verify with USER1 authority : Success\n"));
1843 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1844 if (Ret
== TcgResultSuccess
) {
1845 DEBUG ((DEBUG_INFO
, "Verify with ADMIN1 authority: Success\n"));
1847 ZeroMem (OldPassword
, OldPasswordLen
);
1848 FreePool (OldPassword
);
1849 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1852 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1854 L
"Incorrect password.",
1855 L
"Press ENTER to retry",
1858 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1864 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1865 if (Password
== NULL
) {
1866 ZeroMem (OldPassword
, OldPasswordLen
);
1867 FreePool (OldPassword
);
1871 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1873 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1874 if (PasswordConfirm
== NULL
) {
1875 ZeroMem (OldPassword
, OldPasswordLen
);
1876 FreePool (OldPassword
);
1877 ZeroMem (Password
, PasswordLen
);
1878 FreePool (Password
);
1882 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1883 if ((PasswordLen
!= PasswordLenConfirm
) ||
1884 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1885 ZeroMem (OldPassword
, OldPasswordLen
);
1886 FreePool (OldPassword
);
1887 ZeroMem (Password
, PasswordLen
);
1888 FreePool (Password
);
1889 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1890 FreePool (PasswordConfirm
);
1893 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1895 L
"Passwords are not the same.",
1896 L
"Press ENTER to retry",
1899 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1904 if (PasswordConfirm
!= NULL
) {
1905 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1906 FreePool (PasswordConfirm
);
1909 ZeroMem(&Session
, sizeof(Session
));
1910 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1911 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1912 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1913 Ret
= OpalUtilSetUserPassword(
1920 if (Ret
== TcgResultSuccess
) {
1921 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1922 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1924 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1927 if (OldPassword
!= NULL
) {
1928 ZeroMem (OldPassword
, OldPasswordLen
);
1929 FreePool (OldPassword
);
1932 if (Password
!= NULL
) {
1933 ZeroMem (Password
, PasswordLen
);
1934 FreePool (Password
);
1937 if (Ret
== TcgResultSuccess
) {
1945 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1948 L
"Press ENTER to retry",
1951 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1954 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1957 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1959 L
"Opal password retry count exceeds the limit.",
1960 L
"Press ENTER to skip the request and continue boot",
1963 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1964 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1969 Process Set Admin Pwd OPAL request.
1971 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1972 @param[in] RequestString Request string.
1976 ProcessOpalRequestSetAdminPwd (
1977 IN OPAL_DRIVER_DEVICE
*Dev
,
1978 IN CHAR16
*RequestString
1983 UINT32 OldPasswordLen
;
1986 CHAR8
*PasswordConfirm
;
1987 UINT32 PasswordLenConfirm
;
1988 OPAL_SESSION Session
;
1992 CHAR16
*PopUpString
;
1998 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
2000 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
2004 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
2005 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
2009 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2011 L
"Press ENTER to skip the request and continue boot,",
2012 L
"Press ESC to input password again",
2015 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
2017 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
2018 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2022 // Let user input password again.
2028 if (OldPassword
== NULL
) {
2032 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
2034 ZeroMem(&Session
, sizeof(Session
));
2035 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2036 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2037 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2038 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
2039 if (Ret
== TcgResultSuccess
) {
2040 DEBUG ((DEBUG_INFO
, "Verify: Success\n"));
2042 ZeroMem (OldPassword
, OldPasswordLen
);
2043 FreePool (OldPassword
);
2044 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
2047 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2049 L
"Incorrect password.",
2050 L
"Press ENTER to retry",
2053 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2058 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
2059 if (Password
== NULL
) {
2060 ZeroMem (OldPassword
, OldPasswordLen
);
2061 FreePool (OldPassword
);
2065 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
2067 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
2068 if (PasswordConfirm
== NULL
) {
2069 ZeroMem (OldPassword
, OldPasswordLen
);
2070 FreePool (OldPassword
);
2071 ZeroMem (Password
, PasswordLen
);
2072 FreePool (Password
);
2076 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
2077 if ((PasswordLen
!= PasswordLenConfirm
) ||
2078 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
2079 ZeroMem (OldPassword
, OldPasswordLen
);
2080 FreePool (OldPassword
);
2081 ZeroMem (Password
, PasswordLen
);
2082 FreePool (Password
);
2083 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2084 FreePool (PasswordConfirm
);
2087 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2089 L
"Passwords are not the same.",
2090 L
"Press ENTER to retry",
2093 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2098 if (PasswordConfirm
!= NULL
) {
2099 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2100 FreePool (PasswordConfirm
);
2104 ZeroMem(&Session
, sizeof(Session
));
2105 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2106 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2107 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2108 Ret
= OpalUtilSetAdminPassword(
2115 if (Ret
== TcgResultSuccess
) {
2116 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
2117 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
2119 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
2122 if (OldPassword
!= NULL
) {
2123 ZeroMem (OldPassword
, OldPasswordLen
);
2124 FreePool (OldPassword
);
2127 if (Password
!= NULL
) {
2128 ZeroMem (Password
, PasswordLen
);
2129 FreePool (Password
);
2132 if (Ret
== TcgResultSuccess
) {
2140 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2143 L
"Press ENTER to retry",
2146 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2149 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
2152 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2154 L
"Opal password retry count exceeds the limit.",
2155 L
"Press ENTER to skip the request and continue boot",
2158 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2159 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2164 Process OPAL request.
2166 @param[in] Dev The device which has OPAL request.
2170 ProcessOpalRequest (
2171 IN OPAL_DRIVER_DEVICE
*Dev
2175 OPAL_REQUEST_VARIABLE
*TempVariable
;
2176 OPAL_REQUEST_VARIABLE
*Variable
;
2178 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInVariable
;
2179 UINTN DevicePathSizeInVariable
;
2180 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2181 UINTN DevicePathSize
;
2182 BOOLEAN KeepUserData
;
2184 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
2186 if (mOpalRequestVariable
== NULL
) {
2187 Status
= GetVariable2 (
2188 OPAL_REQUEST_VARIABLE_NAME
,
2189 &gHiiSetupVariableGuid
,
2190 (VOID
**) &Variable
,
2193 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
2196 mOpalRequestVariable
= Variable
;
2197 mOpalRequestVariableSize
= VariableSize
;
2200 // Delete the OPAL request variable.
2202 Status
= gRT
->SetVariable (
2203 OPAL_REQUEST_VARIABLE_NAME
,
2204 (EFI_GUID
*) &gHiiSetupVariableGuid
,
2209 ASSERT_EFI_ERROR (Status
);
2211 Variable
= mOpalRequestVariable
;
2212 VariableSize
= mOpalRequestVariableSize
;
2216 // Process the OPAL requests.
2218 TempVariable
= Variable
;
2219 while ((VariableSize
> sizeof (OPAL_REQUEST_VARIABLE
)) &&
2220 (VariableSize
>= TempVariable
->Length
) &&
2221 (TempVariable
->Length
> sizeof (OPAL_REQUEST_VARIABLE
))) {
2222 DevicePathInVariable
= (EFI_DEVICE_PATH_PROTOCOL
*) ((UINTN
) TempVariable
+ sizeof (OPAL_REQUEST_VARIABLE
));
2223 DevicePathSizeInVariable
= GetDevicePathSize (DevicePathInVariable
);
2224 DevicePath
= Dev
->OpalDisk
.OpalDevicePath
;
2225 DevicePathSize
= GetDevicePathSize (DevicePath
);
2226 if ((DevicePathSize
== DevicePathSizeInVariable
) &&
2227 (CompareMem (DevicePath
, DevicePathInVariable
, DevicePathSize
) == 0)) {
2229 // Found the node for the OPAL device.
2231 if (TempVariable
->OpalRequest
.SetAdminPwd
!= 0) {
2232 ProcessOpalRequestSetAdminPwd (Dev
, L
"Update Admin Pwd:");
2234 if (TempVariable
->OpalRequest
.SetUserPwd
!= 0) {
2235 ProcessOpalRequestSetUserPwd (Dev
, L
"Set User Pwd:");
2237 if (TempVariable
->OpalRequest
.SecureErase
!= 0) {
2238 ProcessOpalRequestSecureErase (Dev
, L
"Secure Erase:");
2240 if (TempVariable
->OpalRequest
.Revert
!= 0) {
2241 KeepUserData
= (BOOLEAN
) TempVariable
->OpalRequest
.KeepUserData
;
2242 ProcessOpalRequestRevert (
2245 KeepUserData
? L
"Admin Revert(keep):" : L
"Admin Revert:"
2248 if (TempVariable
->OpalRequest
.PsidRevert
!= 0) {
2249 ProcessOpalRequestPsidRevert (Dev
, L
"Psid Revert:");
2251 if (TempVariable
->OpalRequest
.DisableUser
!= 0) {
2252 ProcessOpalRequestDisableUser (Dev
, L
"Disable User:");
2254 if (TempVariable
->OpalRequest
.EnableFeature
!= 0) {
2255 ProcessOpalRequestEnableFeature (Dev
, L
"Enable Feature:");
2261 VariableSize
-= TempVariable
->Length
;
2262 TempVariable
= (OPAL_REQUEST_VARIABLE
*) ((UINTN
) TempVariable
+ TempVariable
->Length
);
2265 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
2269 Add new device to the global device list.
2271 @param Dev New create device.
2276 IN OPAL_DRIVER_DEVICE
*Dev
2279 OPAL_DRIVER_DEVICE
*TmpDev
;
2281 if (mOpalDriver
.DeviceList
== NULL
) {
2282 mOpalDriver
.DeviceList
= Dev
;
2284 TmpDev
= mOpalDriver
.DeviceList
;
2285 while (TmpDev
->Next
!= NULL
) {
2286 TmpDev
= TmpDev
->Next
;
2294 Remove one device in the global device list.
2296 @param Dev The device need to be removed.
2301 IN OPAL_DRIVER_DEVICE
*Dev
2304 OPAL_DRIVER_DEVICE
*TmpDev
;
2306 if (mOpalDriver
.DeviceList
== NULL
) {
2310 if (mOpalDriver
.DeviceList
== Dev
) {
2311 mOpalDriver
.DeviceList
= NULL
;
2315 TmpDev
= mOpalDriver
.DeviceList
;
2316 while (TmpDev
->Next
!= NULL
) {
2317 if (TmpDev
->Next
== Dev
) {
2318 TmpDev
->Next
= Dev
->Next
;
2325 Get current device count.
2327 @retval return the current created device count.
2336 OPAL_DRIVER_DEVICE
*TmpDev
;
2339 TmpDev
= mOpalDriver
.DeviceList
;
2341 while (TmpDev
!= NULL
) {
2343 TmpDev
= TmpDev
->Next
;
2350 Get devcie list info.
2352 @retval return the device list pointer.
2355 OpalDriverGetDeviceList(
2359 return mOpalDriver
.DeviceList
;
2363 ReadyToBoot callback to send BlockSid command.
2365 @param Event Pointer to this event
2366 @param Context Event handler private Data
2371 ReadyToBootCallback (
2376 OPAL_DRIVER_DEVICE
*Itr
;
2378 OPAL_SESSION Session
;
2379 UINT32 PpStorageFlag
;
2381 gBS
->CloseEvent (Event
);
2383 PpStorageFlag
= Tcg2PhysicalPresenceLibGetManagementFlags ();
2384 if ((PpStorageFlag
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID
) != 0) {
2386 // Send BlockSID command to each Opal disk
2388 Itr
= mOpalDriver
.DeviceList
;
2389 while (Itr
!= NULL
) {
2390 if (Itr
->OpalDisk
.SupportedAttributes
.BlockSid
) {
2391 ZeroMem(&Session
, sizeof(Session
));
2392 Session
.Sscp
= Itr
->OpalDisk
.Sscp
;
2393 Session
.MediaId
= Itr
->OpalDisk
.MediaId
;
2394 Session
.OpalBaseComId
= Itr
->OpalDisk
.OpalBaseComId
;
2396 DEBUG ((DEBUG_INFO
, "OpalPassword: ReadyToBoot point, send BlockSid command to device!\n"));
2397 Result
= OpalBlockSid (&Session
, TRUE
); // HardwareReset must always be TRUE
2398 if (Result
!= TcgResultSuccess
) {
2399 DEBUG ((DEBUG_ERROR
, "OpalBlockSid fail\n"));
2410 Stop this Controller.
2412 @param Dev The device need to be stopped.
2416 OpalDriverStopDevice (
2417 OPAL_DRIVER_DEVICE
*Dev
2423 FreePool(Dev
->Name16
);
2426 // remove OPAL_DRIVER_DEVICE from the list
2427 // it updates the controllerList pointer
2432 // close protocols that were opened
2436 &gEfiStorageSecurityCommandProtocolGuid
,
2437 gOpalDriverBinding
.DriverBindingHandle
,
2443 &gEfiBlockIoProtocolGuid
,
2444 gOpalDriverBinding
.DriverBindingHandle
,
2452 Get devcie name through the component name protocol.
2454 @param[in] AllHandlesBuffer The handle buffer for current system.
2455 @param[in] NumAllHandles The number of handles for the handle buffer.
2456 @param[in] Dev The device which need to get name.
2457 @param[in] UseComp1 Whether use component name or name2 protocol.
2459 @retval TRUE Find the name for this device.
2460 @retval FALSE Not found the name for this device.
2463 OpalDriverGetDeviceNameByProtocol(
2464 EFI_HANDLE
*AllHandlesBuffer
,
2465 UINTN NumAllHandles
,
2466 OPAL_DRIVER_DEVICE
*Dev
,
2470 EFI_HANDLE
* ProtocolHandlesBuffer
;
2471 UINTN NumProtocolHandles
;
2473 EFI_COMPONENT_NAME2_PROTOCOL
* Cnp1_2
; // efi component name and componentName2 have same layout
2476 EFI_DEVICE_PATH_PROTOCOL
* TmpDevPath
;
2479 EFI_HANDLE TmpHandle
;
2482 if (Dev
== NULL
|| AllHandlesBuffer
== NULL
|| NumAllHandles
== 0) {
2486 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
2489 // Find all EFI_HANDLES with protocol
2491 Status
= gBS
->LocateHandleBuffer(
2495 &NumProtocolHandles
,
2496 &ProtocolHandlesBuffer
2498 if (EFI_ERROR(Status
)) {
2504 // Exit early if no supported devices
2506 if (NumProtocolHandles
== 0) {
2511 // Get printable name by iterating through all protocols
2512 // using the handle as the child, and iterate through all handles for the controller
2513 // exit loop early once found, if not found, then delete device
2514 // storage security protocol instances already exist, add them to internal list
2516 Status
= EFI_DEVICE_ERROR
;
2517 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
2520 if (Dev
->Name16
!= NULL
) {
2524 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
2526 Status
= gBS
->OpenProtocol(
2532 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2534 if (EFI_ERROR(Status
) || Cnp1_2
== NULL
) {
2539 // Use all handles array as controller handle
2541 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
2542 Status
= Cnp1_2
->GetControllerName(
2544 AllHandlesBuffer
[Index2
],
2546 LANGUAGE_ISO_639_2_ENGLISH
,
2549 if (EFI_ERROR(Status
)) {
2550 Status
= Cnp1_2
->GetControllerName(
2552 AllHandlesBuffer
[Index2
],
2554 LANGUAGE_RFC_3066_ENGLISH
,
2558 if (!EFI_ERROR(Status
) && DevName
!= NULL
) {
2559 StrLength
= StrLen(DevName
) + 1; // Add one for NULL terminator
2560 Dev
->Name16
= AllocateZeroPool(StrLength
* sizeof (CHAR16
));
2561 ASSERT (Dev
->Name16
!= NULL
);
2562 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
2563 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool(StrLength
);
2564 UnicodeStrToAsciiStrS (DevName
, Dev
->NameZ
, StrLength
);
2567 // Retrieve bridge BDF info and port number or namespace depending on type
2570 Status
= gBS
->OpenProtocol(
2572 &gEfiDevicePathProtocolGuid
,
2573 (VOID
**)&TmpDevPath
,
2576 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2578 if (!EFI_ERROR(Status
)) {
2579 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
2583 if (Dev
->Name16
!= NULL
) {
2584 FreePool(Dev
->Name16
);
2587 if (Dev
->NameZ
!= NULL
) {
2588 FreePool(Dev
->NameZ
);
2599 Get devcie name through the component name protocol.
2601 @param[in] Dev The device which need to get name.
2603 @retval TRUE Find the name for this device.
2604 @retval FALSE Not found the name for this device.
2607 OpalDriverGetDriverDeviceName(
2608 OPAL_DRIVER_DEVICE
*Dev
2611 EFI_HANDLE
* AllHandlesBuffer
;
2612 UINTN NumAllHandles
;
2616 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
2621 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
2623 if (Dev
->Name16
== NULL
) {
2624 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
2626 // Find all EFI_HANDLES
2628 Status
= gBS
->LocateHandleBuffer(
2635 if (EFI_ERROR(Status
)) {
2636 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
2641 // Try component Name2
2643 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
2644 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
2645 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
2646 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
2656 Main entry for this driver.
2658 @param ImageHandle Image Handle this driver.
2659 @param SystemTable Pointer to SystemTable.
2661 @retval EFI_SUCESS This function always complete successfully.
2665 EfiDriverEntryPoint(
2666 IN EFI_HANDLE ImageHandle
,
2667 IN EFI_SYSTEM_TABLE
* SystemTable
2671 EFI_EVENT ReadyToBootEvent
;
2672 EFI_EVENT EndOfDxeEvent
;
2674 Status
= EfiLibInstallDriverBindingComponentName2 (
2677 &gOpalDriverBinding
,
2679 &gOpalComponentName
,
2680 &gOpalComponentName2
2683 if (EFI_ERROR(Status
)) {
2684 DEBUG((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
2689 // Initialize Driver object
2691 ZeroMem(&mOpalDriver
, sizeof(mOpalDriver
));
2692 mOpalDriver
.Handle
= ImageHandle
;
2694 Status
= gBS
->CreateEventEx (
2697 OpalEndOfDxeEventNotify
,
2699 &gEfiEndOfDxeEventGroupGuid
,
2702 ASSERT_EFI_ERROR (Status
);
2705 // register a ReadyToBoot event callback for sending BlockSid command
2707 Status
= EfiCreateEventReadyToBootEx (
2709 ReadyToBootCallback
,
2710 (VOID
*) &ImageHandle
,
2715 // Install Hii packages.
2723 Tests to see if this driver supports a given controller.
2725 This function checks to see if the controller contains an instance of the
2726 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL
2727 and returns EFI_SUCCESS if it does.
2729 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2730 @param[in] ControllerHandle The Handle of the controller to test. This Handle
2731 must support a protocol interface that supplies
2732 an I/O abstraction to the driver.
2733 @param[in] RemainingDevicePath This parameter is ignored.
2735 @retval EFI_SUCCESS The device contains required protocols
2736 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
2737 RemainingDevicePath is already being managed by the driver
2739 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
2740 RemainingDevicePath is already being managed by a different
2741 driver or an application that requires exclusive access.
2742 Currently not implemented.
2743 @retval EFI_UNSUPPORTED The device does not contain requires protocols
2748 OpalEfiDriverBindingSupported(
2749 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2750 IN EFI_HANDLE Controller
,
2751 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2755 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
* SecurityCommand
;
2756 EFI_BLOCK_IO_PROTOCOL
* BlkIo
;
2758 if (mOpalEndOfDxe
) {
2759 return EFI_UNSUPPORTED
;
2763 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
2765 Status
= gBS
->OpenProtocol(
2767 &gEfiStorageSecurityCommandProtocolGuid
,
2768 ( VOID
** )&SecurityCommand
,
2769 This
->DriverBindingHandle
,
2771 EFI_OPEN_PROTOCOL_BY_DRIVER
2774 if (Status
== EFI_ALREADY_STARTED
) {
2778 if (EFI_ERROR(Status
)) {
2783 // Close protocol and reopen in Start call
2787 &gEfiStorageSecurityCommandProtocolGuid
,
2788 This
->DriverBindingHandle
,
2793 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2796 Status
= gBS
->OpenProtocol(
2798 &gEfiBlockIoProtocolGuid
,
2800 This
->DriverBindingHandle
,
2802 EFI_OPEN_PROTOCOL_BY_DRIVER
2805 if (EFI_ERROR(Status
)) {
2806 DEBUG((DEBUG_INFO
, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
2811 // Close protocol and reopen in Start call
2815 &gEfiBlockIoProtocolGuid
,
2816 This
->DriverBindingHandle
,
2824 Enables Opal Management on a supported device if available.
2826 The start function is designed to be called after the Opal UEFI Driver has confirmed the
2827 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
2828 This function will complete the other necessary checks, such as verifying the device supports
2829 the correct version of Opal. Upon verification, it will add the device to the
2830 Opal HII list in order to expose Opal managmeent options.
2832 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2833 @param[in] ControllerHandle The Handle of the controller to start. This Handle
2834 must support a protocol interface that supplies
2835 an I/O abstraction to the driver.
2836 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
2837 parameter is ignored by device drivers, and is optional for bus
2838 drivers. For a bus driver, if this parameter is NULL, then handles
2839 for all the children of Controller are created by this driver.
2840 If this parameter is not NULL and the first Device Path Node is
2841 not the End of Device Path Node, then only the Handle for the
2842 child device specified by the first Device Path Node of
2843 RemainingDevicePath is created by this driver.
2844 If the first Device Path Node of RemainingDevicePath is
2845 the End of Device Path Node, no child Handle is created by this
2848 @retval EFI_SUCCESS Opal management was enabled.
2849 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
2850 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
2851 @retval Others The driver failed to start the device.
2856 OpalEfiDriverBindingStart(
2857 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2858 IN EFI_HANDLE Controller
,
2859 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2863 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
2864 OPAL_DRIVER_DEVICE
*Dev
;
2865 OPAL_DRIVER_DEVICE
*Itr
;
2868 Itr
= mOpalDriver
.DeviceList
;
2869 while (Itr
!= NULL
) {
2870 if (Controller
== Itr
->Handle
) {
2877 // Create internal device for tracking. This allows all disks to be tracked
2880 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE
));
2882 return EFI_OUT_OF_RESOURCES
;
2884 Dev
->Handle
= Controller
;
2887 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
2889 Status
= gBS
->OpenProtocol(
2891 &gEfiStorageSecurityCommandProtocolGuid
,
2892 (VOID
**)&Dev
->Sscp
,
2893 This
->DriverBindingHandle
,
2895 EFI_OPEN_PROTOCOL_BY_DRIVER
2897 if (EFI_ERROR(Status
)) {
2903 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2906 Status
= gBS
->OpenProtocol(
2908 &gEfiBlockIoProtocolGuid
,
2910 This
->DriverBindingHandle
,
2912 EFI_OPEN_PROTOCOL_BY_DRIVER
2914 if (EFI_ERROR(Status
)) {
2916 // Close storage security that was opened
2920 &gEfiStorageSecurityCommandProtocolGuid
,
2921 This
->DriverBindingHandle
,
2932 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
2936 &gEfiBlockIoProtocolGuid
,
2937 This
->DriverBindingHandle
,
2942 // Acquire Ascii printable name of child, if not found, then ignore device
2944 Result
= OpalDriverGetDriverDeviceName (Dev
);
2949 Status
= OpalDiskInitialize (Dev
);
2950 if (EFI_ERROR (Status
)) {
2954 AddDeviceToTail(Dev
);
2957 // Check if device is locked and prompt for password.
2959 OpalDriverRequestPassword (Dev
, L
"Unlock:");
2962 // Process OPAL request from last boot.
2964 ProcessOpalRequest (Dev
);
2970 // free device, close protocols and exit
2974 &gEfiStorageSecurityCommandProtocolGuid
,
2975 This
->DriverBindingHandle
,
2981 return EFI_DEVICE_ERROR
;
2985 Stop this driver on Controller.
2987 @param This Protocol instance pointer.
2988 @param Controller Handle of device to stop driver on
2989 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
2990 children is zero stop the entire bus driver.
2991 @param ChildHandleBuffer List of Child Handles to Stop.
2993 @retval EFI_SUCCESS This driver is removed Controller.
2994 @retval other This driver could not be removed from this device.
2999 OpalEfiDriverBindingStop(
3000 EFI_DRIVER_BINDING_PROTOCOL
* This
,
3001 EFI_HANDLE Controller
,
3002 UINTN NumberOfChildren
,
3003 EFI_HANDLE
* ChildHandleBuffer
3006 OPAL_DRIVER_DEVICE
* Itr
;
3008 Itr
= mOpalDriver
.DeviceList
;
3011 // does Controller match any of the devices we are managing for Opal
3013 while (Itr
!= NULL
) {
3014 if (Itr
->Handle
== Controller
) {
3015 OpalDriverStopDevice (Itr
);
3022 return EFI_NOT_FOUND
;
3027 Unloads UEFI Driver. Very useful for debugging and testing.
3029 @param ImageHandle Image Handle this driver.
3031 @retval EFI_SUCCESS This function always complete successfully.
3032 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
3036 OpalEfiDriverUnload (
3037 IN EFI_HANDLE ImageHandle
3041 OPAL_DRIVER_DEVICE
*Itr
;
3043 Status
= EFI_SUCCESS
;
3045 if (ImageHandle
!= gImageHandle
) {
3046 return (EFI_INVALID_PARAMETER
);
3050 // Uninstall any interface added to each device by us
3052 while (mOpalDriver
.DeviceList
) {
3053 Itr
= mOpalDriver
.DeviceList
;
3055 // Remove OPAL_DRIVER_DEVICE from the list
3056 // it updates the controllerList pointer
3058 OpalDriverStopDevice(Itr
);
3062 // Uninstall the HII capability
3064 Status
= HiiUninstall();