2 Entrypoint of Opal UEFI Driver and contains all the logic to
3 register for new Opal device instances.
5 Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 // This UEFI driver consumes EFI_STORAGE_SECURITY_PROTOCOL instances and installs an
17 // HII GUI to manage Opal features if the device is Opal capable
18 // If the Opal device is being managed by the UEFI Driver, it shall provide a popup
19 // window during boot requesting a user password
21 #include "OpalDriver.h"
24 EFI_GUID mOpalDeviceAtaGuid
= OPAL_DEVICE_ATA_GUID
;
25 EFI_GUID mOpalDeviceNvmeGuid
= OPAL_DEVICE_NVME_GUID
;
27 BOOLEAN mOpalEndOfDxe
= FALSE
;
28 OPAL_REQUEST_VARIABLE
*mOpalRequestVariable
= NULL
;
29 UINTN mOpalRequestVariableSize
= 0;
30 CHAR16 mPopUpString
[100];
34 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
35 } OPAL_HC_PCI_REGISTER_SAVE
;
38 // To unlock the Intel SATA controller at S3 Resume, restored the following registers.
40 const OPAL_HC_PCI_REGISTER_SAVE mSataHcRegisterSaveTemplate
[] = {
41 {0x9, S3BootScriptWidthUint8
},
42 {0x10, S3BootScriptWidthUint32
},
43 {0x14, S3BootScriptWidthUint32
},
44 {0x18, S3BootScriptWidthUint32
},
45 {0x1C, S3BootScriptWidthUint32
},
46 {0x20, S3BootScriptWidthUint32
},
47 {0x24, S3BootScriptWidthUint32
},
48 {0x3c, S3BootScriptWidthUint8
},
49 {0x3d, S3BootScriptWidthUint8
},
50 {0x40, S3BootScriptWidthUint16
},
51 {0x42, S3BootScriptWidthUint16
},
52 {0x92, S3BootScriptWidthUint16
},
53 {0x94, S3BootScriptWidthUint32
},
54 {0x9C, S3BootScriptWidthUint32
},
55 {0x4, S3BootScriptWidthUint16
},
58 OPAL_DRIVER mOpalDriver
;
63 EFI_DRIVER_BINDING_PROTOCOL gOpalDriverBinding
= {
64 OpalEfiDriverBindingSupported
,
65 OpalEfiDriverBindingStart
,
66 OpalEfiDriverBindingStop
,
74 The function determines the available actions for the OPAL_DISK provided.
76 @param[in] SupportedAttributes The supported attributes for the device.
77 @param[in] LockingFeature The locking status for the device.
78 @param[in] OwnerShip The ownership for the device.
79 @param[out] AvalDiskActions Pointer to fill-out with appropriate disk actions.
84 OpalSupportGetAvailableActions(
85 IN OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
,
86 IN TCG_LOCKING_FEATURE_DESCRIPTOR
*LockingFeature
,
88 OUT OPAL_DISK_ACTIONS
*AvalDiskActions
91 BOOLEAN ExistingPassword
;
93 NULL_CHECK(AvalDiskActions
);
95 AvalDiskActions
->AdminPass
= 1;
96 AvalDiskActions
->UserPass
= 0;
97 AvalDiskActions
->DisableUser
= 0;
98 AvalDiskActions
->Unlock
= 0;
101 // Revert is performed on locking sp, so only allow if locking sp is enabled
103 if (LockingFeature
->LockingEnabled
) {
104 AvalDiskActions
->Revert
= 1;
108 // Psid revert is available for any device with media encryption support or pyrite 2.0 type support.
110 if (SupportedAttributes
->PyriteSscV2
|| SupportedAttributes
->MediaEncryption
) {
113 // Only allow psid revert if media encryption is enabled or pyrite 2.0 type support..
114 // Otherwise, someone who steals a disk can psid revert the disk and the user Data is still
115 // intact and accessible
117 AvalDiskActions
->PsidRevert
= 1;
118 AvalDiskActions
->RevertKeepDataForced
= 0;
121 // Secure erase is performed by generating a new encryption key
122 // this is only available if encryption is supported
124 AvalDiskActions
->SecureErase
= 1;
126 AvalDiskActions
->PsidRevert
= 0;
127 AvalDiskActions
->SecureErase
= 0;
130 // If no media encryption is supported, then a revert (using password) will not
131 // erase the Data (since you can't generate a new encryption key)
133 AvalDiskActions
->RevertKeepDataForced
= 1;
136 if (LockingFeature
->Locked
) {
137 AvalDiskActions
->Unlock
= 1;
139 AvalDiskActions
->Unlock
= 0;
143 // Only allow user to set password if an admin password exists
145 ExistingPassword
= OpalUtilAdminPasswordExists(OwnerShip
, LockingFeature
);
146 AvalDiskActions
->UserPass
= ExistingPassword
;
149 // This will still show up even if there isn't a user, which is fine
151 AvalDiskActions
->DisableUser
= ExistingPassword
;
153 return TcgResultSuccess
;
157 Enable Opal Feature for the input device.
159 @param[in] Session The opal session for the opal device.
161 @param[in] MsidLength Msid Length
162 @param[in] Password Admin password
163 @param[in] PassLength Length of password in bytes
168 OpalSupportEnableOpalFeature (
169 IN OPAL_SESSION
*Session
,
171 IN UINT32 MsidLength
,
180 NULL_CHECK(Password
);
182 Ret
= OpalUtilSetAdminPasswordAsSid(
189 if (Ret
== TcgResultSuccess
) {
191 // Enable global locking range
193 Ret
= OpalUtilSetOpalLockingRange(
197 OPAL_LOCKING_SP_LOCKING_GLOBALRANGE
,
211 Update password for the Opal disk.
213 @param[in, out] OpalDisk The disk to update password.
214 @param[in] Password The input password.
215 @param[in] PasswordLength The input password length.
219 OpalSupportUpdatePassword (
220 IN OUT OPAL_DISK
*OpalDisk
,
222 IN UINT32 PasswordLength
225 CopyMem (OpalDisk
->Password
, Password
, PasswordLength
);
226 OpalDisk
->PasswordLength
= (UINT8
) PasswordLength
;
230 Extract device info from the device path.
232 @param[in] DevicePath Device path info for the device.
233 @param[out] DevInfoLength Device information length needed.
234 @param[out] DevInfo Device information extracted.
240 ExtractDeviceInfoFromDevicePath (
241 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
242 OUT UINT16
*DevInfoLength
,
243 OUT OPAL_DEVICE_COMMON
*DevInfo OPTIONAL
246 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath
;
247 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath2
;
248 PCI_DEVICE_PATH
*PciDevPath
;
251 OPAL_PCI_DEVICE
*PciDevice
;
252 OPAL_DEVICE_ATA
*DevInfoAta
;
253 OPAL_DEVICE_NVME
*DevInfoNvme
;
254 SATA_DEVICE_PATH
*SataDevPath
;
255 NVME_NAMESPACE_DEVICE_PATH
*NvmeDevPath
;
257 ASSERT (DevicePath
!= NULL
);
258 ASSERT (DevInfoLength
!= NULL
);
260 DeviceType
= OPAL_DEVICE_TYPE_UNKNOWN
;
263 TmpDevPath
= DevicePath
;
268 while (!IsDevicePathEnd (TmpDevPath
)) {
269 if (TmpDevPath
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath
->SubType
== MSG_SATA_DP
) {
273 if (DevInfo
!= NULL
) {
274 SataDevPath
= (SATA_DEVICE_PATH
*) TmpDevPath
;
275 DevInfoAta
= (OPAL_DEVICE_ATA
*) DevInfo
;
276 DevInfoAta
->Port
= SataDevPath
->HBAPortNumber
;
277 DevInfoAta
->PortMultiplierPort
= SataDevPath
->PortMultiplierPortNumber
;
279 DeviceType
= OPAL_DEVICE_TYPE_ATA
;
280 *DevInfoLength
= sizeof (OPAL_DEVICE_ATA
);
282 } else if (TmpDevPath
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath
->SubType
== MSG_NVME_NAMESPACE_DP
) {
286 if (DevInfo
!= NULL
) {
287 NvmeDevPath
= (NVME_NAMESPACE_DEVICE_PATH
*) TmpDevPath
;
288 DevInfoNvme
= (OPAL_DEVICE_NVME
*) DevInfo
;
289 DevInfoNvme
->NvmeNamespaceId
= NvmeDevPath
->NamespaceId
;
291 DeviceType
= OPAL_DEVICE_TYPE_NVME
;
292 *DevInfoLength
= sizeof (OPAL_DEVICE_NVME
);
295 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
302 TmpDevPath
= DevicePath
;
303 TmpDevPath2
= NextDevicePathNode (DevicePath
);
304 while (!IsDevicePathEnd (TmpDevPath2
)) {
305 if (TmpDevPath
->Type
== HARDWARE_DEVICE_PATH
&& TmpDevPath
->SubType
== HW_PCI_DP
) {
306 PciDevPath
= (PCI_DEVICE_PATH
*) TmpDevPath
;
307 if ((TmpDevPath2
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath2
->SubType
== MSG_NVME_NAMESPACE_DP
)||
308 (TmpDevPath2
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath2
->SubType
== MSG_SATA_DP
)) {
309 if (DevInfo
!= NULL
) {
310 PciDevice
= &DevInfo
->Device
;
311 PciDevice
->Segment
= 0;
312 PciDevice
->Bus
= BusNum
;
313 PciDevice
->Device
= PciDevPath
->Device
;
314 PciDevice
->Function
= PciDevPath
->Function
;
317 if (DevInfo
!= NULL
) {
318 PciDevice
= (OPAL_PCI_DEVICE
*) ((UINTN
) DevInfo
+ *DevInfoLength
);
319 PciDevice
->Segment
= 0;
320 PciDevice
->Bus
= BusNum
;
321 PciDevice
->Device
= PciDevPath
->Device
;
322 PciDevice
->Function
= PciDevPath
->Function
;
324 *DevInfoLength
+= sizeof (OPAL_PCI_DEVICE
);
325 if (TmpDevPath2
->Type
== HARDWARE_DEVICE_PATH
&& TmpDevPath2
->SubType
== HW_PCI_DP
) {
326 BusNum
= PciRead8 (PCI_LIB_ADDRESS (BusNum
, PciDevPath
->Device
, PciDevPath
->Function
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
331 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
332 TmpDevPath2
= NextDevicePathNode (TmpDevPath2
);
335 ASSERT (DeviceType
!= OPAL_DEVICE_TYPE_UNKNOWN
);
340 Save boot script for ATA OPAL device.
342 @param[in] DevInfo Pointer to ATA Opal device information.
346 OpalDeviceAtaSaveBootScript (
347 IN OPAL_DEVICE_ATA
*DevInfo
357 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
359 OPAL_HC_PCI_REGISTER_SAVE
*HcRegisterSaveListPtr
;
364 Bus
= DevInfo
->Device
.Bus
;
365 Device
= DevInfo
->Device
.Device
;
366 Function
= DevInfo
->Device
.Function
;
368 HcRegisterSaveListPtr
= (OPAL_HC_PCI_REGISTER_SAVE
*) mSataHcRegisterSaveTemplate
;
369 Count
= sizeof (mSataHcRegisterSaveTemplate
) / sizeof (OPAL_HC_PCI_REGISTER_SAVE
);
371 for (Index
= 0; Index
< Count
; Index
++) {
372 Offset
= HcRegisterSaveListPtr
[Index
].Address
;
373 Width
= HcRegisterSaveListPtr
[Index
].Width
;
376 case S3BootScriptWidthUint8
:
377 Data
= (UINT32
)PciRead8 (PCI_LIB_ADDRESS(Bus
,Device
,Function
,Offset
));
379 case S3BootScriptWidthUint16
:
380 Data
= (UINT32
)PciRead16 (PCI_LIB_ADDRESS(Bus
,Device
,Function
,Offset
));
382 case S3BootScriptWidthUint32
:
383 Data
= PciRead32 (PCI_LIB_ADDRESS(Bus
,Device
,Function
,Offset
));
390 Address
= S3_BOOT_SCRIPT_LIB_PCI_ADDRESS (Bus
, Device
, Function
, Offset
);
391 Status
= S3BootScriptSavePciCfgWrite (Width
, Address
, 1, &Data
);
392 ASSERT_EFI_ERROR (Status
);
397 Build ATA OPAL device info and save them to LockBox.
399 @param[in] BarAddr Bar address allocated.
403 BuildOpalDeviceInfoAta (
409 OPAL_DEVICE_ATA
*DevInfoAta
;
410 OPAL_DEVICE_ATA
*TempDevInfoAta
;
411 UINTN DevInfoLengthAta
;
412 UINT16 DevInfoLength
;
413 OPAL_DRIVER_DEVICE
*TmpDev
;
416 // Build ATA OPAL device info and save them to LockBox.
418 DevInfoLengthAta
= 0;
419 TmpDev
= mOpalDriver
.DeviceList
;
420 while (TmpDev
!= NULL
) {
421 DeviceType
= ExtractDeviceInfoFromDevicePath (
422 TmpDev
->OpalDisk
.OpalDevicePath
,
426 if (DeviceType
== OPAL_DEVICE_TYPE_ATA
) {
427 DevInfoLengthAta
+= DevInfoLength
;
430 TmpDev
= TmpDev
->Next
;
433 if (DevInfoLengthAta
== 0) {
437 DevInfoAta
= AllocateZeroPool (DevInfoLengthAta
);
438 ASSERT (DevInfoAta
!= NULL
);
440 TempDevInfoAta
= DevInfoAta
;
441 TmpDev
= mOpalDriver
.DeviceList
;
442 while (TmpDev
!= NULL
) {
443 DeviceType
= ExtractDeviceInfoFromDevicePath (
444 TmpDev
->OpalDisk
.OpalDevicePath
,
448 if (DeviceType
== OPAL_DEVICE_TYPE_ATA
) {
449 ExtractDeviceInfoFromDevicePath (
450 TmpDev
->OpalDisk
.OpalDevicePath
,
452 (OPAL_DEVICE_COMMON
*) TempDevInfoAta
454 TempDevInfoAta
->Length
= DevInfoLength
;
455 TempDevInfoAta
->OpalBaseComId
= TmpDev
->OpalDisk
.OpalBaseComId
;
456 TempDevInfoAta
->BarAddr
= BarAddr
;
458 TempDevInfoAta
->Password
,
459 TmpDev
->OpalDisk
.Password
,
460 TmpDev
->OpalDisk
.PasswordLength
462 TempDevInfoAta
->PasswordLength
= TmpDev
->OpalDisk
.PasswordLength
;
463 OpalDeviceAtaSaveBootScript (TempDevInfoAta
);
464 TempDevInfoAta
= (OPAL_DEVICE_ATA
*) ((UINTN
) TempDevInfoAta
+ DevInfoLength
);
467 TmpDev
= TmpDev
->Next
;
470 Status
= SaveLockBox (
475 ASSERT_EFI_ERROR (Status
);
477 Status
= SetLockBoxAttributes (
479 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
481 ASSERT_EFI_ERROR (Status
);
483 ZeroMem (DevInfoAta
, DevInfoLengthAta
);
484 FreePool (DevInfoAta
);
488 Build NVMe OPAL device info and save them to LockBox.
490 @param[in] BarAddr Bar address allocated.
494 BuildOpalDeviceInfoNvme (
500 OPAL_DEVICE_NVME
*DevInfoNvme
;
501 OPAL_DEVICE_NVME
*TempDevInfoNvme
;
502 UINTN DevInfoLengthNvme
;
503 UINT16 DevInfoLength
;
504 OPAL_DRIVER_DEVICE
*TmpDev
;
507 // Build NVMe OPAL device info and save them to LockBox.
509 DevInfoLengthNvme
= 0;
510 TmpDev
= mOpalDriver
.DeviceList
;
511 while (TmpDev
!= NULL
) {
512 DeviceType
= ExtractDeviceInfoFromDevicePath (
513 TmpDev
->OpalDisk
.OpalDevicePath
,
517 if (DeviceType
== OPAL_DEVICE_TYPE_NVME
) {
518 DevInfoLengthNvme
+= DevInfoLength
;
521 TmpDev
= TmpDev
->Next
;
524 if (DevInfoLengthNvme
== 0) {
528 DevInfoNvme
= AllocateZeroPool (DevInfoLengthNvme
);
529 ASSERT (DevInfoNvme
!= NULL
);
531 TempDevInfoNvme
= DevInfoNvme
;
532 TmpDev
= mOpalDriver
.DeviceList
;
533 while (TmpDev
!= NULL
) {
534 DeviceType
= ExtractDeviceInfoFromDevicePath (
535 TmpDev
->OpalDisk
.OpalDevicePath
,
539 if (DeviceType
== OPAL_DEVICE_TYPE_NVME
) {
540 ExtractDeviceInfoFromDevicePath (
541 TmpDev
->OpalDisk
.OpalDevicePath
,
543 (OPAL_DEVICE_COMMON
*) TempDevInfoNvme
545 TempDevInfoNvme
->Length
= DevInfoLength
;
546 TempDevInfoNvme
->OpalBaseComId
= TmpDev
->OpalDisk
.OpalBaseComId
;
547 TempDevInfoNvme
->BarAddr
= BarAddr
;
549 TempDevInfoNvme
->Password
,
550 TmpDev
->OpalDisk
.Password
,
551 TmpDev
->OpalDisk
.PasswordLength
553 TempDevInfoNvme
->PasswordLength
= TmpDev
->OpalDisk
.PasswordLength
;
554 TempDevInfoNvme
= (OPAL_DEVICE_NVME
*) ((UINTN
) TempDevInfoNvme
+ DevInfoLength
);
557 TmpDev
= TmpDev
->Next
;
560 Status
= SaveLockBox (
561 &mOpalDeviceNvmeGuid
,
565 ASSERT_EFI_ERROR (Status
);
567 Status
= SetLockBoxAttributes (
568 &mOpalDeviceNvmeGuid
,
569 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
571 ASSERT_EFI_ERROR (Status
);
573 ZeroMem (DevInfoNvme
, DevInfoLengthNvme
);
574 FreePool (DevInfoNvme
);
578 Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
580 This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
582 @param Event Event whose notification function is being invoked.
583 @param Context Pointer to the notification function's context.
588 OpalEndOfDxeEventNotify (
594 EFI_PHYSICAL_ADDRESS Address
;
596 OPAL_DRIVER_DEVICE
*TmpDev
;
598 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
600 mOpalEndOfDxe
= TRUE
;
602 if (mOpalRequestVariable
!= NULL
) {
604 // Free the OPAL request variable buffer here
605 // as the OPAL requests should have been processed.
607 FreePool (mOpalRequestVariable
);
608 mOpalRequestVariable
= NULL
;
609 mOpalRequestVariableSize
= 0;
613 // If no any device, return directly.
615 if (mOpalDriver
.DeviceList
== NULL
) {
616 gBS
->CloseEvent (Event
);
621 // Assume 64K size and alignment are enough.
624 Address
= 0xFFFFFFFF;
625 Status
= gDS
->AllocateMemorySpace (
626 EfiGcdAllocateMaxAddressSearchBottomUp
,
627 EfiGcdMemoryTypeMemoryMappedIo
,
628 16, // 2^16: 64K Alignment
634 ASSERT_EFI_ERROR (Status
);
636 BuildOpalDeviceInfoAta ((UINT32
) Address
);
637 BuildOpalDeviceInfoNvme ((UINT32
) Address
);
642 TmpDev
= mOpalDriver
.DeviceList
;
643 while (TmpDev
!= NULL
) {
644 ZeroMem (TmpDev
->OpalDisk
.Password
, TmpDev
->OpalDisk
.PasswordLength
);
645 TmpDev
= TmpDev
->Next
;
648 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
650 gBS
->CloseEvent (Event
);
654 Get Psid input from the popup window.
656 @param[in] Dev The device which need Psid to process Psid Revert
658 @param[in] PopUpString Pop up string.
659 @param[in] PopUpString2 Pop up string in line 2.
661 @param[out] PressEsc Whether user escape function through Press ESC.
663 @retval Psid string if success. NULL if failed.
667 OpalDriverPopUpPsidInput (
668 IN OPAL_DRIVER_DEVICE
*Dev
,
669 IN CHAR16
*PopUpString
,
670 IN CHAR16
*PopUpString2
,
671 OUT BOOLEAN
*PressEsc
674 EFI_INPUT_KEY InputKey
;
676 CHAR16 Mask
[PSID_CHARACTER_LENGTH
+ 1];
677 CHAR16 Unicode
[PSID_CHARACTER_LENGTH
+ 1];
680 ZeroMem(Unicode
, sizeof(Unicode
));
681 ZeroMem(Mask
, sizeof(Mask
));
685 gST
->ConOut
->ClearScreen(gST
->ConOut
);
689 Mask
[InputLength
] = L
'_';
690 if (PopUpString2
== NULL
) {
692 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
695 L
"---------------------",
701 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
705 L
"---------------------",
714 if (InputKey
.ScanCode
== SCAN_NULL
) {
718 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
720 // Add the null terminator.
722 Unicode
[InputLength
] = 0;
723 Mask
[InputLength
] = 0;
725 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
726 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
727 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
732 // delete last key entered
734 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
735 if (InputLength
> 0) {
736 Unicode
[InputLength
] = 0;
737 Mask
[InputLength
] = 0;
742 // add Next key entry
744 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
745 Mask
[InputLength
] = InputKey
.UnicodeChar
;
747 if (InputLength
== PSID_CHARACTER_LENGTH
) {
749 // Add the null terminator.
751 Unicode
[InputLength
] = 0;
752 Mask
[InputLength
] = 0;
762 if (InputKey
.ScanCode
== SCAN_ESC
) {
768 gST
->ConOut
->ClearScreen(gST
->ConOut
);
770 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
771 ZeroMem (Unicode
, sizeof (Unicode
));
772 ZeroMem (Mask
, sizeof (Mask
));
776 Ascii
= AllocateZeroPool (PSID_CHARACTER_LENGTH
+ 1);
778 ZeroMem (Unicode
, sizeof (Unicode
));
779 ZeroMem (Mask
, sizeof (Mask
));
783 UnicodeStrToAsciiStrS (Unicode
, Ascii
, PSID_CHARACTER_LENGTH
+ 1);
784 ZeroMem (Unicode
, sizeof (Unicode
));
785 ZeroMem (Mask
, sizeof (Mask
));
792 Get password input from the popup window.
794 @param[in] Dev The device which need password to unlock or
795 process OPAL request.
796 @param[in] PopUpString1 Pop up string 1.
797 @param[in] PopUpString2 Pop up string 2.
798 @param[out] PressEsc Whether user escape function through Press ESC.
800 @retval Password string if success. NULL if failed.
804 OpalDriverPopUpPasswordInput (
805 IN OPAL_DRIVER_DEVICE
*Dev
,
806 IN CHAR16
*PopUpString1
,
807 IN CHAR16
*PopUpString2
,
808 OUT BOOLEAN
*PressEsc
811 EFI_INPUT_KEY InputKey
;
813 CHAR16 Mask
[OPAL_MAX_PASSWORD_SIZE
+ 1];
814 CHAR16 Unicode
[OPAL_MAX_PASSWORD_SIZE
+ 1];
817 ZeroMem(Unicode
, sizeof(Unicode
));
818 ZeroMem(Mask
, sizeof(Mask
));
822 gST
->ConOut
->ClearScreen(gST
->ConOut
);
826 Mask
[InputLength
] = L
'_';
827 if (PopUpString2
== NULL
) {
829 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
832 L
"---------------------",
838 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
842 L
"---------------------",
851 if (InputKey
.ScanCode
== SCAN_NULL
) {
855 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
857 // Add the null terminator.
859 Unicode
[InputLength
] = 0;
860 Mask
[InputLength
] = 0;
862 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
863 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
864 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
869 // delete last key entered
871 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
872 if (InputLength
> 0) {
873 Unicode
[InputLength
] = 0;
874 Mask
[InputLength
] = 0;
879 // add Next key entry
881 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
882 Mask
[InputLength
] = L
'*';
884 if (InputLength
== OPAL_MAX_PASSWORD_SIZE
) {
886 // Add the null terminator.
888 Unicode
[InputLength
] = 0;
889 Mask
[InputLength
] = 0;
899 if (InputKey
.ScanCode
== SCAN_ESC
) {
905 gST
->ConOut
->ClearScreen(gST
->ConOut
);
907 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
908 ZeroMem (Unicode
, sizeof (Unicode
));
912 Ascii
= AllocateZeroPool (OPAL_MAX_PASSWORD_SIZE
+ 1);
914 ZeroMem (Unicode
, sizeof (Unicode
));
918 UnicodeStrToAsciiStrS (Unicode
, Ascii
, OPAL_MAX_PASSWORD_SIZE
+ 1);
919 ZeroMem (Unicode
, sizeof (Unicode
));
927 @param[in] Dev The OPAL device.
928 @param[in] RequestString Request string.
930 @return Pop up string.
935 IN OPAL_DRIVER_DEVICE
*Dev
,
936 IN CHAR16
*RequestString
939 if (Dev
->Name16
== NULL
) {
940 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s Disk", RequestString
);
942 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s %s", RequestString
, Dev
->Name16
);
949 Check if disk is locked, show popup window and ask for password if it is.
951 @param[in] Dev The device which need to be unlocked.
952 @param[in] RequestString Request string.
956 OpalDriverRequestPassword (
957 IN OPAL_DRIVER_DEVICE
*Dev
,
958 IN CHAR16
*RequestString
966 OPAL_SESSION Session
;
976 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
978 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
982 IsEnabled
= OpalFeatureEnabled (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
984 ZeroMem(&Session
, sizeof(Session
));
985 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
986 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
987 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
989 IsLocked
= OpalDeviceLocked (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
991 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
992 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
996 // Current device in the lock status and
997 // User not input password and press ESC,
998 // keep device in lock status and continue boot.
1002 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1004 L
"Press ENTER to skip the request and continue boot,",
1005 L
"Press ESC to input password again",
1008 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1010 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1011 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1013 // Keep lock and continue boot.
1018 // Let user input password again.
1024 // Current device in the unlock status and
1025 // User not input password and press ESC,
1026 // Shutdown the device.
1030 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1032 L
"Press ENTER to shutdown, Press ESC to input password again",
1035 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1037 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1038 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1041 // Let user input password again.
1048 if (Password
== NULL
) {
1052 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1055 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
1057 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, TRUE
, TRUE
);
1058 if (Ret
== TcgResultSuccess
) {
1059 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
1063 if (Ret
== TcgResultSuccess
) {
1064 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1065 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1067 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1070 if (Password
!= NULL
) {
1071 ZeroMem (Password
, PasswordLen
);
1072 FreePool (Password
);
1075 if (Ret
== TcgResultSuccess
) {
1080 // Check whether opal device's Tries value has reach the TryLimit value, if yes, force a shutdown
1081 // before accept new password.
1083 if (Ret
== TcgResultFailureInvalidType
) {
1084 Count
= MAX_PASSWORD_TRY_COUNT
;
1092 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1094 L
"Invalid password.",
1095 L
"Press ENTER to retry",
1098 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1101 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1104 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1106 L
"Opal password retry count exceeds the limit. Must shutdown!",
1107 L
"Press ENTER to shutdown",
1110 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1112 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1118 Process Enable Feature OPAL request.
1120 @param[in] Dev The device which has Enable Feature OPAL request.
1121 @param[in] RequestString Request string.
1125 ProcessOpalRequestEnableFeature (
1126 IN OPAL_DRIVER_DEVICE
*Dev
,
1127 IN CHAR16
*RequestString
1133 CHAR8
*PasswordConfirm
;
1134 UINT32 PasswordLenConfirm
;
1135 OPAL_SESSION Session
;
1139 CHAR16
*PopUpString
;
1145 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1147 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1151 ZeroMem(&Session
, sizeof(Session
));
1152 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1153 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1154 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1156 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1157 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1161 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1163 L
"Press ENTER to skip the request and continue boot,",
1164 L
"Press ESC to input password again",
1167 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1169 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1170 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1174 // Let user input password again.
1180 if (Password
== NULL
) {
1184 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1186 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1187 if (PasswordConfirm
== NULL
) {
1188 ZeroMem (Password
, PasswordLen
);
1189 FreePool (Password
);
1193 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1194 if ((PasswordLen
!= PasswordLenConfirm
) ||
1195 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1196 ZeroMem (Password
, PasswordLen
);
1197 FreePool (Password
);
1198 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1199 FreePool (PasswordConfirm
);
1202 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1204 L
"Passwords are not the same.",
1205 L
"Press ENTER to retry",
1208 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1213 if (PasswordConfirm
!= NULL
) {
1214 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1215 FreePool (PasswordConfirm
);
1218 Ret
= OpalSupportEnableOpalFeature (&Session
, Dev
->OpalDisk
.Msid
, Dev
->OpalDisk
.MsidLength
, Password
, PasswordLen
);
1219 if (Ret
== TcgResultSuccess
) {
1220 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1221 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1223 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1226 if (Password
!= NULL
) {
1227 ZeroMem (Password
, PasswordLen
);
1228 FreePool (Password
);
1231 if (Ret
== TcgResultSuccess
) {
1239 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1242 L
"Press ENTER to retry",
1245 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1248 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1251 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1253 L
"Opal password retry count exceeds the limit.",
1254 L
"Press ENTER to skip the request and continue boot",
1257 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1258 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1263 Process Disable User OPAL request.
1265 @param[in] Dev The device which has Disable User OPAL request.
1266 @param[in] RequestString Request string.
1270 ProcessOpalRequestDisableUser (
1271 IN OPAL_DRIVER_DEVICE
*Dev
,
1272 IN CHAR16
*RequestString
1278 OPAL_SESSION Session
;
1282 BOOLEAN PasswordFailed
;
1283 CHAR16
*PopUpString
;
1289 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1291 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1295 ZeroMem(&Session
, sizeof(Session
));
1296 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1297 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1298 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1300 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1301 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1305 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1307 L
"Press ENTER to skip the request and continue boot,",
1308 L
"Press ESC to input password again",
1311 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1313 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1314 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1318 // Let user input password again.
1324 if (Password
== NULL
) {
1328 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1330 Ret
= OpalUtilDisableUser(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1331 if (Ret
== TcgResultSuccess
) {
1332 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1333 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1335 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1338 if (Password
!= NULL
) {
1339 ZeroMem (Password
, PasswordLen
);
1340 FreePool (Password
);
1343 if (Ret
== TcgResultSuccess
) {
1351 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1353 L
"Invalid password, request failed.",
1354 L
"Press ENTER to retry",
1357 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1360 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1363 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1365 L
"Opal password retry count exceeds the limit.",
1366 L
"Press ENTER to skip the request and continue boot",
1369 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1370 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1375 Process Psid Revert OPAL request.
1377 @param[in] Dev The device which has Psid Revert OPAL request.
1378 @param[in] RequestString Request string.
1382 ProcessOpalRequestPsidRevert (
1383 IN OPAL_DRIVER_DEVICE
*Dev
,
1384 IN CHAR16
*RequestString
1390 OPAL_SESSION Session
;
1394 CHAR16
*PopUpString
;
1395 CHAR16
*PopUpString2
;
1402 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1404 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1406 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1407 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds, DO NOT power off system during the revert action!");
1408 PopUpString2
= AllocateZeroPool (BufferSize
);
1409 ASSERT (PopUpString2
!= NULL
);
1413 L
"WARNING: Revert action will take about %d seconds, DO NOT power off system during the revert action!",
1414 Dev
->OpalDisk
.EstimateTimeCost
1417 PopUpString2
= NULL
;
1422 ZeroMem(&Session
, sizeof(Session
));
1423 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1424 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1425 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1427 while (Count
< MAX_PSID_TRY_COUNT
) {
1428 Psid
= OpalDriverPopUpPsidInput (Dev
, PopUpString
, PopUpString2
, &PressEsc
);
1432 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1434 L
"Press ENTER to skip the request and continue boot,",
1435 L
"Press ESC to input Psid again",
1438 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1440 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1441 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1445 // Let user input Psid again.
1455 PsidLen
= (UINT32
) AsciiStrLen(Psid
);
1457 Ret
= OpalUtilPsidRevert(&Session
, Psid
, PsidLen
);
1458 if (Ret
== TcgResultSuccess
) {
1459 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1461 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1465 ZeroMem (Psid
, PsidLen
);
1469 if (Ret
== TcgResultSuccess
) {
1477 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1479 L
"Invalid Psid, request failed.",
1480 L
"Press ENTER to retry",
1483 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1486 if (Count
>= MAX_PSID_TRY_COUNT
) {
1489 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1491 L
"Opal Psid retry count exceeds the limit.",
1492 L
"Press ENTER to skip the request and continue boot",
1495 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1496 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1500 if (PopUpString2
!= NULL
) {
1501 FreePool (PopUpString2
);
1506 Process Admin Revert OPAL request.
1508 @param[in] Dev The device which has Revert OPAL request.
1509 @param[in] KeepUserData Whether to keep user data or not.
1510 @param[in] RequestString Request string.
1514 ProcessOpalRequestRevert (
1515 IN OPAL_DRIVER_DEVICE
*Dev
,
1516 IN BOOLEAN KeepUserData
,
1517 IN CHAR16
*RequestString
1523 OPAL_SESSION Session
;
1527 BOOLEAN PasswordFailed
;
1528 CHAR16
*PopUpString
;
1529 CHAR16
*PopUpString2
;
1536 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1538 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1540 if ((!KeepUserData
) &&
1541 (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
)) {
1542 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds, DO NOT power off system during the revert action!");
1543 PopUpString2
= AllocateZeroPool (BufferSize
);
1544 ASSERT (PopUpString2
!= NULL
);
1548 L
"WARNING: Revert action will take about %d seconds, DO NOT power off system during the revert action!",
1549 Dev
->OpalDisk
.EstimateTimeCost
1552 PopUpString2
= NULL
;
1557 ZeroMem(&Session
, sizeof(Session
));
1558 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1559 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1560 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1562 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1563 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, PopUpString2
, &PressEsc
);
1567 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1569 L
"Press ENTER to skip the request and continue boot,",
1570 L
"Press ESC to input password again",
1573 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1575 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1576 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1580 // Let user input password again.
1586 if (Password
== NULL
) {
1590 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1592 if ((Dev
->OpalDisk
.SupportedAttributes
.PyriteSsc
== 1) &&
1593 (Dev
->OpalDisk
.LockingFeature
.MediaEncryption
== 0)) {
1595 // For pyrite type device which does not support media encryption,
1596 // it does not accept "Keep User Data" parameter.
1597 // So here hardcode a FALSE for this case.
1599 Ret
= OpalUtilRevert(
1606 Dev
->OpalDisk
.MsidLength
1609 Ret
= OpalUtilRevert(
1616 Dev
->OpalDisk
.MsidLength
1619 if (Ret
== TcgResultSuccess
) {
1620 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1621 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1623 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1626 if (Password
!= NULL
) {
1627 ZeroMem (Password
, PasswordLen
);
1628 FreePool (Password
);
1631 if (Ret
== TcgResultSuccess
) {
1639 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1641 L
"Invalid password, request failed.",
1642 L
"Press ENTER to retry",
1645 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1648 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1651 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1653 L
"Opal password retry count exceeds the limit.",
1654 L
"Press ENTER to skip the request and continue boot",
1657 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1658 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1662 if (PopUpString2
!= NULL
) {
1663 FreePool (PopUpString2
);
1668 Process Secure Erase OPAL request.
1670 @param[in] Dev The device which has Secure Erase OPAL request.
1671 @param[in] RequestString Request string.
1675 ProcessOpalRequestSecureErase (
1676 IN OPAL_DRIVER_DEVICE
*Dev
,
1677 IN CHAR16
*RequestString
1683 OPAL_SESSION Session
;
1687 BOOLEAN PasswordFailed
;
1688 CHAR16
*PopUpString
;
1694 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1696 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1700 ZeroMem(&Session
, sizeof(Session
));
1701 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1702 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1703 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1705 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1706 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1710 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1712 L
"Press ENTER to skip the request and continue boot,",
1713 L
"Press ESC to input password again",
1716 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1718 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1719 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1723 // Let user input password again.
1729 if (Password
== NULL
) {
1733 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1735 Ret
= OpalUtilSecureErase(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1736 if (Ret
== TcgResultSuccess
) {
1737 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1738 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1740 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1743 if (Password
!= NULL
) {
1744 ZeroMem (Password
, PasswordLen
);
1745 FreePool (Password
);
1748 if (Ret
== TcgResultSuccess
) {
1756 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1758 L
"Invalid password, request failed.",
1759 L
"Press ENTER to retry",
1762 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1765 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1768 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1770 L
"Opal password retry count exceeds the limit.",
1771 L
"Press ENTER to skip the request and continue boot",
1774 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1775 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1780 Process Set Admin Pwd OPAL request.
1782 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1783 @param[in] RequestString Request string.
1787 ProcessOpalRequestSetUserPwd (
1788 IN OPAL_DRIVER_DEVICE
*Dev
,
1789 IN CHAR16
*RequestString
1794 UINT32 OldPasswordLen
;
1797 CHAR8
*PasswordConfirm
;
1798 UINT32 PasswordLenConfirm
;
1799 OPAL_SESSION Session
;
1803 CHAR16
*PopUpString
;
1809 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1811 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1815 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1816 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
1820 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1822 L
"Press ENTER to skip the request and continue boot,",
1823 L
"Press ESC to input password again",
1826 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1828 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1829 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1833 // Let user input password again.
1839 if (OldPassword
== NULL
) {
1843 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1845 ZeroMem(&Session
, sizeof(Session
));
1846 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1847 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1848 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1849 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_USER1_AUTHORITY
);
1850 if (Ret
== TcgResultSuccess
) {
1851 DEBUG ((DEBUG_INFO
, "Verify with USER1 authority : Success\n"));
1853 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1854 if (Ret
== TcgResultSuccess
) {
1855 DEBUG ((DEBUG_INFO
, "Verify with ADMIN1 authority: Success\n"));
1857 ZeroMem (OldPassword
, OldPasswordLen
);
1858 FreePool (OldPassword
);
1859 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1862 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1864 L
"Incorrect password.",
1865 L
"Press ENTER to retry",
1868 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1874 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1875 if (Password
== NULL
) {
1876 ZeroMem (OldPassword
, OldPasswordLen
);
1877 FreePool (OldPassword
);
1881 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1883 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1884 if (PasswordConfirm
== NULL
) {
1885 ZeroMem (OldPassword
, OldPasswordLen
);
1886 FreePool (OldPassword
);
1887 ZeroMem (Password
, PasswordLen
);
1888 FreePool (Password
);
1892 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1893 if ((PasswordLen
!= PasswordLenConfirm
) ||
1894 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1895 ZeroMem (OldPassword
, OldPasswordLen
);
1896 FreePool (OldPassword
);
1897 ZeroMem (Password
, PasswordLen
);
1898 FreePool (Password
);
1899 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1900 FreePool (PasswordConfirm
);
1903 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1905 L
"Passwords are not the same.",
1906 L
"Press ENTER to retry",
1909 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1914 if (PasswordConfirm
!= NULL
) {
1915 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1916 FreePool (PasswordConfirm
);
1919 ZeroMem(&Session
, sizeof(Session
));
1920 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1921 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1922 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1923 Ret
= OpalUtilSetUserPassword(
1930 if (Ret
== TcgResultSuccess
) {
1931 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1932 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1934 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1937 if (OldPassword
!= NULL
) {
1938 ZeroMem (OldPassword
, OldPasswordLen
);
1939 FreePool (OldPassword
);
1942 if (Password
!= NULL
) {
1943 ZeroMem (Password
, PasswordLen
);
1944 FreePool (Password
);
1947 if (Ret
== TcgResultSuccess
) {
1955 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1958 L
"Press ENTER to retry",
1961 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1964 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1967 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1969 L
"Opal password retry count exceeds the limit.",
1970 L
"Press ENTER to skip the request and continue boot",
1973 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1974 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1979 Process Set Admin Pwd OPAL request.
1981 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1982 @param[in] RequestString Request string.
1986 ProcessOpalRequestSetAdminPwd (
1987 IN OPAL_DRIVER_DEVICE
*Dev
,
1988 IN CHAR16
*RequestString
1993 UINT32 OldPasswordLen
;
1996 CHAR8
*PasswordConfirm
;
1997 UINT32 PasswordLenConfirm
;
1998 OPAL_SESSION Session
;
2002 CHAR16
*PopUpString
;
2008 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
2010 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
2014 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
2015 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
2019 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2021 L
"Press ENTER to skip the request and continue boot,",
2022 L
"Press ESC to input password again",
2025 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
2027 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
2028 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2032 // Let user input password again.
2038 if (OldPassword
== NULL
) {
2042 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
2044 ZeroMem(&Session
, sizeof(Session
));
2045 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2046 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2047 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2048 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
2049 if (Ret
== TcgResultSuccess
) {
2050 DEBUG ((DEBUG_INFO
, "Verify: Success\n"));
2052 ZeroMem (OldPassword
, OldPasswordLen
);
2053 FreePool (OldPassword
);
2054 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
2057 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2059 L
"Incorrect password.",
2060 L
"Press ENTER to retry",
2063 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2068 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
2069 if (Password
== NULL
) {
2070 ZeroMem (OldPassword
, OldPasswordLen
);
2071 FreePool (OldPassword
);
2075 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
2077 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
2078 if (PasswordConfirm
== NULL
) {
2079 ZeroMem (OldPassword
, OldPasswordLen
);
2080 FreePool (OldPassword
);
2081 ZeroMem (Password
, PasswordLen
);
2082 FreePool (Password
);
2086 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
2087 if ((PasswordLen
!= PasswordLenConfirm
) ||
2088 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
2089 ZeroMem (OldPassword
, OldPasswordLen
);
2090 FreePool (OldPassword
);
2091 ZeroMem (Password
, PasswordLen
);
2092 FreePool (Password
);
2093 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2094 FreePool (PasswordConfirm
);
2097 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2099 L
"Passwords are not the same.",
2100 L
"Press ENTER to retry",
2103 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2108 if (PasswordConfirm
!= NULL
) {
2109 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2110 FreePool (PasswordConfirm
);
2114 ZeroMem(&Session
, sizeof(Session
));
2115 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2116 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2117 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2118 Ret
= OpalUtilSetAdminPassword(
2125 if (Ret
== TcgResultSuccess
) {
2126 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
2127 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
2129 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
2132 if (OldPassword
!= NULL
) {
2133 ZeroMem (OldPassword
, OldPasswordLen
);
2134 FreePool (OldPassword
);
2137 if (Password
!= NULL
) {
2138 ZeroMem (Password
, PasswordLen
);
2139 FreePool (Password
);
2142 if (Ret
== TcgResultSuccess
) {
2150 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2153 L
"Press ENTER to retry",
2156 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2159 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
2162 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2164 L
"Opal password retry count exceeds the limit.",
2165 L
"Press ENTER to skip the request and continue boot",
2168 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2169 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2174 Process OPAL request.
2176 @param[in] Dev The device which has OPAL request.
2180 ProcessOpalRequest (
2181 IN OPAL_DRIVER_DEVICE
*Dev
2185 OPAL_REQUEST_VARIABLE
*TempVariable
;
2186 OPAL_REQUEST_VARIABLE
*Variable
;
2188 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInVariable
;
2189 UINTN DevicePathSizeInVariable
;
2190 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2191 UINTN DevicePathSize
;
2192 BOOLEAN KeepUserData
;
2194 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
2196 if (mOpalRequestVariable
== NULL
) {
2197 Status
= GetVariable2 (
2198 OPAL_REQUEST_VARIABLE_NAME
,
2199 &gHiiSetupVariableGuid
,
2200 (VOID
**) &Variable
,
2203 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
2206 mOpalRequestVariable
= Variable
;
2207 mOpalRequestVariableSize
= VariableSize
;
2210 // Delete the OPAL request variable.
2212 Status
= gRT
->SetVariable (
2213 OPAL_REQUEST_VARIABLE_NAME
,
2214 (EFI_GUID
*) &gHiiSetupVariableGuid
,
2219 ASSERT_EFI_ERROR (Status
);
2221 Variable
= mOpalRequestVariable
;
2222 VariableSize
= mOpalRequestVariableSize
;
2226 // Process the OPAL requests.
2228 TempVariable
= Variable
;
2229 while ((VariableSize
> sizeof (OPAL_REQUEST_VARIABLE
)) &&
2230 (VariableSize
>= TempVariable
->Length
) &&
2231 (TempVariable
->Length
> sizeof (OPAL_REQUEST_VARIABLE
))) {
2232 DevicePathInVariable
= (EFI_DEVICE_PATH_PROTOCOL
*) ((UINTN
) TempVariable
+ sizeof (OPAL_REQUEST_VARIABLE
));
2233 DevicePathSizeInVariable
= GetDevicePathSize (DevicePathInVariable
);
2234 DevicePath
= Dev
->OpalDisk
.OpalDevicePath
;
2235 DevicePathSize
= GetDevicePathSize (DevicePath
);
2236 if ((DevicePathSize
== DevicePathSizeInVariable
) &&
2237 (CompareMem (DevicePath
, DevicePathInVariable
, DevicePathSize
) == 0)) {
2239 // Found the node for the OPAL device.
2241 if (TempVariable
->OpalRequest
.SetAdminPwd
!= 0) {
2242 ProcessOpalRequestSetAdminPwd (Dev
, L
"Update Admin Pwd:");
2244 if (TempVariable
->OpalRequest
.SetUserPwd
!= 0) {
2245 ProcessOpalRequestSetUserPwd (Dev
, L
"Set User Pwd:");
2247 if (TempVariable
->OpalRequest
.SecureErase
!= 0) {
2248 ProcessOpalRequestSecureErase (Dev
, L
"Secure Erase:");
2250 if (TempVariable
->OpalRequest
.Revert
!= 0) {
2251 KeepUserData
= (BOOLEAN
) TempVariable
->OpalRequest
.KeepUserData
;
2252 ProcessOpalRequestRevert (
2255 KeepUserData
? L
"Admin Revert(keep):" : L
"Admin Revert:"
2258 if (TempVariable
->OpalRequest
.PsidRevert
!= 0) {
2259 ProcessOpalRequestPsidRevert (Dev
, L
"Psid Revert:");
2261 if (TempVariable
->OpalRequest
.DisableUser
!= 0) {
2262 ProcessOpalRequestDisableUser (Dev
, L
"Disable User:");
2264 if (TempVariable
->OpalRequest
.EnableFeature
!= 0) {
2265 ProcessOpalRequestEnableFeature (Dev
, L
"Enable Feature:");
2271 VariableSize
-= TempVariable
->Length
;
2272 TempVariable
= (OPAL_REQUEST_VARIABLE
*) ((UINTN
) TempVariable
+ TempVariable
->Length
);
2275 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
2279 Add new device to the global device list.
2281 @param Dev New create device.
2286 IN OPAL_DRIVER_DEVICE
*Dev
2289 OPAL_DRIVER_DEVICE
*TmpDev
;
2291 if (mOpalDriver
.DeviceList
== NULL
) {
2292 mOpalDriver
.DeviceList
= Dev
;
2294 TmpDev
= mOpalDriver
.DeviceList
;
2295 while (TmpDev
->Next
!= NULL
) {
2296 TmpDev
= TmpDev
->Next
;
2304 Remove one device in the global device list.
2306 @param Dev The device need to be removed.
2311 IN OPAL_DRIVER_DEVICE
*Dev
2314 OPAL_DRIVER_DEVICE
*TmpDev
;
2316 if (mOpalDriver
.DeviceList
== NULL
) {
2320 if (mOpalDriver
.DeviceList
== Dev
) {
2321 mOpalDriver
.DeviceList
= NULL
;
2325 TmpDev
= mOpalDriver
.DeviceList
;
2326 while (TmpDev
->Next
!= NULL
) {
2327 if (TmpDev
->Next
== Dev
) {
2328 TmpDev
->Next
= Dev
->Next
;
2335 Get current device count.
2337 @retval return the current created device count.
2346 OPAL_DRIVER_DEVICE
*TmpDev
;
2349 TmpDev
= mOpalDriver
.DeviceList
;
2351 while (TmpDev
!= NULL
) {
2353 TmpDev
= TmpDev
->Next
;
2360 Get devcie list info.
2362 @retval return the device list pointer.
2365 OpalDriverGetDeviceList(
2369 return mOpalDriver
.DeviceList
;
2373 ReadyToBoot callback to send BlockSid command.
2375 @param Event Pointer to this event
2376 @param Context Event handler private Data
2381 ReadyToBootCallback (
2386 OPAL_DRIVER_DEVICE
*Itr
;
2388 OPAL_SESSION Session
;
2389 UINT32 PpStorageFlag
;
2391 gBS
->CloseEvent (Event
);
2393 PpStorageFlag
= Tcg2PhysicalPresenceLibGetManagementFlags ();
2394 if ((PpStorageFlag
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID
) != 0) {
2396 // Send BlockSID command to each Opal disk
2398 Itr
= mOpalDriver
.DeviceList
;
2399 while (Itr
!= NULL
) {
2400 if (Itr
->OpalDisk
.SupportedAttributes
.BlockSid
) {
2401 ZeroMem(&Session
, sizeof(Session
));
2402 Session
.Sscp
= Itr
->OpalDisk
.Sscp
;
2403 Session
.MediaId
= Itr
->OpalDisk
.MediaId
;
2404 Session
.OpalBaseComId
= Itr
->OpalDisk
.OpalBaseComId
;
2406 DEBUG ((DEBUG_INFO
, "OpalPassword: ReadyToBoot point, send BlockSid command to device!\n"));
2407 Result
= OpalBlockSid (&Session
, TRUE
); // HardwareReset must always be TRUE
2408 if (Result
!= TcgResultSuccess
) {
2409 DEBUG ((DEBUG_ERROR
, "OpalBlockSid fail\n"));
2420 Stop this Controller.
2422 @param Dev The device need to be stopped.
2426 OpalDriverStopDevice (
2427 OPAL_DRIVER_DEVICE
*Dev
2433 FreePool(Dev
->Name16
);
2436 // remove OPAL_DRIVER_DEVICE from the list
2437 // it updates the controllerList pointer
2442 // close protocols that were opened
2446 &gEfiStorageSecurityCommandProtocolGuid
,
2447 gOpalDriverBinding
.DriverBindingHandle
,
2453 &gEfiBlockIoProtocolGuid
,
2454 gOpalDriverBinding
.DriverBindingHandle
,
2462 Get devcie name through the component name protocol.
2464 @param[in] AllHandlesBuffer The handle buffer for current system.
2465 @param[in] NumAllHandles The number of handles for the handle buffer.
2466 @param[in] Dev The device which need to get name.
2467 @param[in] UseComp1 Whether use component name or name2 protocol.
2469 @retval TRUE Find the name for this device.
2470 @retval FALSE Not found the name for this device.
2473 OpalDriverGetDeviceNameByProtocol(
2474 EFI_HANDLE
*AllHandlesBuffer
,
2475 UINTN NumAllHandles
,
2476 OPAL_DRIVER_DEVICE
*Dev
,
2480 EFI_HANDLE
* ProtocolHandlesBuffer
;
2481 UINTN NumProtocolHandles
;
2483 EFI_COMPONENT_NAME2_PROTOCOL
* Cnp1_2
; // efi component name and componentName2 have same layout
2486 EFI_DEVICE_PATH_PROTOCOL
* TmpDevPath
;
2489 EFI_HANDLE TmpHandle
;
2492 if (Dev
== NULL
|| AllHandlesBuffer
== NULL
|| NumAllHandles
== 0) {
2496 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
2499 // Find all EFI_HANDLES with protocol
2501 Status
= gBS
->LocateHandleBuffer(
2505 &NumProtocolHandles
,
2506 &ProtocolHandlesBuffer
2508 if (EFI_ERROR(Status
)) {
2514 // Exit early if no supported devices
2516 if (NumProtocolHandles
== 0) {
2521 // Get printable name by iterating through all protocols
2522 // using the handle as the child, and iterate through all handles for the controller
2523 // exit loop early once found, if not found, then delete device
2524 // storage security protocol instances already exist, add them to internal list
2526 Status
= EFI_DEVICE_ERROR
;
2527 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
2530 if (Dev
->Name16
!= NULL
) {
2534 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
2536 Status
= gBS
->OpenProtocol(
2542 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2544 if (EFI_ERROR(Status
) || Cnp1_2
== NULL
) {
2549 // Use all handles array as controller handle
2551 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
2552 Status
= Cnp1_2
->GetControllerName(
2554 AllHandlesBuffer
[Index2
],
2556 LANGUAGE_ISO_639_2_ENGLISH
,
2559 if (EFI_ERROR(Status
)) {
2560 Status
= Cnp1_2
->GetControllerName(
2562 AllHandlesBuffer
[Index2
],
2564 LANGUAGE_RFC_3066_ENGLISH
,
2568 if (!EFI_ERROR(Status
) && DevName
!= NULL
) {
2569 StrLength
= StrLen(DevName
) + 1; // Add one for NULL terminator
2570 Dev
->Name16
= AllocateZeroPool(StrLength
* sizeof (CHAR16
));
2571 ASSERT (Dev
->Name16
!= NULL
);
2572 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
2573 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool(StrLength
);
2574 UnicodeStrToAsciiStrS (DevName
, Dev
->NameZ
, StrLength
);
2577 // Retrieve bridge BDF info and port number or namespace depending on type
2580 Status
= gBS
->OpenProtocol(
2582 &gEfiDevicePathProtocolGuid
,
2583 (VOID
**)&TmpDevPath
,
2586 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2588 if (!EFI_ERROR(Status
)) {
2589 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
2593 if (Dev
->Name16
!= NULL
) {
2594 FreePool(Dev
->Name16
);
2597 if (Dev
->NameZ
!= NULL
) {
2598 FreePool(Dev
->NameZ
);
2609 Get devcie name through the component name protocol.
2611 @param[in] Dev The device which need to get name.
2613 @retval TRUE Find the name for this device.
2614 @retval FALSE Not found the name for this device.
2617 OpalDriverGetDriverDeviceName(
2618 OPAL_DRIVER_DEVICE
*Dev
2621 EFI_HANDLE
* AllHandlesBuffer
;
2622 UINTN NumAllHandles
;
2626 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
2631 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
2633 if (Dev
->Name16
== NULL
) {
2634 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
2636 // Find all EFI_HANDLES
2638 Status
= gBS
->LocateHandleBuffer(
2645 if (EFI_ERROR(Status
)) {
2646 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
2651 // Try component Name2
2653 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
2654 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
2655 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
2656 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
2666 Main entry for this driver.
2668 @param ImageHandle Image Handle this driver.
2669 @param SystemTable Pointer to SystemTable.
2671 @retval EFI_SUCESS This function always complete successfully.
2675 EfiDriverEntryPoint(
2676 IN EFI_HANDLE ImageHandle
,
2677 IN EFI_SYSTEM_TABLE
* SystemTable
2681 EFI_EVENT ReadyToBootEvent
;
2682 EFI_EVENT EndOfDxeEvent
;
2684 Status
= EfiLibInstallDriverBindingComponentName2 (
2687 &gOpalDriverBinding
,
2689 &gOpalComponentName
,
2690 &gOpalComponentName2
2693 if (EFI_ERROR(Status
)) {
2694 DEBUG((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
2699 // Initialize Driver object
2701 ZeroMem(&mOpalDriver
, sizeof(mOpalDriver
));
2702 mOpalDriver
.Handle
= ImageHandle
;
2704 Status
= gBS
->CreateEventEx (
2707 OpalEndOfDxeEventNotify
,
2709 &gEfiEndOfDxeEventGroupGuid
,
2712 ASSERT_EFI_ERROR (Status
);
2715 // register a ReadyToBoot event callback for sending BlockSid command
2717 Status
= EfiCreateEventReadyToBootEx (
2719 ReadyToBootCallback
,
2720 (VOID
*) &ImageHandle
,
2725 // Install Hii packages.
2733 Tests to see if this driver supports a given controller.
2735 This function checks to see if the controller contains an instance of the
2736 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL
2737 and returns EFI_SUCCESS if it does.
2739 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2740 @param[in] ControllerHandle The Handle of the controller to test. This Handle
2741 must support a protocol interface that supplies
2742 an I/O abstraction to the driver.
2743 @param[in] RemainingDevicePath This parameter is ignored.
2745 @retval EFI_SUCCESS The device contains required protocols
2746 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
2747 RemainingDevicePath is already being managed by the driver
2749 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
2750 RemainingDevicePath is already being managed by a different
2751 driver or an application that requires exclusive access.
2752 Currently not implemented.
2753 @retval EFI_UNSUPPORTED The device does not contain requires protocols
2758 OpalEfiDriverBindingSupported(
2759 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2760 IN EFI_HANDLE Controller
,
2761 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2765 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
* SecurityCommand
;
2766 EFI_BLOCK_IO_PROTOCOL
* BlkIo
;
2768 if (mOpalEndOfDxe
) {
2769 return EFI_UNSUPPORTED
;
2773 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
2775 Status
= gBS
->OpenProtocol(
2777 &gEfiStorageSecurityCommandProtocolGuid
,
2778 ( VOID
** )&SecurityCommand
,
2779 This
->DriverBindingHandle
,
2781 EFI_OPEN_PROTOCOL_BY_DRIVER
2784 if (Status
== EFI_ALREADY_STARTED
) {
2788 if (EFI_ERROR(Status
)) {
2793 // Close protocol and reopen in Start call
2797 &gEfiStorageSecurityCommandProtocolGuid
,
2798 This
->DriverBindingHandle
,
2803 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2806 Status
= gBS
->OpenProtocol(
2808 &gEfiBlockIoProtocolGuid
,
2810 This
->DriverBindingHandle
,
2812 EFI_OPEN_PROTOCOL_BY_DRIVER
2815 if (EFI_ERROR(Status
)) {
2816 DEBUG((DEBUG_INFO
, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
2821 // Close protocol and reopen in Start call
2825 &gEfiBlockIoProtocolGuid
,
2826 This
->DriverBindingHandle
,
2834 Enables Opal Management on a supported device if available.
2836 The start function is designed to be called after the Opal UEFI Driver has confirmed the
2837 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
2838 This function will complete the other necessary checks, such as verifying the device supports
2839 the correct version of Opal. Upon verification, it will add the device to the
2840 Opal HII list in order to expose Opal managmeent options.
2842 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2843 @param[in] ControllerHandle The Handle of the controller to start. This Handle
2844 must support a protocol interface that supplies
2845 an I/O abstraction to the driver.
2846 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
2847 parameter is ignored by device drivers, and is optional for bus
2848 drivers. For a bus driver, if this parameter is NULL, then handles
2849 for all the children of Controller are created by this driver.
2850 If this parameter is not NULL and the first Device Path Node is
2851 not the End of Device Path Node, then only the Handle for the
2852 child device specified by the first Device Path Node of
2853 RemainingDevicePath is created by this driver.
2854 If the first Device Path Node of RemainingDevicePath is
2855 the End of Device Path Node, no child Handle is created by this
2858 @retval EFI_SUCCESS Opal management was enabled.
2859 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
2860 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
2861 @retval Others The driver failed to start the device.
2866 OpalEfiDriverBindingStart(
2867 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2868 IN EFI_HANDLE Controller
,
2869 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2873 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
2874 OPAL_DRIVER_DEVICE
*Dev
;
2875 OPAL_DRIVER_DEVICE
*Itr
;
2878 Itr
= mOpalDriver
.DeviceList
;
2879 while (Itr
!= NULL
) {
2880 if (Controller
== Itr
->Handle
) {
2887 // Create internal device for tracking. This allows all disks to be tracked
2890 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE
));
2892 return EFI_OUT_OF_RESOURCES
;
2894 Dev
->Handle
= Controller
;
2897 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
2899 Status
= gBS
->OpenProtocol(
2901 &gEfiStorageSecurityCommandProtocolGuid
,
2902 (VOID
**)&Dev
->Sscp
,
2903 This
->DriverBindingHandle
,
2905 EFI_OPEN_PROTOCOL_BY_DRIVER
2907 if (EFI_ERROR(Status
)) {
2913 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2916 Status
= gBS
->OpenProtocol(
2918 &gEfiBlockIoProtocolGuid
,
2920 This
->DriverBindingHandle
,
2922 EFI_OPEN_PROTOCOL_BY_DRIVER
2924 if (EFI_ERROR(Status
)) {
2926 // Close storage security that was opened
2930 &gEfiStorageSecurityCommandProtocolGuid
,
2931 This
->DriverBindingHandle
,
2942 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
2946 &gEfiBlockIoProtocolGuid
,
2947 This
->DriverBindingHandle
,
2952 // Acquire Ascii printable name of child, if not found, then ignore device
2954 Result
= OpalDriverGetDriverDeviceName (Dev
);
2959 Status
= OpalDiskInitialize (Dev
);
2960 if (EFI_ERROR (Status
)) {
2964 AddDeviceToTail(Dev
);
2967 // Check if device is locked and prompt for password.
2969 OpalDriverRequestPassword (Dev
, L
"Unlock:");
2972 // Process OPAL request from last boot.
2974 ProcessOpalRequest (Dev
);
2980 // free device, close protocols and exit
2984 &gEfiStorageSecurityCommandProtocolGuid
,
2985 This
->DriverBindingHandle
,
2991 return EFI_DEVICE_ERROR
;
2995 Stop this driver on Controller.
2997 @param This Protocol instance pointer.
2998 @param Controller Handle of device to stop driver on
2999 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
3000 children is zero stop the entire bus driver.
3001 @param ChildHandleBuffer List of Child Handles to Stop.
3003 @retval EFI_SUCCESS This driver is removed Controller.
3004 @retval other This driver could not be removed from this device.
3009 OpalEfiDriverBindingStop(
3010 EFI_DRIVER_BINDING_PROTOCOL
* This
,
3011 EFI_HANDLE Controller
,
3012 UINTN NumberOfChildren
,
3013 EFI_HANDLE
* ChildHandleBuffer
3016 OPAL_DRIVER_DEVICE
* Itr
;
3018 Itr
= mOpalDriver
.DeviceList
;
3021 // does Controller match any of the devices we are managing for Opal
3023 while (Itr
!= NULL
) {
3024 if (Itr
->Handle
== Controller
) {
3025 OpalDriverStopDevice (Itr
);
3032 return EFI_NOT_FOUND
;
3037 Unloads UEFI Driver. Very useful for debugging and testing.
3039 @param ImageHandle Image Handle this driver.
3041 @retval EFI_SUCCESS This function always complete successfully.
3042 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
3046 OpalEfiDriverUnload (
3047 IN EFI_HANDLE ImageHandle
3051 OPAL_DRIVER_DEVICE
*Itr
;
3053 Status
= EFI_SUCCESS
;
3055 if (ImageHandle
!= gImageHandle
) {
3056 return (EFI_INVALID_PARAMETER
);
3060 // Uninstall any interface added to each device by us
3062 while (mOpalDriver
.DeviceList
) {
3063 Itr
= mOpalDriver
.DeviceList
;
3065 // Remove OPAL_DRIVER_DEVICE from the list
3066 // it updates the controllerList pointer
3068 OpalDriverStopDevice(Itr
);
3072 // Uninstall the HII capability
3074 Status
= HiiUninstall();