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
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 Psid 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
));
913 @param[in] Dev The OPAL device.
914 @param[in] RequestString Request string.
916 @return Pop up string.
921 IN OPAL_DRIVER_DEVICE
*Dev
,
922 IN CHAR16
*RequestString
925 if (Dev
->Name16
== NULL
) {
926 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s Disk", RequestString
);
928 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s %s", RequestString
, Dev
->Name16
);
935 Check if disk is locked, show popup window and ask for password if it is.
937 @param[in] Dev The device which need to be unlocked.
938 @param[in] RequestString Request string.
942 OpalDriverRequestPassword (
943 IN OPAL_DRIVER_DEVICE
*Dev
,
944 IN CHAR16
*RequestString
952 OPAL_SESSION Session
;
962 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
964 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
968 IsEnabled
= OpalFeatureEnabled (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
970 ZeroMem(&Session
, sizeof(Session
));
971 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
972 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
973 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
975 IsLocked
= OpalDeviceLocked (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
977 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
978 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
982 // Current device in the lock status and
983 // User not input password and press ESC,
984 // keep device in lock status and continue boot.
988 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
990 L
"Press ENTER to skip the request and continue boot,",
991 L
"Press ESC to input password again",
994 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
996 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
997 gST
->ConOut
->ClearScreen(gST
->ConOut
);
999 // Keep lock and continue boot.
1004 // Let user input password again.
1010 // Current device in the unlock status and
1011 // User not input password and press ESC,
1012 // Shutdown the device.
1016 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1018 L
"Press ENTER to shutdown, Press ESC to input password again",
1021 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1023 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1024 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1027 // Let user input password again.
1034 if (Password
== NULL
) {
1038 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1041 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
1043 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, TRUE
, TRUE
);
1044 if (Ret
== TcgResultSuccess
) {
1045 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
1049 if (Ret
== TcgResultSuccess
) {
1050 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1051 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1053 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1056 if (Password
!= NULL
) {
1057 ZeroMem (Password
, PasswordLen
);
1058 FreePool (Password
);
1061 if (Ret
== TcgResultSuccess
) {
1069 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1071 L
"Invalid password.",
1072 L
"Press ENTER to retry",
1075 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1078 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1081 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1083 L
"Opal password retry count exceeds the limit. Must shutdown!",
1084 L
"Press ENTER to shutdown",
1087 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1089 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1095 Process Enable Feature OPAL request.
1097 @param[in] Dev The device which has Enable Feature OPAL request.
1098 @param[in] RequestString Request string.
1102 ProcessOpalRequestEnableFeature (
1103 IN OPAL_DRIVER_DEVICE
*Dev
,
1104 IN CHAR16
*RequestString
1110 CHAR8
*PasswordConfirm
;
1111 UINT32 PasswordLenConfirm
;
1112 OPAL_SESSION Session
;
1116 CHAR16
*PopUpString
;
1122 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1124 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1128 ZeroMem(&Session
, sizeof(Session
));
1129 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1130 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1131 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1133 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1134 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1138 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1140 L
"Press ENTER to skip the request and continue boot,",
1141 L
"Press ESC to input password again",
1144 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1146 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1147 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1151 // Let user input password again.
1157 if (Password
== NULL
) {
1161 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1163 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1164 if (PasswordConfirm
== NULL
) {
1165 ZeroMem (Password
, PasswordLen
);
1166 FreePool (Password
);
1170 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1171 if ((PasswordLen
!= PasswordLenConfirm
) ||
1172 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1173 ZeroMem (Password
, PasswordLen
);
1174 FreePool (Password
);
1175 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1176 FreePool (PasswordConfirm
);
1179 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1181 L
"Passwords are not the same.",
1182 L
"Press ENTER to retry",
1185 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1190 if (PasswordConfirm
!= NULL
) {
1191 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1192 FreePool (PasswordConfirm
);
1195 Ret
= OpalSupportEnableOpalFeature (&Session
, Dev
->OpalDisk
.Msid
, Dev
->OpalDisk
.MsidLength
, Password
, PasswordLen
);
1196 if (Ret
== TcgResultSuccess
) {
1197 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1198 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1200 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1203 if (Password
!= NULL
) {
1204 ZeroMem (Password
, PasswordLen
);
1205 FreePool (Password
);
1208 if (Ret
== TcgResultSuccess
) {
1216 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1219 L
"Press ENTER to retry",
1222 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1225 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1228 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1230 L
"Opal password retry count exceeds the limit.",
1231 L
"Press ENTER to skip the request and continue boot",
1234 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1235 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1240 Process Disable User OPAL request.
1242 @param[in] Dev The device which has Disable User OPAL request.
1243 @param[in] RequestString Request string.
1247 ProcessOpalRequestDisableUser (
1248 IN OPAL_DRIVER_DEVICE
*Dev
,
1249 IN CHAR16
*RequestString
1255 OPAL_SESSION Session
;
1259 BOOLEAN PasswordFailed
;
1260 CHAR16
*PopUpString
;
1266 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1268 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1272 ZeroMem(&Session
, sizeof(Session
));
1273 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1274 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1275 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1277 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1278 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1282 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1284 L
"Press ENTER to skip the request and continue boot,",
1285 L
"Press ESC to input password again",
1288 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1290 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1291 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1295 // Let user input password again.
1301 if (Password
== NULL
) {
1305 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1307 Ret
= OpalUtilDisableUser(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1308 if (Ret
== TcgResultSuccess
) {
1309 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1310 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1312 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1315 if (Password
!= NULL
) {
1316 ZeroMem (Password
, PasswordLen
);
1317 FreePool (Password
);
1320 if (Ret
== TcgResultSuccess
) {
1328 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1330 L
"Invalid password, request failed.",
1331 L
"Press ENTER to retry",
1334 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1337 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1340 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1342 L
"Opal password retry count exceeds the limit.",
1343 L
"Press ENTER to skip the request and continue boot",
1346 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1347 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1352 Process Psid Revert OPAL request.
1354 @param[in] Dev The device which has Psid Revert OPAL request.
1355 @param[in] RequestString Request string.
1359 ProcessOpalRequestPsidRevert (
1360 IN OPAL_DRIVER_DEVICE
*Dev
,
1361 IN CHAR16
*RequestString
1367 OPAL_SESSION Session
;
1371 CHAR16
*PopUpString
;
1377 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1379 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1383 ZeroMem(&Session
, sizeof(Session
));
1384 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1385 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1386 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1388 while (Count
< MAX_PSID_TRY_COUNT
) {
1389 Psid
= OpalDriverPopUpPsidInput (Dev
, PopUpString
, &PressEsc
);
1393 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1395 L
"Press ENTER to skip the request and continue boot,",
1396 L
"Press ESC to input Psid again",
1399 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1401 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1402 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1406 // Let user input Psid again.
1416 PsidLen
= (UINT32
) AsciiStrLen(Psid
);
1418 Ret
= OpalUtilPsidRevert(&Session
, Psid
, PsidLen
);
1419 if (Ret
== TcgResultSuccess
) {
1420 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1422 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1426 ZeroMem (Psid
, PsidLen
);
1430 if (Ret
== TcgResultSuccess
) {
1438 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1440 L
"Invalid Psid, request failed.",
1441 L
"Press ENTER to retry",
1444 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1447 if (Count
>= MAX_PSID_TRY_COUNT
) {
1450 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1452 L
"Opal Psid retry count exceeds the limit.",
1453 L
"Press ENTER to skip the request and continue boot",
1456 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1457 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1462 Process Admin Revert OPAL request.
1464 @param[in] Dev The device which has Revert OPAL request.
1465 @param[in] KeepUserData Whether to keep user data or not.
1466 @param[in] RequestString Request string.
1470 ProcessOpalRequestRevert (
1471 IN OPAL_DRIVER_DEVICE
*Dev
,
1472 IN BOOLEAN KeepUserData
,
1473 IN CHAR16
*RequestString
1479 OPAL_SESSION Session
;
1483 BOOLEAN PasswordFailed
;
1484 CHAR16
*PopUpString
;
1490 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1492 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1496 ZeroMem(&Session
, sizeof(Session
));
1497 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1498 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1499 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1501 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1502 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1506 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1508 L
"Press ENTER to skip the request and continue boot,",
1509 L
"Press ESC to input password again",
1512 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1514 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1515 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1519 // Let user input password again.
1525 if (Password
== NULL
) {
1529 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1531 if ((Dev
->OpalDisk
.SupportedAttributes
.PyriteSsc
== 1) &&
1532 (Dev
->OpalDisk
.LockingFeature
.MediaEncryption
== 0)) {
1534 // For pyrite type device which does not support media encryption,
1535 // it does not accept "Keep User Data" parameter.
1536 // So here hardcode a FALSE for this case.
1538 Ret
= OpalUtilRevert(
1545 Dev
->OpalDisk
.MsidLength
1548 Ret
= OpalUtilRevert(
1555 Dev
->OpalDisk
.MsidLength
1558 if (Ret
== TcgResultSuccess
) {
1559 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1560 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1562 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1565 if (Password
!= NULL
) {
1566 ZeroMem (Password
, PasswordLen
);
1567 FreePool (Password
);
1570 if (Ret
== TcgResultSuccess
) {
1578 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1580 L
"Invalid password, request failed.",
1581 L
"Press ENTER to retry",
1584 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1587 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1590 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1592 L
"Opal password retry count exceeds the limit.",
1593 L
"Press ENTER to skip the request and continue boot",
1596 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1597 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1602 Process Secure Erase OPAL request.
1604 @param[in] Dev The device which has Secure Erase OPAL request.
1605 @param[in] RequestString Request string.
1609 ProcessOpalRequestSecureErase (
1610 IN OPAL_DRIVER_DEVICE
*Dev
,
1611 IN CHAR16
*RequestString
1617 OPAL_SESSION Session
;
1621 BOOLEAN PasswordFailed
;
1622 CHAR16
*PopUpString
;
1628 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1630 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1634 ZeroMem(&Session
, sizeof(Session
));
1635 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1636 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1637 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1639 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1640 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1644 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1646 L
"Press ENTER to skip the request and continue boot,",
1647 L
"Press ESC to input password again",
1650 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1652 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1653 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1657 // Let user input password again.
1663 if (Password
== NULL
) {
1667 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1669 Ret
= OpalUtilSecureErase(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1670 if (Ret
== TcgResultSuccess
) {
1671 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1672 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1674 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1677 if (Password
!= NULL
) {
1678 ZeroMem (Password
, PasswordLen
);
1679 FreePool (Password
);
1682 if (Ret
== TcgResultSuccess
) {
1690 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1692 L
"Invalid password, request failed.",
1693 L
"Press ENTER to retry",
1696 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1699 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1702 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1704 L
"Opal password retry count exceeds the limit.",
1705 L
"Press ENTER to skip the request and continue boot",
1708 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1709 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1714 Process Set Admin Pwd OPAL request.
1716 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1717 @param[in] RequestString Request string.
1721 ProcessOpalRequestSetUserPwd (
1722 IN OPAL_DRIVER_DEVICE
*Dev
,
1723 IN CHAR16
*RequestString
1728 UINT32 OldPasswordLen
;
1731 CHAR8
*PasswordConfirm
;
1732 UINT32 PasswordLenConfirm
;
1733 OPAL_SESSION Session
;
1737 CHAR16
*PopUpString
;
1743 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1745 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1749 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1750 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
1754 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1756 L
"Press ENTER to skip the request and continue boot,",
1757 L
"Press ESC to input password again",
1760 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1762 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1763 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1767 // Let user input password again.
1773 if (OldPassword
== NULL
) {
1777 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1779 ZeroMem(&Session
, sizeof(Session
));
1780 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1781 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1782 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1783 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_USER1_AUTHORITY
);
1784 if (Ret
== TcgResultSuccess
) {
1785 DEBUG ((DEBUG_INFO
, "Verify with USER1 authority : Success\n"));
1787 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1788 if (Ret
== TcgResultSuccess
) {
1789 DEBUG ((DEBUG_INFO
, "Verify with ADMIN1 authority: Success\n"));
1791 ZeroMem (OldPassword
, OldPasswordLen
);
1792 FreePool (OldPassword
);
1793 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1796 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1798 L
"Incorrect password.",
1799 L
"Press ENTER to retry",
1802 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1808 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1809 if (Password
== NULL
) {
1810 ZeroMem (OldPassword
, OldPasswordLen
);
1811 FreePool (OldPassword
);
1815 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1817 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1818 if (PasswordConfirm
== NULL
) {
1819 ZeroMem (OldPassword
, OldPasswordLen
);
1820 FreePool (OldPassword
);
1821 ZeroMem (Password
, PasswordLen
);
1822 FreePool (Password
);
1826 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1827 if ((PasswordLen
!= PasswordLenConfirm
) ||
1828 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1829 ZeroMem (OldPassword
, OldPasswordLen
);
1830 FreePool (OldPassword
);
1831 ZeroMem (Password
, PasswordLen
);
1832 FreePool (Password
);
1833 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1834 FreePool (PasswordConfirm
);
1837 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1839 L
"Passwords are not the same.",
1840 L
"Press ENTER to retry",
1843 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1848 if (PasswordConfirm
!= NULL
) {
1849 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1850 FreePool (PasswordConfirm
);
1853 ZeroMem(&Session
, sizeof(Session
));
1854 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1855 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1856 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1857 Ret
= OpalUtilSetUserPassword(
1864 if (Ret
== TcgResultSuccess
) {
1865 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1866 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1868 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1871 if (OldPassword
!= NULL
) {
1872 ZeroMem (OldPassword
, OldPasswordLen
);
1873 FreePool (OldPassword
);
1876 if (Password
!= NULL
) {
1877 ZeroMem (Password
, PasswordLen
);
1878 FreePool (Password
);
1881 if (Ret
== TcgResultSuccess
) {
1889 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1892 L
"Press ENTER to retry",
1895 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1898 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1901 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1903 L
"Opal password retry count exceeds the limit.",
1904 L
"Press ENTER to skip the request and continue boot",
1907 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1908 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1913 Process Set Admin Pwd OPAL request.
1915 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1916 @param[in] RequestString Request string.
1920 ProcessOpalRequestSetAdminPwd (
1921 IN OPAL_DRIVER_DEVICE
*Dev
,
1922 IN CHAR16
*RequestString
1927 UINT32 OldPasswordLen
;
1930 CHAR8
*PasswordConfirm
;
1931 UINT32 PasswordLenConfirm
;
1932 OPAL_SESSION Session
;
1936 CHAR16
*PopUpString
;
1942 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1944 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1948 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1949 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
1953 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1955 L
"Press ENTER to skip the request and continue boot,",
1956 L
"Press ESC to input password again",
1959 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1961 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1962 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1966 // Let user input password again.
1972 if (OldPassword
== NULL
) {
1976 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1978 ZeroMem(&Session
, sizeof(Session
));
1979 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1980 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1981 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1982 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1983 if (Ret
== TcgResultSuccess
) {
1984 DEBUG ((DEBUG_INFO
, "Verify: Success\n"));
1986 ZeroMem (OldPassword
, OldPasswordLen
);
1987 FreePool (OldPassword
);
1988 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1991 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1993 L
"Incorrect password.",
1994 L
"Press ENTER to retry",
1997 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2002 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
2003 if (Password
== NULL
) {
2004 ZeroMem (OldPassword
, OldPasswordLen
);
2005 FreePool (OldPassword
);
2009 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
2011 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
2012 if (PasswordConfirm
== NULL
) {
2013 ZeroMem (OldPassword
, OldPasswordLen
);
2014 FreePool (OldPassword
);
2015 ZeroMem (Password
, PasswordLen
);
2016 FreePool (Password
);
2020 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
2021 if ((PasswordLen
!= PasswordLenConfirm
) ||
2022 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
2023 ZeroMem (OldPassword
, OldPasswordLen
);
2024 FreePool (OldPassword
);
2025 ZeroMem (Password
, PasswordLen
);
2026 FreePool (Password
);
2027 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2028 FreePool (PasswordConfirm
);
2031 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2033 L
"Passwords are not the same.",
2034 L
"Press ENTER to retry",
2037 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2042 if (PasswordConfirm
!= NULL
) {
2043 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2044 FreePool (PasswordConfirm
);
2048 ZeroMem(&Session
, sizeof(Session
));
2049 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2050 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2051 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2052 Ret
= OpalUtilSetAdminPassword(
2059 if (Ret
== TcgResultSuccess
) {
2060 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
2061 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
2063 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
2066 if (OldPassword
!= NULL
) {
2067 ZeroMem (OldPassword
, OldPasswordLen
);
2068 FreePool (OldPassword
);
2071 if (Password
!= NULL
) {
2072 ZeroMem (Password
, PasswordLen
);
2073 FreePool (Password
);
2076 if (Ret
== TcgResultSuccess
) {
2084 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2087 L
"Press ENTER to retry",
2090 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2093 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
2096 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2098 L
"Opal password retry count exceeds the limit.",
2099 L
"Press ENTER to skip the request and continue boot",
2102 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2103 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2108 Process OPAL request.
2110 @param[in] Dev The device which has OPAL request.
2114 ProcessOpalRequest (
2115 IN OPAL_DRIVER_DEVICE
*Dev
2119 OPAL_REQUEST_VARIABLE
*TempVariable
;
2120 OPAL_REQUEST_VARIABLE
*Variable
;
2122 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInVariable
;
2123 UINTN DevicePathSizeInVariable
;
2124 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2125 UINTN DevicePathSize
;
2126 BOOLEAN KeepUserData
;
2128 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
2130 if (mOpalRequestVariable
== NULL
) {
2131 Status
= GetVariable2 (
2132 OPAL_REQUEST_VARIABLE_NAME
,
2133 &gHiiSetupVariableGuid
,
2134 (VOID
**) &Variable
,
2137 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
2140 mOpalRequestVariable
= Variable
;
2141 mOpalRequestVariableSize
= VariableSize
;
2144 // Delete the OPAL request variable.
2146 Status
= gRT
->SetVariable (
2147 OPAL_REQUEST_VARIABLE_NAME
,
2148 (EFI_GUID
*) &gHiiSetupVariableGuid
,
2153 ASSERT_EFI_ERROR (Status
);
2155 Variable
= mOpalRequestVariable
;
2156 VariableSize
= mOpalRequestVariableSize
;
2160 // Process the OPAL requests.
2162 TempVariable
= Variable
;
2163 while ((VariableSize
> sizeof (OPAL_REQUEST_VARIABLE
)) &&
2164 (VariableSize
>= TempVariable
->Length
) &&
2165 (TempVariable
->Length
> sizeof (OPAL_REQUEST_VARIABLE
))) {
2166 DevicePathInVariable
= (EFI_DEVICE_PATH_PROTOCOL
*) ((UINTN
) TempVariable
+ sizeof (OPAL_REQUEST_VARIABLE
));
2167 DevicePathSizeInVariable
= GetDevicePathSize (DevicePathInVariable
);
2168 DevicePath
= Dev
->OpalDisk
.OpalDevicePath
;
2169 DevicePathSize
= GetDevicePathSize (DevicePath
);
2170 if ((DevicePathSize
== DevicePathSizeInVariable
) &&
2171 (CompareMem (DevicePath
, DevicePathInVariable
, DevicePathSize
) == 0)) {
2173 // Found the node for the OPAL device.
2175 if (TempVariable
->OpalRequest
.SetAdminPwd
!= 0) {
2176 ProcessOpalRequestSetAdminPwd (Dev
, L
"Update Admin Pwd:");
2178 if (TempVariable
->OpalRequest
.SetUserPwd
!= 0) {
2179 ProcessOpalRequestSetUserPwd (Dev
, L
"Set User Pwd:");
2181 if (TempVariable
->OpalRequest
.SecureErase
!= 0) {
2182 ProcessOpalRequestSecureErase (Dev
, L
"Secure Erase:");
2184 if (TempVariable
->OpalRequest
.Revert
!= 0) {
2185 KeepUserData
= (BOOLEAN
) TempVariable
->OpalRequest
.KeepUserData
;
2186 ProcessOpalRequestRevert (
2189 KeepUserData
? L
"Admin Revert(keep):" : L
"Admin Revert:"
2192 if (TempVariable
->OpalRequest
.PsidRevert
!= 0) {
2193 ProcessOpalRequestPsidRevert (Dev
, L
"Psid Revert:");
2195 if (TempVariable
->OpalRequest
.DisableUser
!= 0) {
2196 ProcessOpalRequestDisableUser (Dev
, L
"Disable User:");
2198 if (TempVariable
->OpalRequest
.EnableFeature
!= 0) {
2199 ProcessOpalRequestEnableFeature (Dev
, L
"Enable Feature:");
2205 VariableSize
-= TempVariable
->Length
;
2206 TempVariable
= (OPAL_REQUEST_VARIABLE
*) ((UINTN
) TempVariable
+ TempVariable
->Length
);
2209 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
2213 Add new device to the global device list.
2215 @param Dev New create device.
2220 IN OPAL_DRIVER_DEVICE
*Dev
2223 OPAL_DRIVER_DEVICE
*TmpDev
;
2225 if (mOpalDriver
.DeviceList
== NULL
) {
2226 mOpalDriver
.DeviceList
= Dev
;
2228 TmpDev
= mOpalDriver
.DeviceList
;
2229 while (TmpDev
->Next
!= NULL
) {
2230 TmpDev
= TmpDev
->Next
;
2238 Remove one device in the global device list.
2240 @param Dev The device need to be removed.
2245 IN OPAL_DRIVER_DEVICE
*Dev
2248 OPAL_DRIVER_DEVICE
*TmpDev
;
2250 if (mOpalDriver
.DeviceList
== NULL
) {
2254 if (mOpalDriver
.DeviceList
== Dev
) {
2255 mOpalDriver
.DeviceList
= NULL
;
2259 TmpDev
= mOpalDriver
.DeviceList
;
2260 while (TmpDev
->Next
!= NULL
) {
2261 if (TmpDev
->Next
== Dev
) {
2262 TmpDev
->Next
= Dev
->Next
;
2269 Get current device count.
2271 @retval return the current created device count.
2280 OPAL_DRIVER_DEVICE
*TmpDev
;
2283 TmpDev
= mOpalDriver
.DeviceList
;
2285 while (TmpDev
!= NULL
) {
2287 TmpDev
= TmpDev
->Next
;
2294 Get devcie list info.
2296 @retval return the device list pointer.
2299 OpalDriverGetDeviceList(
2303 return mOpalDriver
.DeviceList
;
2307 ReadyToBoot callback to send BlockSid command.
2309 @param Event Pointer to this event
2310 @param Context Event handler private Data
2315 ReadyToBootCallback (
2320 OPAL_DRIVER_DEVICE
*Itr
;
2322 OPAL_SESSION Session
;
2323 UINT32 PpStorageFlag
;
2325 gBS
->CloseEvent (Event
);
2327 PpStorageFlag
= Tcg2PhysicalPresenceLibGetManagementFlags ();
2328 if ((PpStorageFlag
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID
) != 0) {
2330 // Send BlockSID command to each Opal disk
2332 Itr
= mOpalDriver
.DeviceList
;
2333 while (Itr
!= NULL
) {
2334 if (Itr
->OpalDisk
.SupportedAttributes
.BlockSid
) {
2335 ZeroMem(&Session
, sizeof(Session
));
2336 Session
.Sscp
= Itr
->OpalDisk
.Sscp
;
2337 Session
.MediaId
= Itr
->OpalDisk
.MediaId
;
2338 Session
.OpalBaseComId
= Itr
->OpalDisk
.OpalBaseComId
;
2340 Result
= OpalBlockSid (&Session
, TRUE
); // HardwareReset must always be TRUE
2341 if (Result
!= TcgResultSuccess
) {
2342 DEBUG ((DEBUG_ERROR
, "OpalBlockSid fail\n"));
2353 Stop this Controller.
2355 @param Dev The device need to be stopped.
2359 OpalDriverStopDevice (
2360 OPAL_DRIVER_DEVICE
*Dev
2366 FreePool(Dev
->Name16
);
2369 // remove OPAL_DRIVER_DEVICE from the list
2370 // it updates the controllerList pointer
2375 // close protocols that were opened
2379 &gEfiStorageSecurityCommandProtocolGuid
,
2380 gOpalDriverBinding
.DriverBindingHandle
,
2386 &gEfiBlockIoProtocolGuid
,
2387 gOpalDriverBinding
.DriverBindingHandle
,
2395 Get devcie name through the component name protocol.
2397 @param[in] AllHandlesBuffer The handle buffer for current system.
2398 @param[in] NumAllHandles The number of handles for the handle buffer.
2399 @param[in] Dev The device which need to get name.
2400 @param[in] UseComp1 Whether use component name or name2 protocol.
2402 @retval TRUE Find the name for this device.
2403 @retval FALSE Not found the name for this device.
2406 OpalDriverGetDeviceNameByProtocol(
2407 EFI_HANDLE
*AllHandlesBuffer
,
2408 UINTN NumAllHandles
,
2409 OPAL_DRIVER_DEVICE
*Dev
,
2413 EFI_HANDLE
* ProtocolHandlesBuffer
;
2414 UINTN NumProtocolHandles
;
2416 EFI_COMPONENT_NAME2_PROTOCOL
* Cnp1_2
; // efi component name and componentName2 have same layout
2419 EFI_DEVICE_PATH_PROTOCOL
* TmpDevPath
;
2422 EFI_HANDLE TmpHandle
;
2425 if (Dev
== NULL
|| AllHandlesBuffer
== NULL
|| NumAllHandles
== 0) {
2429 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
2432 // Find all EFI_HANDLES with protocol
2434 Status
= gBS
->LocateHandleBuffer(
2438 &NumProtocolHandles
,
2439 &ProtocolHandlesBuffer
2441 if (EFI_ERROR(Status
)) {
2447 // Exit early if no supported devices
2449 if (NumProtocolHandles
== 0) {
2454 // Get printable name by iterating through all protocols
2455 // using the handle as the child, and iterate through all handles for the controller
2456 // exit loop early once found, if not found, then delete device
2457 // storage security protocol instances already exist, add them to internal list
2459 Status
= EFI_DEVICE_ERROR
;
2460 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
2463 if (Dev
->Name16
!= NULL
) {
2467 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
2469 Status
= gBS
->OpenProtocol(
2475 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2477 if (EFI_ERROR(Status
) || Cnp1_2
== NULL
) {
2482 // Use all handles array as controller handle
2484 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
2485 Status
= Cnp1_2
->GetControllerName(
2487 AllHandlesBuffer
[Index2
],
2489 LANGUAGE_ISO_639_2_ENGLISH
,
2492 if (EFI_ERROR(Status
)) {
2493 Status
= Cnp1_2
->GetControllerName(
2495 AllHandlesBuffer
[Index2
],
2497 LANGUAGE_RFC_3066_ENGLISH
,
2501 if (!EFI_ERROR(Status
) && DevName
!= NULL
) {
2502 StrLength
= StrLen(DevName
) + 1; // Add one for NULL terminator
2503 Dev
->Name16
= AllocateZeroPool(StrLength
* sizeof (CHAR16
));
2504 ASSERT (Dev
->Name16
!= NULL
);
2505 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
2506 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool(StrLength
);
2507 UnicodeStrToAsciiStrS (DevName
, Dev
->NameZ
, StrLength
);
2510 // Retrieve bridge BDF info and port number or namespace depending on type
2513 Status
= gBS
->OpenProtocol(
2515 &gEfiDevicePathProtocolGuid
,
2516 (VOID
**)&TmpDevPath
,
2519 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2521 if (!EFI_ERROR(Status
)) {
2522 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
2526 if (Dev
->Name16
!= NULL
) {
2527 FreePool(Dev
->Name16
);
2530 if (Dev
->NameZ
!= NULL
) {
2531 FreePool(Dev
->NameZ
);
2542 Get devcie name through the component name protocol.
2544 @param[in] Dev The device which need to get name.
2546 @retval TRUE Find the name for this device.
2547 @retval FALSE Not found the name for this device.
2550 OpalDriverGetDriverDeviceName(
2551 OPAL_DRIVER_DEVICE
*Dev
2554 EFI_HANDLE
* AllHandlesBuffer
;
2555 UINTN NumAllHandles
;
2559 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
2564 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
2566 if (Dev
->Name16
== NULL
) {
2567 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
2569 // Find all EFI_HANDLES
2571 Status
= gBS
->LocateHandleBuffer(
2578 if (EFI_ERROR(Status
)) {
2579 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
2584 // Try component Name2
2586 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
2587 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
2588 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
2589 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
2599 Main entry for this driver.
2601 @param ImageHandle Image Handle this driver.
2602 @param SystemTable Pointer to SystemTable.
2604 @retval EFI_SUCESS This function always complete successfully.
2608 EfiDriverEntryPoint(
2609 IN EFI_HANDLE ImageHandle
,
2610 IN EFI_SYSTEM_TABLE
* SystemTable
2614 EFI_EVENT ReadyToBootEvent
;
2615 EFI_EVENT EndOfDxeEvent
;
2617 Status
= EfiLibInstallDriverBindingComponentName2 (
2620 &gOpalDriverBinding
,
2622 &gOpalComponentName
,
2623 &gOpalComponentName2
2626 if (EFI_ERROR(Status
)) {
2627 DEBUG((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
2632 // Initialize Driver object
2634 ZeroMem(&mOpalDriver
, sizeof(mOpalDriver
));
2635 mOpalDriver
.Handle
= ImageHandle
;
2637 Status
= gBS
->CreateEventEx (
2640 OpalEndOfDxeEventNotify
,
2642 &gEfiEndOfDxeEventGroupGuid
,
2645 ASSERT_EFI_ERROR (Status
);
2648 // register a ReadyToBoot event callback for sending BlockSid command
2650 Status
= EfiCreateEventReadyToBootEx (
2652 ReadyToBootCallback
,
2653 (VOID
*) &ImageHandle
,
2658 // Install Hii packages.
2666 Tests to see if this driver supports a given controller.
2668 This function checks to see if the controller contains an instance of the
2669 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL
2670 and returns EFI_SUCCESS if it does.
2672 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2673 @param[in] ControllerHandle The Handle of the controller to test. This Handle
2674 must support a protocol interface that supplies
2675 an I/O abstraction to the driver.
2676 @param[in] RemainingDevicePath This parameter is ignored.
2678 @retval EFI_SUCCESS The device contains required protocols
2679 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
2680 RemainingDevicePath is already being managed by the driver
2682 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
2683 RemainingDevicePath is already being managed by a different
2684 driver or an application that requires exclusive access.
2685 Currently not implemented.
2686 @retval EFI_UNSUPPORTED The device does not contain requires protocols
2691 OpalEfiDriverBindingSupported(
2692 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2693 IN EFI_HANDLE Controller
,
2694 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2698 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
* SecurityCommand
;
2699 EFI_BLOCK_IO_PROTOCOL
* BlkIo
;
2701 if (mOpalEndOfDxe
) {
2702 return EFI_UNSUPPORTED
;
2706 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
2708 Status
= gBS
->OpenProtocol(
2710 &gEfiStorageSecurityCommandProtocolGuid
,
2711 ( VOID
** )&SecurityCommand
,
2712 This
->DriverBindingHandle
,
2714 EFI_OPEN_PROTOCOL_BY_DRIVER
2717 if (Status
== EFI_ALREADY_STARTED
) {
2721 if (EFI_ERROR(Status
)) {
2726 // Close protocol and reopen in Start call
2730 &gEfiStorageSecurityCommandProtocolGuid
,
2731 This
->DriverBindingHandle
,
2736 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2739 Status
= gBS
->OpenProtocol(
2741 &gEfiBlockIoProtocolGuid
,
2743 This
->DriverBindingHandle
,
2745 EFI_OPEN_PROTOCOL_BY_DRIVER
2748 if (EFI_ERROR(Status
)) {
2749 DEBUG((DEBUG_INFO
, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
2754 // Close protocol and reopen in Start call
2758 &gEfiBlockIoProtocolGuid
,
2759 This
->DriverBindingHandle
,
2767 Enables Opal Management on a supported device if available.
2769 The start function is designed to be called after the Opal UEFI Driver has confirmed the
2770 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
2771 This function will complete the other necessary checks, such as verifying the device supports
2772 the correct version of Opal. Upon verification, it will add the device to the
2773 Opal HII list in order to expose Opal managmeent options.
2775 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2776 @param[in] ControllerHandle The Handle of the controller to start. This Handle
2777 must support a protocol interface that supplies
2778 an I/O abstraction to the driver.
2779 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
2780 parameter is ignored by device drivers, and is optional for bus
2781 drivers. For a bus driver, if this parameter is NULL, then handles
2782 for all the children of Controller are created by this driver.
2783 If this parameter is not NULL and the first Device Path Node is
2784 not the End of Device Path Node, then only the Handle for the
2785 child device specified by the first Device Path Node of
2786 RemainingDevicePath is created by this driver.
2787 If the first Device Path Node of RemainingDevicePath is
2788 the End of Device Path Node, no child Handle is created by this
2791 @retval EFI_SUCCESS Opal management was enabled.
2792 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
2793 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
2794 @retval Others The driver failed to start the device.
2799 OpalEfiDriverBindingStart(
2800 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2801 IN EFI_HANDLE Controller
,
2802 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2806 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
2807 OPAL_DRIVER_DEVICE
*Dev
;
2808 OPAL_DRIVER_DEVICE
*Itr
;
2811 Itr
= mOpalDriver
.DeviceList
;
2812 while (Itr
!= NULL
) {
2813 if (Controller
== Itr
->Handle
) {
2820 // Create internal device for tracking. This allows all disks to be tracked
2823 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE
));
2825 return EFI_OUT_OF_RESOURCES
;
2827 Dev
->Handle
= Controller
;
2830 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
2832 Status
= gBS
->OpenProtocol(
2834 &gEfiStorageSecurityCommandProtocolGuid
,
2835 (VOID
**)&Dev
->Sscp
,
2836 This
->DriverBindingHandle
,
2838 EFI_OPEN_PROTOCOL_BY_DRIVER
2840 if (EFI_ERROR(Status
)) {
2846 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2849 Status
= gBS
->OpenProtocol(
2851 &gEfiBlockIoProtocolGuid
,
2853 This
->DriverBindingHandle
,
2855 EFI_OPEN_PROTOCOL_BY_DRIVER
2857 if (EFI_ERROR(Status
)) {
2859 // Close storage security that was opened
2863 &gEfiStorageSecurityCommandProtocolGuid
,
2864 This
->DriverBindingHandle
,
2875 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
2879 &gEfiBlockIoProtocolGuid
,
2880 This
->DriverBindingHandle
,
2885 // Acquire Ascii printable name of child, if not found, then ignore device
2887 Result
= OpalDriverGetDriverDeviceName (Dev
);
2892 Status
= OpalDiskInitialize (Dev
);
2893 if (EFI_ERROR (Status
)) {
2897 AddDeviceToTail(Dev
);
2900 // Check if device is locked and prompt for password.
2902 OpalDriverRequestPassword (Dev
, L
"Unlock:");
2905 // Process OPAL request from last boot.
2907 ProcessOpalRequest (Dev
);
2913 // free device, close protocols and exit
2917 &gEfiStorageSecurityCommandProtocolGuid
,
2918 This
->DriverBindingHandle
,
2924 return EFI_DEVICE_ERROR
;
2928 Stop this driver on Controller.
2930 @param This Protocol instance pointer.
2931 @param Controller Handle of device to stop driver on
2932 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
2933 children is zero stop the entire bus driver.
2934 @param ChildHandleBuffer List of Child Handles to Stop.
2936 @retval EFI_SUCCESS This driver is removed Controller.
2937 @retval other This driver could not be removed from this device.
2942 OpalEfiDriverBindingStop(
2943 EFI_DRIVER_BINDING_PROTOCOL
* This
,
2944 EFI_HANDLE Controller
,
2945 UINTN NumberOfChildren
,
2946 EFI_HANDLE
* ChildHandleBuffer
2949 OPAL_DRIVER_DEVICE
* Itr
;
2951 Itr
= mOpalDriver
.DeviceList
;
2954 // does Controller match any of the devices we are managing for Opal
2956 while (Itr
!= NULL
) {
2957 if (Itr
->Handle
== Controller
) {
2958 OpalDriverStopDevice (Itr
);
2965 return EFI_NOT_FOUND
;
2970 Unloads UEFI Driver. Very useful for debugging and testing.
2972 @param ImageHandle Image Handle this driver.
2974 @retval EFI_SUCCESS This function always complete successfully.
2975 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
2979 OpalEfiDriverUnload (
2980 IN EFI_HANDLE ImageHandle
2984 OPAL_DRIVER_DEVICE
*Itr
;
2986 Status
= EFI_SUCCESS
;
2988 if (ImageHandle
!= gImageHandle
) {
2989 return (EFI_INVALID_PARAMETER
);
2993 // Uninstall any interface added to each device by us
2995 while (mOpalDriver
.DeviceList
) {
2996 Itr
= mOpalDriver
.DeviceList
;
2998 // Remove OPAL_DRIVER_DEVICE from the list
2999 // it updates the controllerList pointer
3001 OpalDriverStopDevice(Itr
);
3005 // Uninstall the HII capability
3007 Status
= HiiUninstall();