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
[256];
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
109 // Revert is allowed for any device with media encryption support, however it requires
111 if (SupportedAttributes
->MediaEncryption
) {
114 // Only allow psid revert if media encryption is enabled.
115 // Otherwise, someone who steals a disk can psid revert the disk and the user Data is still
116 // intact and accessible
118 AvalDiskActions
->PsidRevert
= 1;
119 AvalDiskActions
->RevertKeepDataForced
= 0;
122 // Secure erase is performed by generating a new encryption key
123 // this is only available if encryption is supported
125 AvalDiskActions
->SecureErase
= 1;
127 AvalDiskActions
->PsidRevert
= 0;
128 AvalDiskActions
->SecureErase
= 0;
131 // If no media encryption is supported, then a revert (using password) will not
132 // erase the Data (since you can't generate a new encryption key)
134 AvalDiskActions
->RevertKeepDataForced
= 1;
137 if (LockingFeature
->Locked
) {
138 AvalDiskActions
->Unlock
= 1;
140 AvalDiskActions
->Unlock
= 0;
144 // Only allow user to set password if an admin password exists
146 ExistingPassword
= OpalUtilAdminPasswordExists(OwnerShip
, LockingFeature
);
147 AvalDiskActions
->UserPass
= ExistingPassword
;
150 // This will still show up even if there isn't a user, which is fine
152 AvalDiskActions
->DisableUser
= ExistingPassword
;
154 return TcgResultSuccess
;
158 Enable Opal Feature for the input device.
160 @param[in] Session The opal session for the opal device.
162 @param[in] MsidLength Msid Length
163 @param[in] Password Admin password
164 @param[in] PassLength Length of password in bytes
169 OpalSupportEnableOpalFeature (
170 IN OPAL_SESSION
*Session
,
172 IN UINT32 MsidLength
,
181 NULL_CHECK(Password
);
183 Ret
= OpalUtilSetAdminPasswordAsSid(
190 if (Ret
== TcgResultSuccess
) {
192 // Enable global locking range
194 Ret
= OpalUtilSetOpalLockingRange(
198 OPAL_LOCKING_SP_LOCKING_GLOBALRANGE
,
212 Update password for the Opal disk.
214 @param[in, out] OpalDisk The disk to update password.
215 @param[in] Password The input password.
216 @param[in] PasswordLength The input password length.
220 OpalSupportUpdatePassword (
221 IN OUT OPAL_DISK
*OpalDisk
,
223 IN UINT32 PasswordLength
226 CopyMem (OpalDisk
->Password
, Password
, PasswordLength
);
227 OpalDisk
->PasswordLength
= (UINT8
) PasswordLength
;
231 Extract device info from the device path.
233 @param[in] DevicePath Device path info for the device.
234 @param[out] DevInfoLength Device information length needed.
235 @param[out] DevInfo Device information extracted.
241 ExtractDeviceInfoFromDevicePath (
242 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
243 OUT UINT16
*DevInfoLength
,
244 OUT OPAL_DEVICE_COMMON
*DevInfo OPTIONAL
247 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath
;
248 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath2
;
249 PCI_DEVICE_PATH
*PciDevPath
;
252 OPAL_PCI_DEVICE
*PciDevice
;
253 OPAL_DEVICE_ATA
*DevInfoAta
;
254 OPAL_DEVICE_NVME
*DevInfoNvme
;
255 SATA_DEVICE_PATH
*SataDevPath
;
256 NVME_NAMESPACE_DEVICE_PATH
*NvmeDevPath
;
258 ASSERT (DevicePath
!= NULL
);
259 ASSERT (DevInfoLength
!= NULL
);
261 DeviceType
= OPAL_DEVICE_TYPE_UNKNOWN
;
264 TmpDevPath
= DevicePath
;
269 while (!IsDevicePathEnd (TmpDevPath
)) {
270 if (TmpDevPath
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath
->SubType
== MSG_SATA_DP
) {
274 if (DevInfo
!= NULL
) {
275 SataDevPath
= (SATA_DEVICE_PATH
*) TmpDevPath
;
276 DevInfoAta
= (OPAL_DEVICE_ATA
*) DevInfo
;
277 DevInfoAta
->Port
= SataDevPath
->HBAPortNumber
;
278 DevInfoAta
->PortMultiplierPort
= SataDevPath
->PortMultiplierPortNumber
;
280 DeviceType
= OPAL_DEVICE_TYPE_ATA
;
281 *DevInfoLength
= sizeof (OPAL_DEVICE_ATA
);
283 } else if (TmpDevPath
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath
->SubType
== MSG_NVME_NAMESPACE_DP
) {
287 if (DevInfo
!= NULL
) {
288 NvmeDevPath
= (NVME_NAMESPACE_DEVICE_PATH
*) TmpDevPath
;
289 DevInfoNvme
= (OPAL_DEVICE_NVME
*) DevInfo
;
290 DevInfoNvme
->NvmeNamespaceId
= NvmeDevPath
->NamespaceId
;
292 DeviceType
= OPAL_DEVICE_TYPE_NVME
;
293 *DevInfoLength
= sizeof (OPAL_DEVICE_NVME
);
296 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
303 TmpDevPath
= DevicePath
;
304 TmpDevPath2
= NextDevicePathNode (DevicePath
);
305 while (!IsDevicePathEnd (TmpDevPath2
)) {
306 if (TmpDevPath
->Type
== HARDWARE_DEVICE_PATH
&& TmpDevPath
->SubType
== HW_PCI_DP
) {
307 PciDevPath
= (PCI_DEVICE_PATH
*) TmpDevPath
;
308 if ((TmpDevPath2
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath2
->SubType
== MSG_NVME_NAMESPACE_DP
)||
309 (TmpDevPath2
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath2
->SubType
== MSG_SATA_DP
)) {
310 if (DevInfo
!= NULL
) {
311 PciDevice
= &DevInfo
->Device
;
312 PciDevice
->Segment
= 0;
313 PciDevice
->Bus
= BusNum
;
314 PciDevice
->Device
= PciDevPath
->Device
;
315 PciDevice
->Function
= PciDevPath
->Function
;
318 if (DevInfo
!= NULL
) {
319 PciDevice
= (OPAL_PCI_DEVICE
*) ((UINTN
) DevInfo
+ *DevInfoLength
);
320 PciDevice
->Segment
= 0;
321 PciDevice
->Bus
= BusNum
;
322 PciDevice
->Device
= PciDevPath
->Device
;
323 PciDevice
->Function
= PciDevPath
->Function
;
325 *DevInfoLength
+= sizeof (OPAL_PCI_DEVICE
);
326 if (TmpDevPath2
->Type
== HARDWARE_DEVICE_PATH
&& TmpDevPath2
->SubType
== HW_PCI_DP
) {
327 BusNum
= PciRead8 (PCI_LIB_ADDRESS (BusNum
, PciDevPath
->Device
, PciDevPath
->Function
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
332 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
333 TmpDevPath2
= NextDevicePathNode (TmpDevPath2
);
336 ASSERT (DeviceType
!= OPAL_DEVICE_TYPE_UNKNOWN
);
341 Save boot script for ATA OPAL device.
343 @param[in] DevInfo Pointer to ATA Opal device information.
347 OpalDeviceAtaSaveBootScript (
348 IN OPAL_DEVICE_ATA
*DevInfo
358 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
360 OPAL_HC_PCI_REGISTER_SAVE
*HcRegisterSaveListPtr
;
365 Bus
= DevInfo
->Device
.Bus
;
366 Device
= DevInfo
->Device
.Device
;
367 Function
= DevInfo
->Device
.Function
;
369 HcRegisterSaveListPtr
= (OPAL_HC_PCI_REGISTER_SAVE
*) mSataHcRegisterSaveTemplate
;
370 Count
= sizeof (mSataHcRegisterSaveTemplate
) / sizeof (OPAL_HC_PCI_REGISTER_SAVE
);
372 for (Index
= 0; Index
< Count
; Index
++) {
373 Offset
= HcRegisterSaveListPtr
[Index
].Address
;
374 Width
= HcRegisterSaveListPtr
[Index
].Width
;
377 case S3BootScriptWidthUint8
:
378 Data
= (UINT32
)PciRead8 (PCI_LIB_ADDRESS(Bus
,Device
,Function
,Offset
));
380 case S3BootScriptWidthUint16
:
381 Data
= (UINT32
)PciRead16 (PCI_LIB_ADDRESS(Bus
,Device
,Function
,Offset
));
383 case S3BootScriptWidthUint32
:
384 Data
= PciRead32 (PCI_LIB_ADDRESS(Bus
,Device
,Function
,Offset
));
391 Address
= S3_BOOT_SCRIPT_LIB_PCI_ADDRESS (Bus
, Device
, Function
, Offset
);
392 Status
= S3BootScriptSavePciCfgWrite (Width
, Address
, 1, &Data
);
393 ASSERT_EFI_ERROR (Status
);
398 Build ATA OPAL device info and save them to LockBox.
400 @param[in] BarAddr Bar address allocated.
404 BuildOpalDeviceInfoAta (
410 OPAL_DEVICE_ATA
*DevInfoAta
;
411 OPAL_DEVICE_ATA
*TempDevInfoAta
;
412 UINTN DevInfoLengthAta
;
413 UINT16 DevInfoLength
;
414 OPAL_DRIVER_DEVICE
*TmpDev
;
417 // Build ATA OPAL device info and save them to LockBox.
419 DevInfoLengthAta
= 0;
420 TmpDev
= mOpalDriver
.DeviceList
;
421 while (TmpDev
!= NULL
) {
422 DeviceType
= ExtractDeviceInfoFromDevicePath (
423 TmpDev
->OpalDisk
.OpalDevicePath
,
427 if (DeviceType
== OPAL_DEVICE_TYPE_ATA
) {
428 DevInfoLengthAta
+= DevInfoLength
;
431 TmpDev
= TmpDev
->Next
;
434 if (DevInfoLengthAta
== 0) {
438 DevInfoAta
= AllocateZeroPool (DevInfoLengthAta
);
439 ASSERT (DevInfoAta
!= NULL
);
441 TempDevInfoAta
= DevInfoAta
;
442 TmpDev
= mOpalDriver
.DeviceList
;
443 while (TmpDev
!= NULL
) {
444 DeviceType
= ExtractDeviceInfoFromDevicePath (
445 TmpDev
->OpalDisk
.OpalDevicePath
,
449 if (DeviceType
== OPAL_DEVICE_TYPE_ATA
) {
450 ExtractDeviceInfoFromDevicePath (
451 TmpDev
->OpalDisk
.OpalDevicePath
,
453 (OPAL_DEVICE_COMMON
*) TempDevInfoAta
455 TempDevInfoAta
->Length
= DevInfoLength
;
456 TempDevInfoAta
->OpalBaseComId
= TmpDev
->OpalDisk
.OpalBaseComId
;
457 TempDevInfoAta
->BarAddr
= BarAddr
;
459 TempDevInfoAta
->Password
,
460 TmpDev
->OpalDisk
.Password
,
461 TmpDev
->OpalDisk
.PasswordLength
463 TempDevInfoAta
->PasswordLength
= TmpDev
->OpalDisk
.PasswordLength
;
464 OpalDeviceAtaSaveBootScript (TempDevInfoAta
);
465 TempDevInfoAta
= (OPAL_DEVICE_ATA
*) ((UINTN
) TempDevInfoAta
+ DevInfoLength
);
468 TmpDev
= TmpDev
->Next
;
471 Status
= SaveLockBox (
476 ASSERT_EFI_ERROR (Status
);
478 Status
= SetLockBoxAttributes (
480 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
482 ASSERT_EFI_ERROR (Status
);
484 ZeroMem (DevInfoAta
, DevInfoLengthAta
);
485 FreePool (DevInfoAta
);
489 Build NVMe OPAL device info and save them to LockBox.
491 @param[in] BarAddr Bar address allocated.
495 BuildOpalDeviceInfoNvme (
501 OPAL_DEVICE_NVME
*DevInfoNvme
;
502 OPAL_DEVICE_NVME
*TempDevInfoNvme
;
503 UINTN DevInfoLengthNvme
;
504 UINT16 DevInfoLength
;
505 OPAL_DRIVER_DEVICE
*TmpDev
;
508 // Build NVMe OPAL device info and save them to LockBox.
510 DevInfoLengthNvme
= 0;
511 TmpDev
= mOpalDriver
.DeviceList
;
512 while (TmpDev
!= NULL
) {
513 DeviceType
= ExtractDeviceInfoFromDevicePath (
514 TmpDev
->OpalDisk
.OpalDevicePath
,
518 if (DeviceType
== OPAL_DEVICE_TYPE_NVME
) {
519 DevInfoLengthNvme
+= DevInfoLength
;
522 TmpDev
= TmpDev
->Next
;
525 if (DevInfoLengthNvme
== 0) {
529 DevInfoNvme
= AllocateZeroPool (DevInfoLengthNvme
);
530 ASSERT (DevInfoNvme
!= NULL
);
532 TempDevInfoNvme
= DevInfoNvme
;
533 TmpDev
= mOpalDriver
.DeviceList
;
534 while (TmpDev
!= NULL
) {
535 DeviceType
= ExtractDeviceInfoFromDevicePath (
536 TmpDev
->OpalDisk
.OpalDevicePath
,
540 if (DeviceType
== OPAL_DEVICE_TYPE_NVME
) {
541 ExtractDeviceInfoFromDevicePath (
542 TmpDev
->OpalDisk
.OpalDevicePath
,
544 (OPAL_DEVICE_COMMON
*) TempDevInfoNvme
546 TempDevInfoNvme
->Length
= DevInfoLength
;
547 TempDevInfoNvme
->OpalBaseComId
= TmpDev
->OpalDisk
.OpalBaseComId
;
548 TempDevInfoNvme
->BarAddr
= BarAddr
;
550 TempDevInfoNvme
->Password
,
551 TmpDev
->OpalDisk
.Password
,
552 TmpDev
->OpalDisk
.PasswordLength
554 TempDevInfoNvme
->PasswordLength
= TmpDev
->OpalDisk
.PasswordLength
;
555 TempDevInfoNvme
= (OPAL_DEVICE_NVME
*) ((UINTN
) TempDevInfoNvme
+ DevInfoLength
);
558 TmpDev
= TmpDev
->Next
;
561 Status
= SaveLockBox (
562 &mOpalDeviceNvmeGuid
,
566 ASSERT_EFI_ERROR (Status
);
568 Status
= SetLockBoxAttributes (
569 &mOpalDeviceNvmeGuid
,
570 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
572 ASSERT_EFI_ERROR (Status
);
574 ZeroMem (DevInfoNvme
, DevInfoLengthNvme
);
575 FreePool (DevInfoNvme
);
579 Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
581 This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
583 @param Event Event whose notification function is being invoked.
584 @param Context Pointer to the notification function's context.
589 OpalEndOfDxeEventNotify (
595 EFI_PHYSICAL_ADDRESS Address
;
597 OPAL_DRIVER_DEVICE
*TmpDev
;
599 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
601 mOpalEndOfDxe
= TRUE
;
603 if (mOpalRequestVariable
!= NULL
) {
605 // Free the OPAL request variable buffer here
606 // as the OPAL requests should have been processed.
608 FreePool (mOpalRequestVariable
);
609 mOpalRequestVariable
= NULL
;
610 mOpalRequestVariableSize
= 0;
614 // If no any device, return directly.
616 if (mOpalDriver
.DeviceList
== NULL
) {
617 gBS
->CloseEvent (Event
);
622 // Assume 64K size and alignment are enough.
625 Address
= 0xFFFFFFFF;
626 Status
= gDS
->AllocateMemorySpace (
627 EfiGcdAllocateMaxAddressSearchBottomUp
,
628 EfiGcdMemoryTypeMemoryMappedIo
,
629 16, // 2^16: 64K Alignment
635 ASSERT_EFI_ERROR (Status
);
637 BuildOpalDeviceInfoAta ((UINT32
) Address
);
638 BuildOpalDeviceInfoNvme ((UINT32
) Address
);
643 TmpDev
= mOpalDriver
.DeviceList
;
644 while (TmpDev
!= NULL
) {
645 ZeroMem (TmpDev
->OpalDisk
.Password
, TmpDev
->OpalDisk
.PasswordLength
);
646 TmpDev
= TmpDev
->Next
;
649 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
651 gBS
->CloseEvent (Event
);
655 Get Psid input from the popup window.
657 @param[in] Dev The device which need Psid to process Psid Revert
659 @param[in] PopUpString Pop up string.
660 @param[out] PressEsc Whether user escape function through Press ESC.
662 @retval Password string if success. NULL if failed.
666 OpalDriverPopUpPsidInput (
667 IN OPAL_DRIVER_DEVICE
*Dev
,
668 IN CHAR16
*PopUpString
,
669 OUT BOOLEAN
*PressEsc
672 EFI_INPUT_KEY InputKey
;
674 CHAR16 Mask
[PSID_CHARACTER_LENGTH
+ 1];
675 CHAR16 Unicode
[PSID_CHARACTER_LENGTH
+ 1];
678 ZeroMem(Unicode
, sizeof(Unicode
));
679 ZeroMem(Mask
, sizeof(Mask
));
683 gST
->ConOut
->ClearScreen(gST
->ConOut
);
687 Mask
[InputLength
] = L
'_';
689 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
692 L
"---------------------",
700 if (InputKey
.ScanCode
== SCAN_NULL
) {
704 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
706 // Add the null terminator.
708 Unicode
[InputLength
] = 0;
709 Mask
[InputLength
] = 0;
711 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
712 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
713 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
718 // delete last key entered
720 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
721 if (InputLength
> 0) {
722 Unicode
[InputLength
] = 0;
723 Mask
[InputLength
] = 0;
728 // add Next key entry
730 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
731 Mask
[InputLength
] = InputKey
.UnicodeChar
;
733 if (InputLength
== PSID_CHARACTER_LENGTH
) {
735 // Add the null terminator.
737 Unicode
[InputLength
] = 0;
738 Mask
[InputLength
] = 0;
748 if (InputKey
.ScanCode
== SCAN_ESC
) {
754 gST
->ConOut
->ClearScreen(gST
->ConOut
);
756 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
757 ZeroMem (Unicode
, sizeof (Unicode
));
758 ZeroMem (Mask
, sizeof (Mask
));
762 Ascii
= AllocateZeroPool (PSID_CHARACTER_LENGTH
+ 1);
764 ZeroMem (Unicode
, sizeof (Unicode
));
765 ZeroMem (Mask
, sizeof (Mask
));
769 UnicodeStrToAsciiStrS (Unicode
, Ascii
, PSID_CHARACTER_LENGTH
+ 1);
770 ZeroMem (Unicode
, sizeof (Unicode
));
771 ZeroMem (Mask
, sizeof (Mask
));
778 Get password input from the popup window.
780 @param[in] Dev The device which need password to unlock or
781 process OPAL request.
782 @param[in] PopUpString1 Pop up string 1.
783 @param[in] PopUpString2 Pop up string 2.
784 @param[out] PressEsc Whether user escape function through Press ESC.
786 @retval Password string if success. NULL if failed.
790 OpalDriverPopUpPasswordInput (
791 IN OPAL_DRIVER_DEVICE
*Dev
,
792 IN CHAR16
*PopUpString1
,
793 IN CHAR16
*PopUpString2
,
794 OUT BOOLEAN
*PressEsc
797 EFI_INPUT_KEY InputKey
;
799 CHAR16 Mask
[OPAL_MAX_PASSWORD_SIZE
+ 1];
800 CHAR16 Unicode
[OPAL_MAX_PASSWORD_SIZE
+ 1];
803 ZeroMem(Unicode
, sizeof(Unicode
));
804 ZeroMem(Mask
, sizeof(Mask
));
808 gST
->ConOut
->ClearScreen(gST
->ConOut
);
812 Mask
[InputLength
] = L
'_';
813 if (PopUpString2
== NULL
) {
815 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
818 L
"---------------------",
824 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
828 L
"---------------------",
837 if (InputKey
.ScanCode
== SCAN_NULL
) {
841 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
843 // Add the null terminator.
845 Unicode
[InputLength
] = 0;
846 Mask
[InputLength
] = 0;
848 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
849 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
850 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
855 // delete last key entered
857 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
858 if (InputLength
> 0) {
859 Unicode
[InputLength
] = 0;
860 Mask
[InputLength
] = 0;
865 // add Next key entry
867 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
868 Mask
[InputLength
] = L
'*';
870 if (InputLength
== OPAL_MAX_PASSWORD_SIZE
) {
872 // Add the null terminator.
874 Unicode
[InputLength
] = 0;
875 Mask
[InputLength
] = 0;
885 if (InputKey
.ScanCode
== SCAN_ESC
) {
891 gST
->ConOut
->ClearScreen(gST
->ConOut
);
893 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
894 ZeroMem (Unicode
, sizeof (Unicode
));
898 Ascii
= AllocateZeroPool (OPAL_MAX_PASSWORD_SIZE
+ 1);
900 ZeroMem (Unicode
, sizeof (Unicode
));
904 UnicodeStrToAsciiStrS (Unicode
, Ascii
, OPAL_MAX_PASSWORD_SIZE
+ 1);
905 ZeroMem (Unicode
, sizeof (Unicode
));
911 Check if disk is locked, show popup window and ask for password if it is.
913 @param[in] Dev The device which need to be unlocked.
914 @param[in] RequestString Request string.
919 IN OPAL_DRIVER_DEVICE
*Dev
,
920 IN CHAR16
*RequestString
925 StrLength
= StrLen (RequestString
) + 1 + MAX (StrLen (Dev
->Name16
), StrLen (L
"Disk"));
926 ASSERT (StrLength
< sizeof (mPopUpString
) / sizeof (CHAR16
));
928 if (Dev
->Name16
== NULL
) {
929 UnicodeSPrint (mPopUpString
, StrLength
+ 1, L
"%s Disk", RequestString
);
931 UnicodeSPrint (mPopUpString
, StrLength
+ 1, L
"%s %s", RequestString
, Dev
->Name16
);
938 Check if disk is locked, show popup window and ask for password if it is.
940 @param[in] Dev The device which need to be unlocked.
941 @param[in] RequestString Request string.
945 OpalDriverRequestPassword (
946 IN OPAL_DRIVER_DEVICE
*Dev
,
947 IN CHAR16
*RequestString
955 OPAL_SESSION Session
;
965 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
967 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
971 IsEnabled
= OpalFeatureEnabled (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
973 ZeroMem(&Session
, sizeof(Session
));
974 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
975 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
976 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
978 IsLocked
= OpalDeviceLocked (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
980 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
981 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
985 // Current device in the lock status and
986 // User not input password and press ESC,
987 // keep device in lock status and continue boot.
991 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
993 L
"Press ENTER to skip the request and continue boot,",
994 L
"Press ESC to input password again",
997 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
999 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1000 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1002 // Keep lock and continue boot.
1007 // Let user input password again.
1013 // Current device in the unlock status and
1014 // User not input password and press ESC,
1015 // Shutdown the device.
1019 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1021 L
"Press ENTER to shutdown, Press ESC to input password again",
1024 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1026 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1027 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1030 // Let user input password again.
1037 if (Password
== NULL
) {
1041 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1044 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
1046 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, TRUE
, TRUE
);
1047 if (Ret
== TcgResultSuccess
) {
1048 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
1052 if (Ret
== TcgResultSuccess
) {
1053 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1054 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1056 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1059 if (Password
!= NULL
) {
1060 ZeroMem (Password
, PasswordLen
);
1061 FreePool (Password
);
1064 if (Ret
== TcgResultSuccess
) {
1072 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1074 L
"Invalid password.",
1075 L
"Press ENTER to retry",
1078 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1081 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1084 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1086 L
"Opal password retry count exceeds the limit. Must shutdown!",
1087 L
"Press ENTER to shutdown",
1090 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1092 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1098 Process Enable Feature OPAL request.
1100 @param[in] Dev The device which has Enable Feature OPAL request.
1101 @param[in] RequestString Request string.
1105 ProcessOpalRequestEnableFeature (
1106 IN OPAL_DRIVER_DEVICE
*Dev
,
1107 IN CHAR16
*RequestString
1113 CHAR8
*PasswordConfirm
;
1114 UINT32 PasswordLenConfirm
;
1115 OPAL_SESSION Session
;
1119 CHAR16
*PopUpString
;
1125 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1127 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1131 ZeroMem(&Session
, sizeof(Session
));
1132 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1133 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1134 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1136 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1137 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1141 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1143 L
"Press ENTER to skip the request and continue boot,",
1144 L
"Press ESC to input password again",
1147 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1149 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1150 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1154 // Let user input password again.
1160 if (Password
== NULL
) {
1164 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1166 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1167 if (PasswordConfirm
== NULL
) {
1168 ZeroMem (Password
, PasswordLen
);
1169 FreePool (Password
);
1173 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1174 if ((PasswordLen
!= PasswordLenConfirm
) ||
1175 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1176 ZeroMem (Password
, PasswordLen
);
1177 FreePool (Password
);
1178 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1179 FreePool (PasswordConfirm
);
1182 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1184 L
"Passwords are not the same.",
1185 L
"Press ENTER to retry",
1188 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1193 if (PasswordConfirm
!= NULL
) {
1194 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1195 FreePool (PasswordConfirm
);
1198 Ret
= OpalSupportEnableOpalFeature (&Session
, Dev
->OpalDisk
.Msid
, Dev
->OpalDisk
.MsidLength
, Password
, PasswordLen
);
1199 if (Ret
== TcgResultSuccess
) {
1200 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1201 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1203 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1206 if (Password
!= NULL
) {
1207 ZeroMem (Password
, PasswordLen
);
1208 FreePool (Password
);
1211 if (Ret
== TcgResultSuccess
) {
1219 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1222 L
"Press ENTER to retry",
1225 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1228 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1231 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1233 L
"Opal password retry count exceeds the limit.",
1234 L
"Press ENTER to skip the request and continue boot",
1237 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1238 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1243 Process Disable User OPAL request.
1245 @param[in] Dev The device which has Disable User OPAL request.
1246 @param[in] RequestString Request string.
1250 ProcessOpalRequestDisableUser (
1251 IN OPAL_DRIVER_DEVICE
*Dev
,
1252 IN CHAR16
*RequestString
1258 OPAL_SESSION Session
;
1262 BOOLEAN PasswordFailed
;
1263 CHAR16
*PopUpString
;
1269 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1271 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1275 ZeroMem(&Session
, sizeof(Session
));
1276 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1277 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1278 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1280 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1281 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1285 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1287 L
"Press ENTER to skip the request and continue boot,",
1288 L
"Press ESC to input password again",
1291 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1293 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1294 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1298 // Let user input password again.
1304 if (Password
== NULL
) {
1308 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1310 Ret
= OpalUtilDisableUser(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1311 if (Ret
== TcgResultSuccess
) {
1312 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1313 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1315 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1318 if (Password
!= NULL
) {
1319 ZeroMem (Password
, PasswordLen
);
1320 FreePool (Password
);
1323 if (Ret
== TcgResultSuccess
) {
1331 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1333 L
"Invalid password, request failed.",
1334 L
"Press ENTER to retry",
1337 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1340 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1343 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1345 L
"Opal password retry count exceeds the limit.",
1346 L
"Press ENTER to skip the request and continue boot",
1349 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1350 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1355 Process Psid Revert OPAL request.
1357 @param[in] Dev The device which has Psid Revert OPAL request.
1358 @param[in] RequestString Request string.
1362 ProcessOpalRequestPsidRevert (
1363 IN OPAL_DRIVER_DEVICE
*Dev
,
1364 IN CHAR16
*RequestString
1370 OPAL_SESSION Session
;
1374 CHAR16
*PopUpString
;
1380 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1382 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1386 ZeroMem(&Session
, sizeof(Session
));
1387 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1388 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1389 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1391 while (Count
< MAX_PSID_TRY_COUNT
) {
1392 Psid
= OpalDriverPopUpPsidInput (Dev
, PopUpString
, &PressEsc
);
1396 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1398 L
"Press ENTER to skip the request and continue boot,",
1399 L
"Press ESC to input Psid again",
1402 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1404 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1405 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1409 // Let user input Psid again.
1419 PsidLen
= (UINT32
) AsciiStrLen(Psid
);
1421 Ret
= OpalUtilPsidRevert(&Session
, Psid
, PsidLen
);
1422 if (Ret
== TcgResultSuccess
) {
1423 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1425 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1429 ZeroMem (Psid
, PsidLen
);
1433 if (Ret
== TcgResultSuccess
) {
1441 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1443 L
"Invalid Psid, request failed.",
1444 L
"Press ENTER to retry",
1447 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1450 if (Count
>= MAX_PSID_TRY_COUNT
) {
1453 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1455 L
"Opal Psid retry count exceeds the limit.",
1456 L
"Press ENTER to skip the request and continue boot",
1459 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1460 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1465 Process Admin Revert OPAL request.
1467 @param[in] Dev The device which has Revert OPAL request.
1468 @param[in] KeepUserData Whether to keep user data or not.
1469 @param[in] RequestString Request string.
1473 ProcessOpalRequestRevert (
1474 IN OPAL_DRIVER_DEVICE
*Dev
,
1475 IN BOOLEAN KeepUserData
,
1476 IN CHAR16
*RequestString
1482 OPAL_SESSION Session
;
1486 BOOLEAN PasswordFailed
;
1487 CHAR16
*PopUpString
;
1493 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1495 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1499 ZeroMem(&Session
, sizeof(Session
));
1500 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1501 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1502 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1504 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1505 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1509 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1511 L
"Press ENTER to skip the request and continue boot,",
1512 L
"Press ESC to input password again",
1515 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1517 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1518 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1522 // Let user input password again.
1528 if (Password
== NULL
) {
1532 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1534 if ((Dev
->OpalDisk
.SupportedAttributes
.PyriteSsc
== 1) &&
1535 (Dev
->OpalDisk
.LockingFeature
.MediaEncryption
== 0)) {
1537 // For pyrite type device which does not support media encryption,
1538 // it does not accept "Keep User Data" parameter.
1539 // So here hardcode a FALSE for this case.
1541 Ret
= OpalUtilRevert(
1548 Dev
->OpalDisk
.MsidLength
1551 Ret
= OpalUtilRevert(
1558 Dev
->OpalDisk
.MsidLength
1561 if (Ret
== TcgResultSuccess
) {
1562 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1563 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1565 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1568 if (Password
!= NULL
) {
1569 ZeroMem (Password
, PasswordLen
);
1570 FreePool (Password
);
1573 if (Ret
== TcgResultSuccess
) {
1581 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1583 L
"Invalid password, request failed.",
1584 L
"Press ENTER to retry",
1587 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1590 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1593 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1595 L
"Opal password retry count exceeds the limit.",
1596 L
"Press ENTER to skip the request and continue boot",
1599 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1600 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1605 Process Secure Erase OPAL request.
1607 @param[in] Dev The device which has Secure Erase OPAL request.
1608 @param[in] RequestString Request string.
1612 ProcessOpalRequestSecureErase (
1613 IN OPAL_DRIVER_DEVICE
*Dev
,
1614 IN CHAR16
*RequestString
1620 OPAL_SESSION Session
;
1624 BOOLEAN PasswordFailed
;
1625 CHAR16
*PopUpString
;
1631 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1633 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1637 ZeroMem(&Session
, sizeof(Session
));
1638 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1639 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1640 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1642 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1643 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1647 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1649 L
"Press ENTER to skip the request and continue boot,",
1650 L
"Press ESC to input password again",
1653 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1655 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1656 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1660 // Let user input password again.
1666 if (Password
== NULL
) {
1670 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1672 Ret
= OpalUtilSecureErase(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1673 if (Ret
== TcgResultSuccess
) {
1674 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1675 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1677 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1680 if (Password
!= NULL
) {
1681 ZeroMem (Password
, PasswordLen
);
1682 FreePool (Password
);
1685 if (Ret
== TcgResultSuccess
) {
1693 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1695 L
"Invalid password, request failed.",
1696 L
"Press ENTER to retry",
1699 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1702 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1705 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1707 L
"Opal password retry count exceeds the limit.",
1708 L
"Press ENTER to skip the request and continue boot",
1711 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1712 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1717 Process Set Admin Pwd OPAL request.
1719 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1720 @param[in] RequestString Request string.
1724 ProcessOpalRequestSetUserPwd (
1725 IN OPAL_DRIVER_DEVICE
*Dev
,
1726 IN CHAR16
*RequestString
1731 UINT32 OldPasswordLen
;
1734 CHAR8
*PasswordConfirm
;
1735 UINT32 PasswordLenConfirm
;
1736 OPAL_SESSION Session
;
1740 CHAR16
*PopUpString
;
1746 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1748 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1752 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1753 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
1757 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1759 L
"Press ENTER to skip the request and continue boot,",
1760 L
"Press ESC to input password again",
1763 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1765 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1766 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1770 // Let user input password again.
1776 if (OldPassword
== NULL
) {
1780 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1782 ZeroMem(&Session
, sizeof(Session
));
1783 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1784 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1785 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1786 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_USER1_AUTHORITY
);
1787 if (Ret
== TcgResultSuccess
) {
1788 DEBUG ((DEBUG_INFO
, "Verify with USER1 authority : Success\n"));
1790 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1791 if (Ret
== TcgResultSuccess
) {
1792 DEBUG ((DEBUG_INFO
, "Verify with ADMIN1 authority: Success\n"));
1794 ZeroMem (OldPassword
, OldPasswordLen
);
1795 FreePool (OldPassword
);
1796 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1799 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1801 L
"Incorrect password.",
1802 L
"Press ENTER to retry",
1805 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1811 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1812 if (Password
== NULL
) {
1813 ZeroMem (OldPassword
, OldPasswordLen
);
1814 FreePool (OldPassword
);
1818 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1820 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1821 if (PasswordConfirm
== NULL
) {
1822 ZeroMem (OldPassword
, OldPasswordLen
);
1823 FreePool (OldPassword
);
1824 ZeroMem (Password
, PasswordLen
);
1825 FreePool (Password
);
1829 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1830 if ((PasswordLen
!= PasswordLenConfirm
) ||
1831 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1832 ZeroMem (OldPassword
, OldPasswordLen
);
1833 FreePool (OldPassword
);
1834 ZeroMem (Password
, PasswordLen
);
1835 FreePool (Password
);
1836 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1837 FreePool (PasswordConfirm
);
1840 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1842 L
"Passwords are not the same.",
1843 L
"Press ENTER to retry",
1846 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1851 if (PasswordConfirm
!= NULL
) {
1852 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1853 FreePool (PasswordConfirm
);
1856 ZeroMem(&Session
, sizeof(Session
));
1857 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1858 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1859 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1860 Ret
= OpalUtilSetUserPassword(
1867 if (Ret
== TcgResultSuccess
) {
1868 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1869 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1871 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1874 if (OldPassword
!= NULL
) {
1875 ZeroMem (OldPassword
, OldPasswordLen
);
1876 FreePool (OldPassword
);
1879 if (Password
!= NULL
) {
1880 ZeroMem (Password
, PasswordLen
);
1881 FreePool (Password
);
1884 if (Ret
== TcgResultSuccess
) {
1892 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1895 L
"Press ENTER to retry",
1898 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1901 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1904 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1906 L
"Opal password retry count exceeds the limit.",
1907 L
"Press ENTER to skip the request and continue boot",
1910 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1911 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1916 Process Set Admin Pwd OPAL request.
1918 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1919 @param[in] RequestString Request string.
1923 ProcessOpalRequestSetAdminPwd (
1924 IN OPAL_DRIVER_DEVICE
*Dev
,
1925 IN CHAR16
*RequestString
1930 UINT32 OldPasswordLen
;
1933 CHAR8
*PasswordConfirm
;
1934 UINT32 PasswordLenConfirm
;
1935 OPAL_SESSION Session
;
1939 CHAR16
*PopUpString
;
1945 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1947 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1951 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1952 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
1956 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1958 L
"Press ENTER to skip the request and continue boot,",
1959 L
"Press ESC to input password again",
1962 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1964 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1965 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1969 // Let user input password again.
1975 if (OldPassword
== NULL
) {
1979 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1981 ZeroMem(&Session
, sizeof(Session
));
1982 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1983 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1984 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1985 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1986 if (Ret
== TcgResultSuccess
) {
1987 DEBUG ((DEBUG_INFO
, "Verify: Success\n"));
1989 ZeroMem (OldPassword
, OldPasswordLen
);
1990 FreePool (OldPassword
);
1991 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1994 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1996 L
"Incorrect password.",
1997 L
"Press ENTER to retry",
2000 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2005 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
2006 if (Password
== NULL
) {
2007 ZeroMem (OldPassword
, OldPasswordLen
);
2008 FreePool (OldPassword
);
2012 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
2014 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
2015 if (PasswordConfirm
== NULL
) {
2016 ZeroMem (OldPassword
, OldPasswordLen
);
2017 FreePool (OldPassword
);
2018 ZeroMem (Password
, PasswordLen
);
2019 FreePool (Password
);
2023 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
2024 if ((PasswordLen
!= PasswordLenConfirm
) ||
2025 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
2026 ZeroMem (OldPassword
, OldPasswordLen
);
2027 FreePool (OldPassword
);
2028 ZeroMem (Password
, PasswordLen
);
2029 FreePool (Password
);
2030 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2031 FreePool (PasswordConfirm
);
2034 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2036 L
"Passwords are not the same.",
2037 L
"Press ENTER to retry",
2040 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2045 if (PasswordConfirm
!= NULL
) {
2046 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2047 FreePool (PasswordConfirm
);
2051 ZeroMem(&Session
, sizeof(Session
));
2052 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2053 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2054 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2055 Ret
= OpalUtilSetAdminPassword(
2062 if (Ret
== TcgResultSuccess
) {
2063 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
2064 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
2066 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
2069 if (OldPassword
!= NULL
) {
2070 ZeroMem (OldPassword
, OldPasswordLen
);
2071 FreePool (OldPassword
);
2074 if (Password
!= NULL
) {
2075 ZeroMem (Password
, PasswordLen
);
2076 FreePool (Password
);
2079 if (Ret
== TcgResultSuccess
) {
2087 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2090 L
"Press ENTER to retry",
2093 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2096 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
2099 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2101 L
"Opal password retry count exceeds the limit.",
2102 L
"Press ENTER to skip the request and continue boot",
2105 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2106 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2111 Process OPAL request.
2113 @param[in] Dev The device which has OPAL request.
2117 ProcessOpalRequest (
2118 IN OPAL_DRIVER_DEVICE
*Dev
2122 OPAL_REQUEST_VARIABLE
*TempVariable
;
2123 OPAL_REQUEST_VARIABLE
*Variable
;
2125 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInVariable
;
2126 UINTN DevicePathSizeInVariable
;
2127 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2128 UINTN DevicePathSize
;
2129 BOOLEAN KeepUserData
;
2131 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
2133 if (mOpalRequestVariable
== NULL
) {
2134 Status
= GetVariable2 (
2135 OPAL_REQUEST_VARIABLE_NAME
,
2136 &gHiiSetupVariableGuid
,
2137 (VOID
**) &Variable
,
2140 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
2143 mOpalRequestVariable
= Variable
;
2144 mOpalRequestVariableSize
= VariableSize
;
2147 // Delete the OPAL request variable.
2149 Status
= gRT
->SetVariable (
2150 OPAL_REQUEST_VARIABLE_NAME
,
2151 (EFI_GUID
*) &gHiiSetupVariableGuid
,
2156 ASSERT_EFI_ERROR (Status
);
2158 Variable
= mOpalRequestVariable
;
2159 VariableSize
= mOpalRequestVariableSize
;
2163 // Process the OPAL requests.
2165 TempVariable
= Variable
;
2166 while ((VariableSize
> sizeof (OPAL_REQUEST_VARIABLE
)) &&
2167 (VariableSize
>= TempVariable
->Length
) &&
2168 (TempVariable
->Length
> sizeof (OPAL_REQUEST_VARIABLE
))) {
2169 DevicePathInVariable
= (EFI_DEVICE_PATH_PROTOCOL
*) ((UINTN
) TempVariable
+ sizeof (OPAL_REQUEST_VARIABLE
));
2170 DevicePathSizeInVariable
= GetDevicePathSize (DevicePathInVariable
);
2171 DevicePath
= Dev
->OpalDisk
.OpalDevicePath
;
2172 DevicePathSize
= GetDevicePathSize (DevicePath
);
2173 if ((DevicePathSize
== DevicePathSizeInVariable
) &&
2174 (CompareMem (DevicePath
, DevicePathInVariable
, DevicePathSize
) == 0)) {
2176 // Found the node for the OPAL device.
2178 if (TempVariable
->OpalRequest
.SetAdminPwd
!= 0) {
2179 ProcessOpalRequestSetAdminPwd (Dev
, L
"Update Admin Pwd:");
2181 if (TempVariable
->OpalRequest
.SetUserPwd
!= 0) {
2182 ProcessOpalRequestSetUserPwd (Dev
, L
"Set User Pwd:");
2184 if (TempVariable
->OpalRequest
.SecureErase
!= 0) {
2185 ProcessOpalRequestSecureErase (Dev
, L
"Secure Erase:");
2187 if (TempVariable
->OpalRequest
.Revert
!= 0) {
2188 KeepUserData
= (BOOLEAN
) TempVariable
->OpalRequest
.KeepUserData
;
2189 ProcessOpalRequestRevert (
2192 KeepUserData
? L
"Admin Revert(keep):" : L
"Admin Revert:"
2195 if (TempVariable
->OpalRequest
.PsidRevert
!= 0) {
2196 ProcessOpalRequestPsidRevert (Dev
, L
"Psid Revert:");
2198 if (TempVariable
->OpalRequest
.DisableUser
!= 0) {
2199 ProcessOpalRequestDisableUser (Dev
, L
"Disable User:");
2201 if (TempVariable
->OpalRequest
.EnableFeature
!= 0) {
2202 ProcessOpalRequestEnableFeature (Dev
, L
"Enable Feature:");
2208 VariableSize
-= TempVariable
->Length
;
2209 TempVariable
= (OPAL_REQUEST_VARIABLE
*) ((UINTN
) TempVariable
+ TempVariable
->Length
);
2212 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
2216 Add new device to the global device list.
2218 @param Dev New create device.
2223 IN OPAL_DRIVER_DEVICE
*Dev
2226 OPAL_DRIVER_DEVICE
*TmpDev
;
2228 if (mOpalDriver
.DeviceList
== NULL
) {
2229 mOpalDriver
.DeviceList
= Dev
;
2231 TmpDev
= mOpalDriver
.DeviceList
;
2232 while (TmpDev
->Next
!= NULL
) {
2233 TmpDev
= TmpDev
->Next
;
2241 Remove one device in the global device list.
2243 @param Dev The device need to be removed.
2248 IN OPAL_DRIVER_DEVICE
*Dev
2251 OPAL_DRIVER_DEVICE
*TmpDev
;
2253 if (mOpalDriver
.DeviceList
== NULL
) {
2257 if (mOpalDriver
.DeviceList
== Dev
) {
2258 mOpalDriver
.DeviceList
= NULL
;
2262 TmpDev
= mOpalDriver
.DeviceList
;
2263 while (TmpDev
->Next
!= NULL
) {
2264 if (TmpDev
->Next
== Dev
) {
2265 TmpDev
->Next
= Dev
->Next
;
2272 Get current device count.
2274 @retval return the current created device count.
2283 OPAL_DRIVER_DEVICE
*TmpDev
;
2286 TmpDev
= mOpalDriver
.DeviceList
;
2288 while (TmpDev
!= NULL
) {
2290 TmpDev
= TmpDev
->Next
;
2297 Get devcie list info.
2299 @retval return the device list pointer.
2302 OpalDriverGetDeviceList(
2306 return mOpalDriver
.DeviceList
;
2310 ReadyToBoot callback to send BlockSid command.
2312 @param Event Pointer to this event
2313 @param Context Event handler private Data
2318 ReadyToBootCallback (
2323 OPAL_DRIVER_DEVICE
*Itr
;
2325 OPAL_SESSION Session
;
2326 UINT32 PpStorageFlag
;
2328 gBS
->CloseEvent (Event
);
2330 PpStorageFlag
= Tcg2PhysicalPresenceLibGetManagementFlags ();
2331 if ((PpStorageFlag
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID
) != 0) {
2333 // Send BlockSID command to each Opal disk
2335 Itr
= mOpalDriver
.DeviceList
;
2336 while (Itr
!= NULL
) {
2337 if (Itr
->OpalDisk
.SupportedAttributes
.BlockSid
) {
2338 ZeroMem(&Session
, sizeof(Session
));
2339 Session
.Sscp
= Itr
->OpalDisk
.Sscp
;
2340 Session
.MediaId
= Itr
->OpalDisk
.MediaId
;
2341 Session
.OpalBaseComId
= Itr
->OpalDisk
.OpalBaseComId
;
2343 Result
= OpalBlockSid (&Session
, TRUE
); // HardwareReset must always be TRUE
2344 if (Result
!= TcgResultSuccess
) {
2345 DEBUG ((DEBUG_ERROR
, "OpalBlockSid fail\n"));
2356 Stop this Controller.
2358 @param Dev The device need to be stopped.
2362 OpalDriverStopDevice (
2363 OPAL_DRIVER_DEVICE
*Dev
2369 FreePool(Dev
->Name16
);
2372 // remove OPAL_DRIVER_DEVICE from the list
2373 // it updates the controllerList pointer
2378 // close protocols that were opened
2382 &gEfiStorageSecurityCommandProtocolGuid
,
2383 gOpalDriverBinding
.DriverBindingHandle
,
2389 &gEfiBlockIoProtocolGuid
,
2390 gOpalDriverBinding
.DriverBindingHandle
,
2398 Get devcie name through the component name protocol.
2400 @param[in] AllHandlesBuffer The handle buffer for current system.
2401 @param[in] NumAllHandles The number of handles for the handle buffer.
2402 @param[in] Dev The device which need to get name.
2403 @param[in] UseComp1 Whether use component name or name2 protocol.
2405 @retval TRUE Find the name for this device.
2406 @retval FALSE Not found the name for this device.
2409 OpalDriverGetDeviceNameByProtocol(
2410 EFI_HANDLE
*AllHandlesBuffer
,
2411 UINTN NumAllHandles
,
2412 OPAL_DRIVER_DEVICE
*Dev
,
2416 EFI_HANDLE
* ProtocolHandlesBuffer
;
2417 UINTN NumProtocolHandles
;
2419 EFI_COMPONENT_NAME2_PROTOCOL
* Cnp1_2
; // efi component name and componentName2 have same layout
2422 EFI_DEVICE_PATH_PROTOCOL
* TmpDevPath
;
2425 EFI_HANDLE TmpHandle
;
2428 if (Dev
== NULL
|| AllHandlesBuffer
== NULL
|| NumAllHandles
== 0) {
2432 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
2435 // Find all EFI_HANDLES with protocol
2437 Status
= gBS
->LocateHandleBuffer(
2441 &NumProtocolHandles
,
2442 &ProtocolHandlesBuffer
2444 if (EFI_ERROR(Status
)) {
2450 // Exit early if no supported devices
2452 if (NumProtocolHandles
== 0) {
2457 // Get printable name by iterating through all protocols
2458 // using the handle as the child, and iterate through all handles for the controller
2459 // exit loop early once found, if not found, then delete device
2460 // storage security protocol instances already exist, add them to internal list
2462 Status
= EFI_DEVICE_ERROR
;
2463 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
2466 if (Dev
->Name16
!= NULL
) {
2470 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
2472 Status
= gBS
->OpenProtocol(
2478 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2480 if (EFI_ERROR(Status
) || Cnp1_2
== NULL
) {
2485 // Use all handles array as controller handle
2487 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
2488 Status
= Cnp1_2
->GetControllerName(
2490 AllHandlesBuffer
[Index2
],
2492 LANGUAGE_ISO_639_2_ENGLISH
,
2495 if (EFI_ERROR(Status
)) {
2496 Status
= Cnp1_2
->GetControllerName(
2498 AllHandlesBuffer
[Index2
],
2500 LANGUAGE_RFC_3066_ENGLISH
,
2504 if (!EFI_ERROR(Status
) && DevName
!= NULL
) {
2505 StrLength
= StrLen(DevName
) + 1; // Add one for NULL terminator
2506 Dev
->Name16
= AllocateZeroPool(StrLength
* sizeof (CHAR16
));
2507 ASSERT (Dev
->Name16
!= NULL
);
2508 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
2509 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool(StrLength
);
2510 UnicodeStrToAsciiStrS (DevName
, Dev
->NameZ
, StrLength
);
2513 // Retrieve bridge BDF info and port number or namespace depending on type
2516 Status
= gBS
->OpenProtocol(
2518 &gEfiDevicePathProtocolGuid
,
2519 (VOID
**)&TmpDevPath
,
2522 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2524 if (!EFI_ERROR(Status
)) {
2525 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
2529 if (Dev
->Name16
!= NULL
) {
2530 FreePool(Dev
->Name16
);
2533 if (Dev
->NameZ
!= NULL
) {
2534 FreePool(Dev
->NameZ
);
2545 Get devcie name through the component name protocol.
2547 @param[in] Dev The device which need to get name.
2549 @retval TRUE Find the name for this device.
2550 @retval FALSE Not found the name for this device.
2553 OpalDriverGetDriverDeviceName(
2554 OPAL_DRIVER_DEVICE
*Dev
2557 EFI_HANDLE
* AllHandlesBuffer
;
2558 UINTN NumAllHandles
;
2562 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
2567 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
2569 if (Dev
->Name16
== NULL
) {
2570 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
2572 // Find all EFI_HANDLES
2574 Status
= gBS
->LocateHandleBuffer(
2581 if (EFI_ERROR(Status
)) {
2582 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
2587 // Try component Name2
2589 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
2590 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
2591 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
2592 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
2602 Main entry for this driver.
2604 @param ImageHandle Image Handle this driver.
2605 @param SystemTable Pointer to SystemTable.
2607 @retval EFI_SUCESS This function always complete successfully.
2611 EfiDriverEntryPoint(
2612 IN EFI_HANDLE ImageHandle
,
2613 IN EFI_SYSTEM_TABLE
* SystemTable
2617 EFI_EVENT ReadyToBootEvent
;
2618 EFI_EVENT EndOfDxeEvent
;
2620 Status
= EfiLibInstallDriverBindingComponentName2 (
2623 &gOpalDriverBinding
,
2625 &gOpalComponentName
,
2626 &gOpalComponentName2
2629 if (EFI_ERROR(Status
)) {
2630 DEBUG((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
2635 // Initialize Driver object
2637 ZeroMem(&mOpalDriver
, sizeof(mOpalDriver
));
2638 mOpalDriver
.Handle
= ImageHandle
;
2640 Status
= gBS
->CreateEventEx (
2643 OpalEndOfDxeEventNotify
,
2645 &gEfiEndOfDxeEventGroupGuid
,
2648 ASSERT_EFI_ERROR (Status
);
2651 // register a ReadyToBoot event callback for sending BlockSid command
2653 Status
= EfiCreateEventReadyToBootEx (
2655 ReadyToBootCallback
,
2656 (VOID
*) &ImageHandle
,
2661 // Install Hii packages.
2669 Tests to see if this driver supports a given controller.
2671 This function checks to see if the controller contains an instance of the
2672 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL
2673 and returns EFI_SUCCESS if it does.
2675 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2676 @param[in] ControllerHandle The Handle of the controller to test. This Handle
2677 must support a protocol interface that supplies
2678 an I/O abstraction to the driver.
2679 @param[in] RemainingDevicePath This parameter is ignored.
2681 @retval EFI_SUCCESS The device contains required protocols
2682 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
2683 RemainingDevicePath is already being managed by the driver
2685 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
2686 RemainingDevicePath is already being managed by a different
2687 driver or an application that requires exclusive access.
2688 Currently not implemented.
2689 @retval EFI_UNSUPPORTED The device does not contain requires protocols
2694 OpalEfiDriverBindingSupported(
2695 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2696 IN EFI_HANDLE Controller
,
2697 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2701 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
* SecurityCommand
;
2702 EFI_BLOCK_IO_PROTOCOL
* BlkIo
;
2704 if (mOpalEndOfDxe
) {
2705 return EFI_UNSUPPORTED
;
2709 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
2711 Status
= gBS
->OpenProtocol(
2713 &gEfiStorageSecurityCommandProtocolGuid
,
2714 ( VOID
** )&SecurityCommand
,
2715 This
->DriverBindingHandle
,
2717 EFI_OPEN_PROTOCOL_BY_DRIVER
2720 if (Status
== EFI_ALREADY_STARTED
) {
2724 if (EFI_ERROR(Status
)) {
2729 // Close protocol and reopen in Start call
2733 &gEfiStorageSecurityCommandProtocolGuid
,
2734 This
->DriverBindingHandle
,
2739 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2742 Status
= gBS
->OpenProtocol(
2744 &gEfiBlockIoProtocolGuid
,
2746 This
->DriverBindingHandle
,
2748 EFI_OPEN_PROTOCOL_BY_DRIVER
2751 if (EFI_ERROR(Status
)) {
2752 DEBUG((DEBUG_INFO
, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
2757 // Close protocol and reopen in Start call
2761 &gEfiBlockIoProtocolGuid
,
2762 This
->DriverBindingHandle
,
2770 Enables Opal Management on a supported device if available.
2772 The start function is designed to be called after the Opal UEFI Driver has confirmed the
2773 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
2774 This function will complete the other necessary checks, such as verifying the device supports
2775 the correct version of Opal. Upon verification, it will add the device to the
2776 Opal HII list in order to expose Opal managmeent options.
2778 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2779 @param[in] ControllerHandle The Handle of the controller to start. This Handle
2780 must support a protocol interface that supplies
2781 an I/O abstraction to the driver.
2782 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
2783 parameter is ignored by device drivers, and is optional for bus
2784 drivers. For a bus driver, if this parameter is NULL, then handles
2785 for all the children of Controller are created by this driver.
2786 If this parameter is not NULL and the first Device Path Node is
2787 not the End of Device Path Node, then only the Handle for the
2788 child device specified by the first Device Path Node of
2789 RemainingDevicePath is created by this driver.
2790 If the first Device Path Node of RemainingDevicePath is
2791 the End of Device Path Node, no child Handle is created by this
2794 @retval EFI_SUCCESS Opal management was enabled.
2795 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
2796 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
2797 @retval Others The driver failed to start the device.
2802 OpalEfiDriverBindingStart(
2803 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2804 IN EFI_HANDLE Controller
,
2805 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2809 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
2810 OPAL_DRIVER_DEVICE
*Dev
;
2811 OPAL_DRIVER_DEVICE
*Itr
;
2814 Itr
= mOpalDriver
.DeviceList
;
2815 while (Itr
!= NULL
) {
2816 if (Controller
== Itr
->Handle
) {
2823 // Create internal device for tracking. This allows all disks to be tracked
2826 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE
));
2828 return EFI_OUT_OF_RESOURCES
;
2830 Dev
->Handle
= Controller
;
2833 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
2835 Status
= gBS
->OpenProtocol(
2837 &gEfiStorageSecurityCommandProtocolGuid
,
2838 (VOID
**)&Dev
->Sscp
,
2839 This
->DriverBindingHandle
,
2841 EFI_OPEN_PROTOCOL_BY_DRIVER
2843 if (EFI_ERROR(Status
)) {
2849 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2852 Status
= gBS
->OpenProtocol(
2854 &gEfiBlockIoProtocolGuid
,
2856 This
->DriverBindingHandle
,
2858 EFI_OPEN_PROTOCOL_BY_DRIVER
2860 if (EFI_ERROR(Status
)) {
2862 // Close storage security that was opened
2866 &gEfiStorageSecurityCommandProtocolGuid
,
2867 This
->DriverBindingHandle
,
2878 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
2882 &gEfiBlockIoProtocolGuid
,
2883 This
->DriverBindingHandle
,
2888 // Acquire Ascii printable name of child, if not found, then ignore device
2890 Result
= OpalDriverGetDriverDeviceName (Dev
);
2895 Status
= OpalDiskInitialize (Dev
);
2896 if (EFI_ERROR (Status
)) {
2900 AddDeviceToTail(Dev
);
2903 // Check if device is locked and prompt for password.
2905 OpalDriverRequestPassword (Dev
, L
"Unlock:");
2908 // Process OPAL request from last boot.
2910 ProcessOpalRequest (Dev
);
2916 // free device, close protocols and exit
2920 &gEfiStorageSecurityCommandProtocolGuid
,
2921 This
->DriverBindingHandle
,
2927 return EFI_DEVICE_ERROR
;
2931 Stop this driver on Controller.
2933 @param This Protocol instance pointer.
2934 @param Controller Handle of device to stop driver on
2935 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
2936 children is zero stop the entire bus driver.
2937 @param ChildHandleBuffer List of Child Handles to Stop.
2939 @retval EFI_SUCCESS This driver is removed Controller.
2940 @retval other This driver could not be removed from this device.
2945 OpalEfiDriverBindingStop(
2946 EFI_DRIVER_BINDING_PROTOCOL
* This
,
2947 EFI_HANDLE Controller
,
2948 UINTN NumberOfChildren
,
2949 EFI_HANDLE
* ChildHandleBuffer
2952 OPAL_DRIVER_DEVICE
* Itr
;
2954 Itr
= mOpalDriver
.DeviceList
;
2957 // does Controller match any of the devices we are managing for Opal
2959 while (Itr
!= NULL
) {
2960 if (Itr
->Handle
== Controller
) {
2961 OpalDriverStopDevice (Itr
);
2968 return EFI_NOT_FOUND
;
2973 Unloads UEFI Driver. Very useful for debugging and testing.
2975 @param ImageHandle Image Handle this driver.
2977 @retval EFI_SUCCESS This function always complete successfully.
2978 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
2982 OpalEfiDriverUnload (
2983 IN EFI_HANDLE ImageHandle
2987 OPAL_DRIVER_DEVICE
*Itr
;
2989 Status
= EFI_SUCCESS
;
2991 if (ImageHandle
!= gImageHandle
) {
2992 return (EFI_INVALID_PARAMETER
);
2996 // Uninstall any interface added to each device by us
2998 while (mOpalDriver
.DeviceList
) {
2999 Itr
= mOpalDriver
.DeviceList
;
3001 // Remove OPAL_DRIVER_DEVICE from the list
3002 // it updates the controllerList pointer
3004 OpalDriverStopDevice(Itr
);
3008 // Uninstall the HII capability
3010 Status
= HiiUninstall();