#\r
# Opal Password solution\r
#\r
- SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalPasswordDxe.inf\r
- SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.inf\r
SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordDxe.inf\r
SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.inf\r
\r
+++ /dev/null
-/** @file\r
- UEFI Component Name(2) protocol implementation for Opal driver.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "OpalDriver.h"\r
-\r
-//\r
-// EFI Component Name Protocol\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gOpalComponentName = {\r
- OpalEfiDriverComponentNameGetDriverName,\r
- OpalEfiDriverComponentNameGetControllerName,\r
- "eng"\r
-};\r
-\r
-//\r
-// EFI Component Name 2 Protocol\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gOpalComponentName2 = {\r
- OpalEfiDriverComponentName2GetDriverName,\r
- OpalEfiDriverComponentName2GetControllerName,\r
- "en"\r
-};\r
-\r
-\r
-/// The name of the driver in all the languages we support.\r
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mOpalDriverNameTable[] = {\r
- { LANGUAGE_RFC_3066_ENGLISH, (CHAR16*)EFI_DRIVER_NAME_UNICODE },\r
- { LANGUAGE_ISO_639_2_ENGLISH, (CHAR16*)EFI_DRIVER_NAME_UNICODE },\r
- { 0, 0 }\r
-};\r
-\r
-/**\r
- Retrieves a Unicode string that is the user readable name of the driver.\r
-\r
- This function retrieves the user readable name of a driver in the form of a\r
- Unicode string. If the driver specified by This has a user readable name in\r
- the language specified by Language, then a pointer to the driver name is\r
- returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
- by This does not support the language specified by Language,\r
- then EFI_UNSUPPORTED is returned.\r
-\r
- @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
- EFI_COMPONENT_NAME_PROTOCOL instance.\r
-\r
- @param Language[in] A pointer to a Null-terminated ASCII string\r
- array indicating the language. This is the\r
- language of the driver name that the caller is\r
- requesting, and it must match one of the\r
- languages specified in SupportedLanguages. The\r
- number of languages supported by a driver is up\r
- to the driver writer. Language is specified\r
- in RFC 4646 or ISO 639-2 language code format.\r
-\r
- @param DriverName[out] A pointer to the Unicode string to return.\r
- This Unicode string is the name of the\r
- driver specified by This in the language\r
- specified by Language.\r
-\r
- @retval EFI_SUCCESS The Unicode string for the Driver specified by\r
- This and the language specified by Language was\r
- returned in DriverName.\r
-\r
- @retval EFI_INVALID_PARAMETER Language is NULL.\r
-\r
- @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
-\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support\r
- the language specified by Language.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalEfiDriverComponentNameGetDriverName(\r
- EFI_COMPONENT_NAME_PROTOCOL* This,\r
- CHAR8* Language,\r
- CHAR16** DriverName\r
- )\r
-{\r
- return LookupUnicodeString2(\r
- Language,\r
- This->SupportedLanguages,\r
- mOpalDriverNameTable,\r
- DriverName,\r
- TRUE\r
- );\r
-}\r
-\r
-/**\r
- Retrieves a Unicode string that is the user readable name of the driver.\r
-\r
- This function retrieves the user readable name of a driver in the form of a\r
- Unicode string. If the driver specified by This has a user readable name in\r
- the language specified by Language, then a pointer to the driver name is\r
- returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
- by This does not support the language specified by Language,\r
- then EFI_UNSUPPORTED is returned.\r
-\r
- @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
- EFI_COMPONENT_NAME_PROTOCOL instance.\r
-\r
- @param Language[in] A pointer to a Null-terminated ASCII string\r
- array indicating the language. This is the\r
- language of the driver name that the caller is\r
- requesting, and it must match one of the\r
- languages specified in SupportedLanguages. The\r
- number of languages supported by a driver is up\r
- to the driver writer. Language is specified\r
- in RFC 4646 or ISO 639-2 language code format.\r
-\r
- @param DriverName[out] A pointer to the Unicode string to return.\r
- This Unicode string is the name of the\r
- driver specified by This in the language\r
- specified by Language.\r
-\r
- @retval EFI_SUCCESS The Unicode string for the Driver specified by\r
- This and the language specified by Language was\r
- returned in DriverName.\r
-\r
- @retval EFI_INVALID_PARAMETER Language is NULL.\r
-\r
- @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
-\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support\r
- the language specified by Language.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalEfiDriverComponentName2GetDriverName(\r
- EFI_COMPONENT_NAME2_PROTOCOL* This,\r
- CHAR8* Language,\r
- CHAR16** DriverName\r
- )\r
-{\r
- return LookupUnicodeString2(\r
- Language,\r
- This->SupportedLanguages,\r
- mOpalDriverNameTable,\r
- DriverName,\r
- FALSE\r
- );\r
-}\r
-\r
-/**\r
- Retrieves a Unicode string that is the user readable name of the controller\r
- that is being managed by a driver.\r
-\r
- This function retrieves the user readable name of the controller specified by\r
- ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
- driver specified by This has a user readable name in the language specified by\r
- Language, then a pointer to the controller name is returned in ControllerName,\r
- and EFI_SUCCESS is returned. If the driver specified by This is not currently\r
- managing the controller specified by ControllerHandle and ChildHandle,\r
- then EFI_UNSUPPORTED is returned. If the driver specified by This does not\r
- support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
-\r
- @param ControllerHandle[in] The handle of a controller that the driver\r
- specified by This is managing. This handle\r
- specifies the controller whose name is to be\r
- returned.\r
-\r
- @param ChildHandle[in] The handle of the child controller to retrieve\r
- the name of. This is an optional parameter that\r
- may be NULL. It will be NULL for device\r
- drivers. It will also be NULL for a bus drivers\r
- that wish to retrieve the name of the bus\r
- controller. It will not be NULL for a bus\r
- driver that wishes to retrieve the name of a\r
- child controller.\r
-\r
-\r
- @param Language[in] A pointer to a Null-terminated ASCII string\r
- array indicating the language. This is the\r
- language of the driver name that the caller is\r
- requesting, and it must match one of the\r
- languages specified in SupportedLanguages. The\r
- number of languages supported by a driver is up\r
- to the driver writer. Language is specified in\r
- RFC 4646 or ISO 639-2 language code format.\r
-\r
- @param ControllerName[out] A pointer to the Unicode string to return.\r
- This Unicode string is the name of the\r
- controller specified by ControllerHandle and\r
- ChildHandle in the language specified by\r
- Language from the point of view of the driver\r
- specified by This.\r
-\r
- @retval EFI_SUCCESS The Unicode string for the user readable name in\r
- the language specified by Language for the\r
- driver specified by This was returned in\r
- DriverName.\r
-\r
- @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
-\r
- @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
- EFI_HANDLE.\r
-\r
- @retval EFI_INVALID_PARAMETER Language is NULL.\r
-\r
- @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
-\r
- @retval EFI_UNSUPPORTED The driver specified by This is not currently\r
- managing the controller specified by\r
- ControllerHandle and ChildHandle.\r
-\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support\r
- the language specified by Language.\r
-\r
-**/\r
-EFI_STATUS\r
-GetControllerName(\r
- EFI_HANDLE ControllerHandle,\r
- EFI_HANDLE ChildHandle,\r
- CHAR8* Language,\r
- CHAR16** ControllerName\r
- )\r
-{\r
- if (Language == NULL || ControllerName == NULL || ControllerHandle == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- // don't support any controller or children names\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-/**\r
- Retrieves a Unicode string that is the user readable name of the controller\r
- that is being managed by a driver.\r
-\r
- This function retrieves the user readable name of the controller specified by\r
- ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
- driver specified by This has a user readable name in the language specified by\r
- Language, then a pointer to the controller name is returned in ControllerName,\r
- and EFI_SUCCESS is returned. If the driver specified by This is not currently\r
- managing the controller specified by ControllerHandle and ChildHandle,\r
- then EFI_UNSUPPORTED is returned. If the driver specified by This does not\r
- support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
-\r
- @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
- EFI_COMPONENT_NAME_PROTOCOL instance.\r
-\r
- @param ControllerHandle[in] The handle of a controller that the driver\r
- specified by This is managing. This handle\r
- specifies the controller whose name is to be\r
- returned.\r
-\r
- @param ChildHandle[in] The handle of the child controller to retrieve\r
- the name of. This is an optional parameter that\r
- may be NULL. It will be NULL for device\r
- drivers. It will also be NULL for a bus drivers\r
- that wish to retrieve the name of the bus\r
- controller. It will not be NULL for a bus\r
- driver that wishes to retrieve the name of a\r
- child controller.\r
-\r
- @param Language[in] A pointer to a Null-terminated ASCII string\r
- array indicating the language. This is the\r
- language of the driver name that the caller is\r
- requesting, and it must match one of the\r
- languages specified in SupportedLanguages. The\r
- number of languages supported by a driver is up\r
- to the driver writer. Language is specified in\r
- RFC 4646 or ISO 639-2 language code format.\r
-\r
- @param ControllerName[out] A pointer to the Unicode string to return.\r
- This Unicode string is the name of the\r
- controller specified by ControllerHandle and\r
- ChildHandle in the language specified by\r
- Language from the point of view of the driver\r
- specified by This.\r
-\r
- @retval EFI_SUCCESS The Unicode string for the user readable name in\r
- the language specified by Language for the\r
- driver specified by This was returned in\r
- DriverName.\r
-\r
- @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
-\r
- @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
- EFI_HANDLE.\r
-\r
- @retval EFI_INVALID_PARAMETER Language is NULL.\r
-\r
- @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
-\r
- @retval EFI_UNSUPPORTED The driver specified by This is not currently\r
- managing the controller specified by\r
- ControllerHandle and ChildHandle.\r
-\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support\r
- the language specified by Language.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalEfiDriverComponentNameGetControllerName(\r
- EFI_COMPONENT_NAME_PROTOCOL* This,\r
- EFI_HANDLE ControllerHandle,\r
- EFI_HANDLE ChildHandle,\r
- CHAR8* Language,\r
- CHAR16** ControllerName\r
- )\r
-{\r
- return (GetControllerName( ControllerHandle, ChildHandle, Language, ControllerName));\r
-}\r
-\r
-/**\r
- Retrieves a Unicode string that is the user readable name of the controller\r
- that is being managed by a driver.\r
-\r
- This function retrieves the user readable name of the controller specified by\r
- ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
- driver specified by This has a user readable name in the language specified by\r
- Language, then a pointer to the controller name is returned in ControllerName,\r
- and EFI_SUCCESS is returned. If the driver specified by This is not currently\r
- managing the controller specified by ControllerHandle and ChildHandle,\r
- then EFI_UNSUPPORTED is returned. If the driver specified by This does not\r
- support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
-\r
- @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
- EFI_COMPONENT_NAME_PROTOCOL instance.\r
-\r
- @param ControllerHandle[in] The handle of a controller that the driver\r
- specified by This is managing. This handle\r
- specifies the controller whose name is to be\r
- returned.\r
-\r
- @param ChildHandle[in] The handle of the child controller to retrieve\r
- the name of. This is an optional parameter that\r
- may be NULL. It will be NULL for device\r
- drivers. It will also be NULL for a bus drivers\r
- that wish to retrieve the name of the bus\r
- controller. It will not be NULL for a bus\r
- driver that wishes to retrieve the name of a\r
- child controller.\r
-\r
- @param Language[in] A pointer to a Null-terminated ASCII string\r
- array indicating the language. This is the\r
- language of the driver name that the caller is\r
- requesting, and it must match one of the\r
- languages specified in SupportedLanguages. The\r
- number of languages supported by a driver is up\r
- to the driver writer. Language is specified in\r
- RFC 4646 or ISO 639-2 language code format.\r
-\r
- @param ControllerName[out] A pointer to the Unicode string to return.\r
- This Unicode string is the name of the\r
- controller specified by ControllerHandle and\r
- ChildHandle in the language specified by\r
- Language from the point of view of the driver\r
- specified by This.\r
-\r
- @retval EFI_SUCCESS The Unicode string for the user readable name in\r
- the language specified by Language for the\r
- driver specified by This was returned in\r
- DriverName.\r
-\r
- @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
-\r
- @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
- EFI_HANDLE.\r
-\r
- @retval EFI_INVALID_PARAMETER Language is NULL.\r
-\r
- @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
-\r
- @retval EFI_UNSUPPORTED The driver specified by This is not currently\r
- managing the controller specified by\r
- ControllerHandle and ChildHandle.\r
-\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support\r
- the language specified by Language.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalEfiDriverComponentName2GetControllerName(\r
- EFI_COMPONENT_NAME2_PROTOCOL* This,\r
- EFI_HANDLE ControllerHandle,\r
- EFI_HANDLE ChildHandle,\r
- CHAR8* Language,\r
- CHAR16** ControllerName\r
- )\r
-{\r
- return (GetControllerName(ControllerHandle, ChildHandle, Language, ControllerName));\r
-}\r
-\r
+++ /dev/null
-/** @file\r
- Entrypoint of Opal UEFI Driver and contains all the logic to\r
- register for new Opal device instances.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-// This UEFI driver consumes EFI_STORAGE_SECURITY_PROTOCOL instances and installs an\r
-// HII GUI to manage Opal features if the device is Opal capable\r
-// If the Opal device is being managed by the UEFI Driver, it shall provide a popup\r
-// window during boot requesting a user password\r
-\r
-#include "OpalDriver.h"\r
-#include "OpalDriverPrivate.h"\r
-#include "OpalHii.h"\r
-\r
-OPAL_DRIVER mOpalDriver;\r
-\r
-#define MAX_PASSWORD_SIZE 32\r
-#define MAX_PASSWORD_TRY_COUNT 5\r
-\r
-//\r
-// Globals\r
-//\r
-EFI_DRIVER_BINDING_PROTOCOL gOpalDriverBinding = {\r
- OpalEfiDriverBindingSupported,\r
- OpalEfiDriverBindingStart,\r
- OpalEfiDriverBindingStop,\r
- 0x1b,\r
- NULL,\r
- NULL\r
-};\r
-\r
-\r
-/**\r
- Add new device to the global device list.\r
-\r
- @param Dev New create device.\r
-\r
-**/\r
-VOID\r
-AddDeviceToTail(\r
- IN OPAL_DRIVER_DEVICE *Dev\r
- )\r
-{\r
- OPAL_DRIVER_DEVICE *TmpDev;\r
-\r
- if (mOpalDriver.DeviceList == NULL) {\r
- mOpalDriver.DeviceList = Dev;\r
- } else {\r
- TmpDev = mOpalDriver.DeviceList;\r
- while (TmpDev->Next != NULL) {\r
- TmpDev = TmpDev->Next;\r
- }\r
-\r
- TmpDev->Next = Dev;\r
- }\r
-}\r
-\r
-/**\r
- Remove one device in the global device list.\r
-\r
- @param Dev The device need to be removed.\r
-\r
-**/\r
-VOID\r
-RemoveDevice (\r
- IN OPAL_DRIVER_DEVICE *Dev\r
- )\r
-{\r
- OPAL_DRIVER_DEVICE *TmpDev;\r
-\r
- if (mOpalDriver.DeviceList == NULL) {\r
- return;\r
- }\r
-\r
- if (mOpalDriver.DeviceList == Dev) {\r
- mOpalDriver.DeviceList = NULL;\r
- return;\r
- }\r
-\r
- TmpDev = mOpalDriver.DeviceList;\r
- while (TmpDev->Next != NULL) {\r
- if (TmpDev->Next == Dev) {\r
- TmpDev->Next = Dev->Next;\r
- break;\r
- }\r
- }\r
-}\r
-\r
-/**\r
- Get current device count.\r
-\r
- @retval return the current created device count.\r
-\r
-**/\r
-UINT8\r
-GetDeviceCount (\r
- VOID\r
- )\r
-{\r
- UINT8 Count;\r
- OPAL_DRIVER_DEVICE *TmpDev;\r
-\r
- Count = 0;\r
- TmpDev = mOpalDriver.DeviceList;\r
-\r
- while (TmpDev != NULL) {\r
- Count++;\r
- TmpDev = TmpDev->Next;\r
- }\r
-\r
- return Count;\r
-}\r
-\r
-/**\r
- Get password input from the popup windows, and unlock the device.\r
-\r
- @param[in] Dev The device which need to be unlock.\r
- @param[out] PressEsc Whether user escape function through Press ESC.\r
-\r
- @retval Password string if success. NULL if failed.\r
-\r
-**/\r
-CHAR8 *\r
-OpalDriverPopUpHddPassword (\r
- IN OPAL_DRIVER_DEVICE *Dev,\r
- OUT BOOLEAN *PressEsc\r
- )\r
-{\r
- EFI_INPUT_KEY InputKey;\r
- UINTN InputLength;\r
- CHAR16 Mask[MAX_PASSWORD_SIZE + 1];\r
- CHAR16 Unicode[MAX_PASSWORD_SIZE + 1];\r
- CHAR8 *Ascii;\r
- CHAR16 *PopUpString;\r
- UINTN StrLength;\r
-\r
- ZeroMem(Unicode, sizeof(Unicode));\r
- ZeroMem(Mask, sizeof(Mask));\r
-\r
- StrLength = StrLen(Dev->Name16);\r
- PopUpString = (CHAR16*) AllocateZeroPool ((8 + StrLength) * 2);\r
- *PressEsc = FALSE;\r
-\r
- if (Dev->Name16 == NULL) {\r
- UnicodeSPrint(PopUpString, StrLen(L"Unlock Disk") + 1, L"Unlock Disk");\r
- } else {\r
- UnicodeSPrint(PopUpString, StrLen(L"Unlock ") + StrLength + 1, L"Unlock %s", Dev->Name16);\r
- }\r
-\r
- gST->ConOut->ClearScreen(gST->ConOut);\r
-\r
- InputLength = 0;\r
- while (TRUE) {\r
- Mask[InputLength] = L'_';\r
- CreatePopUp(\r
- EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
- &InputKey,\r
- PopUpString,\r
- L"---------------------",\r
- Mask,\r
- NULL\r
- );\r
-\r
- //\r
- // Check key.\r
- //\r
- if (InputKey.ScanCode == SCAN_NULL) {\r
- //\r
- // password finished\r
- //\r
- if (InputKey.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
- //\r
- // Add the null terminator.\r
- //\r
- Unicode[InputLength] = 0;\r
- InputLength++;\r
- break;\r
- } else if ((InputKey.UnicodeChar == CHAR_NULL) ||\r
- (InputKey.UnicodeChar == CHAR_TAB) ||\r
- (InputKey.UnicodeChar == CHAR_LINEFEED)\r
- ) {\r
- continue;\r
- } else {\r
- //\r
- // delete last key entered\r
- //\r
- if (InputKey.UnicodeChar == CHAR_BACKSPACE) {\r
- if (InputLength > 0) {\r
- Unicode[InputLength] = 0;\r
- Mask[InputLength] = 0;\r
- InputLength--;\r
- }\r
- } else {\r
- //\r
- // add Next key entry\r
- //\r
- Unicode[InputLength] = InputKey.UnicodeChar;\r
- Mask[InputLength] = L'*';\r
- InputLength++;\r
- if (InputLength == MAX_PASSWORD_SIZE) {\r
- //\r
- // Add the null terminator.\r
- //\r
- Unicode[InputLength] = 0;\r
- Mask[InputLength] = 0;\r
- break;\r
- }\r
- }\r
- }\r
- }\r
-\r
- //\r
- // exit on ESC\r
- //\r
- if (InputKey.ScanCode == SCAN_ESC) {\r
- *PressEsc = TRUE;\r
- break;\r
- }\r
- }\r
-\r
- gST->ConOut->ClearScreen(gST->ConOut);\r
-\r
- if (InputLength == 0 || InputKey.ScanCode == SCAN_ESC) {\r
- return NULL;\r
- }\r
-\r
- Ascii = AllocateZeroPool (MAX_PASSWORD_SIZE + 1);\r
- if (Ascii == NULL) {\r
- return NULL;\r
- }\r
-\r
- UnicodeStrToAsciiStrS (Unicode, Ascii, MAX_PASSWORD_SIZE + 1);\r
- ZeroMem (Unicode, sizeof (Unicode));\r
-\r
- return Ascii;\r
-}\r
-\r
-/**\r
- Check if disk is locked, show popup window and ask for password if it is\r
-\r
- @param[in] Dev The device which need to be unlock.\r
-\r
-**/\r
-VOID\r
-OpalDriverRequestPassword (\r
- OPAL_DRIVER_DEVICE *Dev\r
- )\r
-{\r
- UINT8 Count;\r
- BOOLEAN IsEnabled;\r
- CHAR8 *Password;\r
- UINT32 PasswordLen;\r
- TCG_RESULT Ret;\r
- EFI_INPUT_KEY Key;\r
- OPAL_SESSION Session;\r
- BOOLEAN PressEsc;\r
- BOOLEAN Locked;\r
-\r
- if (Dev == NULL) {\r
- return;\r
- }\r
-\r
- Count = 0;\r
-\r
- IsEnabled = OpalFeatureEnabled (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature);\r
- if (IsEnabled) {\r
- ZeroMem(&Session, sizeof(Session));\r
- Session.Sscp = Dev->OpalDisk.Sscp;\r
- Session.MediaId = Dev->OpalDisk.MediaId;\r
- Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
-\r
- Locked = OpalDeviceLocked (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature);\r
-\r
- while (Count < MAX_PASSWORD_TRY_COUNT) {\r
- Password = OpalDriverPopUpHddPassword (Dev, &PressEsc);\r
- if (PressEsc) {\r
- if (Locked) {\r
- //\r
- // Current device in the lock status and\r
- // User not input password and press ESC,\r
- // keep device in lock status and continue boot.\r
- //\r
- do {\r
- CreatePopUp (\r
- EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
- &Key,\r
- L"Press ENTER to skip password, Press ESC to input password",\r
- NULL\r
- );\r
- } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
-\r
- if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
- gST->ConOut->ClearScreen(gST->ConOut);\r
- //\r
- // Keep lock and continue boot.\r
- //\r
- return;\r
- } else {\r
- //\r
- // Let user input password again.\r
- //\r
- continue;\r
- }\r
- } else {\r
- //\r
- // Current device in the unlock status and\r
- // User not input password and press ESC,\r
- // Shutdown the device.\r
- //\r
- do {\r
- CreatePopUp (\r
- EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
- &Key,\r
- L"Press ENTER to shutdown, Press ESC to input password",\r
- NULL\r
- );\r
- } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
-\r
- if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
- gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);\r
- } else {\r
- //\r
- // Let user input password again.\r
- //\r
- continue;\r
- }\r
- }\r
- }\r
-\r
- if (Password == NULL) {\r
- Count ++;\r
- continue;\r
- }\r
- PasswordLen = (UINT32) AsciiStrLen(Password);\r
-\r
- if (Locked) {\r
- Ret = OpalSupportUnlock(&Session, Password, PasswordLen, Dev->OpalDevicePath);\r
- } else {\r
- Ret = OpalSupportLock(&Session, Password, PasswordLen, Dev->OpalDevicePath);\r
- if (Ret == TcgResultSuccess) {\r
- Ret = OpalSupportUnlock(&Session, Password, PasswordLen, Dev->OpalDevicePath);\r
- }\r
- }\r
-\r
- if (Password != NULL) {\r
- ZeroMem (Password, PasswordLen);\r
- FreePool (Password);\r
- }\r
-\r
- if (Ret == TcgResultSuccess) {\r
- break;\r
- }\r
-\r
- Count++;\r
-\r
- do {\r
- CreatePopUp (\r
- EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
- &Key,\r
- L"Invalid password.",\r
- L"Press ENTER to retry",\r
- NULL\r
- );\r
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
- }\r
-\r
- if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
- do {\r
- CreatePopUp (\r
- EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
- &Key,\r
- L"Opal password retry count exceeds the limit. Must shutdown!",\r
- L"Press ENTER to shutdown",\r
- NULL\r
- );\r
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
-\r
- gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);\r
- }\r
- }\r
-}\r
-\r
-/**\r
- Get devcie list info.\r
-\r
- @retval return the device list pointer.\r
-**/\r
-OPAL_DRIVER_DEVICE*\r
-OpalDriverGetDeviceList(\r
- VOID\r
- )\r
-{\r
- return mOpalDriver.DeviceList;\r
-}\r
-\r
-/**\r
- ReadyToBoot callback to send BlockSid command.\r
-\r
- @param Event Pointer to this event\r
- @param Context Event handler private Data\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-ReadyToBootCallback (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- OPAL_DRIVER_DEVICE *Itr;\r
- TCG_RESULT Result;\r
- OPAL_SESSION Session;\r
- UINT32 PpStorageFlag;\r
-\r
- gBS->CloseEvent (Event);\r
-\r
- PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags ();\r
- if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) {\r
- //\r
- // Send BlockSID command to each Opal disk\r
- //\r
- Itr = mOpalDriver.DeviceList;\r
- while (Itr != NULL) {\r
- if (Itr->OpalDisk.SupportedAttributes.BlockSid) {\r
- ZeroMem(&Session, sizeof(Session));\r
- Session.Sscp = Itr->OpalDisk.Sscp;\r
- Session.MediaId = Itr->OpalDisk.MediaId;\r
- Session.OpalBaseComId = Itr->OpalDisk.OpalBaseComId;\r
-\r
- Result = OpalBlockSid (&Session, TRUE); // HardwareReset must always be TRUE\r
- if (Result != TcgResultSuccess) {\r
- DEBUG ((DEBUG_ERROR, "OpalBlockSid fail\n"));\r
- break;\r
- }\r
- }\r
-\r
- Itr = Itr->Next;\r
- }\r
- }\r
-}\r
-\r
-/**\r
- Stop this Controller.\r
-\r
- @param Dev The device need to be stopped.\r
-\r
-**/\r
-VOID\r
-OpalDriverStopDevice (\r
- OPAL_DRIVER_DEVICE *Dev\r
- )\r
-{\r
- //\r
- // free each name\r
- //\r
- FreePool(Dev->Name16);\r
-\r
- //\r
- // remove OPAL_DRIVER_DEVICE from the list\r
- // it updates the controllerList pointer\r
- //\r
- RemoveDevice(Dev);\r
-\r
- //\r
- // close protocols that were opened\r
- //\r
- gBS->CloseProtocol(\r
- Dev->Handle,\r
- &gEfiStorageSecurityCommandProtocolGuid,\r
- gOpalDriverBinding.DriverBindingHandle,\r
- Dev->Handle\r
- );\r
-\r
- gBS->CloseProtocol(\r
- Dev->Handle,\r
- &gEfiBlockIoProtocolGuid,\r
- gOpalDriverBinding.DriverBindingHandle,\r
- Dev->Handle\r
- );\r
-\r
- FreePool(Dev);\r
-}\r
-\r
-/**\r
- Get devcie name through the component name protocol.\r
-\r
- @param[in] AllHandlesBuffer The handle buffer for current system.\r
- @param[in] NumAllHandles The number of handles for the handle buffer.\r
- @param[in] Dev The device which need to get name.\r
- @param[in] UseComp1 Whether use component name or name2 protocol.\r
-\r
- @retval TRUE Find the name for this device.\r
- @retval FALSE Not found the name for this device.\r
-**/\r
-BOOLEAN\r
-OpalDriverGetDeviceNameByProtocol(\r
- EFI_HANDLE *AllHandlesBuffer,\r
- UINTN NumAllHandles,\r
- OPAL_DRIVER_DEVICE *Dev,\r
- BOOLEAN UseComp1\r
- )\r
-{\r
- EFI_HANDLE* ProtocolHandlesBuffer;\r
- UINTN NumProtocolHandles;\r
- EFI_STATUS Status;\r
- EFI_COMPONENT_NAME2_PROTOCOL* Cnp1_2; // efi component name and componentName2 have same layout\r
- EFI_GUID Protocol;\r
- UINTN StrLength;\r
- EFI_DEVICE_PATH_PROTOCOL* TmpDevPath;\r
- UINTN Index1;\r
- UINTN Index2;\r
- EFI_HANDLE TmpHandle;\r
- CHAR16 *DevName;\r
-\r
- if (Dev == NULL || AllHandlesBuffer == NULL || NumAllHandles == 0) {\r
- return FALSE;\r
- }\r
-\r
- Protocol = UseComp1 ? gEfiComponentNameProtocolGuid : gEfiComponentName2ProtocolGuid;\r
-\r
- //\r
- // Find all EFI_HANDLES with protocol\r
- //\r
- Status = gBS->LocateHandleBuffer(\r
- ByProtocol,\r
- &Protocol,\r
- NULL,\r
- &NumProtocolHandles,\r
- &ProtocolHandlesBuffer\r
- );\r
- if (EFI_ERROR(Status)) {\r
- return FALSE;\r
- }\r
-\r
-\r
- //\r
- // Exit early if no supported devices\r
- //\r
- if (NumProtocolHandles == 0) {\r
- return FALSE;\r
- }\r
-\r
- //\r
- // Get printable name by iterating through all protocols\r
- // using the handle as the child, and iterate through all handles for the controller\r
- // exit loop early once found, if not found, then delete device\r
- // storage security protocol instances already exist, add them to internal list\r
- //\r
- Status = EFI_DEVICE_ERROR;\r
- for (Index1 = 0; Index1 < NumProtocolHandles; Index1++) {\r
- DevName = NULL;\r
-\r
- if (Dev->Name16 != NULL) {\r
- return TRUE;\r
- }\r
-\r
- TmpHandle = ProtocolHandlesBuffer[Index1];\r
-\r
- Status = gBS->OpenProtocol(\r
- TmpHandle,\r
- &Protocol,\r
- (VOID**)&Cnp1_2,\r
- gImageHandle,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR(Status) || Cnp1_2 == NULL) {\r
- continue;\r
- }\r
-\r
- //\r
- // Use all handles array as controller handle\r
- //\r
- for (Index2 = 0; Index2 < NumAllHandles; Index2++) {\r
- Status = Cnp1_2->GetControllerName(\r
- Cnp1_2,\r
- AllHandlesBuffer[Index2],\r
- Dev->Handle,\r
- LANGUAGE_ISO_639_2_ENGLISH,\r
- &DevName\r
- );\r
- if (EFI_ERROR(Status)) {\r
- Status = Cnp1_2->GetControllerName(\r
- Cnp1_2,\r
- AllHandlesBuffer[Index2],\r
- Dev->Handle,\r
- LANGUAGE_RFC_3066_ENGLISH,\r
- &DevName\r
- );\r
- }\r
- if (!EFI_ERROR(Status) && DevName != NULL) {\r
- StrLength = StrLen(DevName) + 1; // Add one for NULL terminator\r
- Dev->Name16 = AllocateZeroPool(StrLength * sizeof (CHAR16));\r
- ASSERT (Dev->Name16 != NULL);\r
- StrCpyS (Dev->Name16, StrLength, DevName);\r
- Dev->NameZ = (CHAR8*)AllocateZeroPool(StrLength);\r
- UnicodeStrToAsciiStrS (DevName, Dev->NameZ, StrLength);\r
-\r
- //\r
- // Retrieve bridge BDF info and port number or namespace depending on type\r
- //\r
- TmpDevPath = NULL;\r
- Status = gBS->OpenProtocol(\r
- Dev->Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID**)&TmpDevPath,\r
- gImageHandle,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (!EFI_ERROR(Status)) {\r
- Dev->OpalDevicePath = DuplicateDevicePath (TmpDevPath);\r
- return TRUE;\r
- }\r
-\r
- if (Dev->Name16 != NULL) {\r
- FreePool(Dev->Name16);\r
- Dev->Name16 = NULL;\r
- }\r
- if (Dev->NameZ != NULL) {\r
- FreePool(Dev->NameZ);\r
- Dev->NameZ = NULL;\r
- }\r
- }\r
- }\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-/**\r
- Get devcie name through the component name protocol.\r
-\r
- @param[in] Dev The device which need to get name.\r
-\r
- @retval TRUE Find the name for this device.\r
- @retval FALSE Not found the name for this device.\r
-**/\r
-BOOLEAN\r
-OpalDriverGetDriverDeviceName(\r
- OPAL_DRIVER_DEVICE *Dev\r
- )\r
-{\r
- EFI_HANDLE* AllHandlesBuffer;\r
- UINTN NumAllHandles;\r
- EFI_STATUS Status;\r
-\r
- if (Dev == NULL) {\r
- DEBUG((DEBUG_ERROR | DEBUG_INIT, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));\r
- return FALSE;\r
- }\r
-\r
- //\r
- // Iterate through ComponentName2 handles to get name, if fails, try ComponentName\r
- //\r
- if (Dev->Name16 == NULL) {\r
- DEBUG((DEBUG_ERROR | DEBUG_INIT, "Name is null, update it\n"));\r
- //\r
- // Find all EFI_HANDLES\r
- //\r
- Status = gBS->LocateHandleBuffer(\r
- AllHandles,\r
- NULL,\r
- NULL,\r
- &NumAllHandles,\r
- &AllHandlesBuffer\r
- );\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_INFO, "LocateHandleBuffer for AllHandles failed %r\n", Status ));\r
- return FALSE;\r
- }\r
-\r
- //\r
- // Try component Name2\r
- //\r
- if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer, NumAllHandles, Dev, FALSE)) {\r
- DEBUG((DEBUG_ERROR | DEBUG_INIT, "ComponentName2 failed to get device name, try ComponentName\n"));\r
- if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer, NumAllHandles, Dev, TRUE)) {\r
- DEBUG((DEBUG_ERROR | DEBUG_INIT, "ComponentName failed to get device name, skip device\n"));\r
- return FALSE;\r
- }\r
- }\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
- Main entry for this driver.\r
-\r
- @param ImageHandle Image Handle this driver.\r
- @param SystemTable Pointer to SystemTable.\r
-\r
- @retval EFI_SUCESS This function always complete successfully.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiDriverEntryPoint(\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE* SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_EVENT ReadyToBootEvent;\r
-\r
- Status = EfiLibInstallDriverBindingComponentName2 (\r
- ImageHandle,\r
- SystemTable,\r
- &gOpalDriverBinding,\r
- ImageHandle,\r
- &gOpalComponentName,\r
- &gOpalComponentName2\r
- );\r
-\r
- if (EFI_ERROR(Status)) {\r
- DEBUG((DEBUG_ERROR, "Install protocols to Opal driver Handle failed\n"));\r
- return Status ;\r
- }\r
-\r
- //\r
- // Initialize Driver object\r
- //\r
- ZeroMem(&mOpalDriver, sizeof(mOpalDriver));\r
- mOpalDriver.Handle = ImageHandle;\r
-\r
- //\r
- // register a ReadyToBoot event callback for sending BlockSid command\r
- //\r
- Status = EfiCreateEventReadyToBootEx (\r
- TPL_CALLBACK,\r
- ReadyToBootCallback,\r
- (VOID *) &ImageHandle,\r
- &ReadyToBootEvent\r
- );\r
-\r
- //\r
- // Install Hii packages.\r
- //\r
- HiiInstall();\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Tests to see if this driver supports a given controller.\r
-\r
- This function checks to see if the controller contains an instance of the\r
- EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL\r
- and returns EFI_SUCCESS if it does.\r
-\r
- @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
- @param[in] ControllerHandle The Handle of the controller to test. This Handle\r
- must support a protocol interface that supplies\r
- an I/O abstraction to the driver.\r
- @param[in] RemainingDevicePath This parameter is ignored.\r
-\r
- @retval EFI_SUCCESS The device contains required protocols\r
- @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r
- RemainingDevicePath is already being managed by the driver\r
- specified by This.\r
- @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r
- RemainingDevicePath is already being managed by a different\r
- driver or an application that requires exclusive access.\r
- Currently not implemented.\r
- @retval EFI_UNSUPPORTED The device does not contain requires protocols\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalEfiDriverBindingSupported(\r
- IN EFI_DRIVER_BINDING_PROTOCOL* This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_STORAGE_SECURITY_COMMAND_PROTOCOL* SecurityCommand;\r
- EFI_BLOCK_IO_PROTOCOL* BlkIo;\r
-\r
- //\r
- // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.\r
- //\r
- Status = gBS->OpenProtocol(\r
- Controller,\r
- &gEfiStorageSecurityCommandProtocolGuid,\r
- ( VOID ** )&SecurityCommand,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
-\r
- if (Status == EFI_ALREADY_STARTED) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Close protocol and reopen in Start call\r
- //\r
- gBS->CloseProtocol(\r
- Controller,\r
- &gEfiStorageSecurityCommandProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- //\r
- // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL\r
- // function APIs\r
- //\r
- Status = gBS->OpenProtocol(\r
- Controller,\r
- &gEfiBlockIoProtocolGuid,\r
- (VOID **)&BlkIo,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
-\r
- if (EFI_ERROR(Status)) {\r
- DEBUG((DEBUG_INFO, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));\r
- return Status;\r
- }\r
-\r
- //\r
- // Close protocol and reopen in Start call\r
- //\r
- gBS->CloseProtocol(\r
- Controller,\r
- &gEfiBlockIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Enables Opal Management on a supported device if available.\r
-\r
- The start function is designed to be called after the Opal UEFI Driver has confirmed the\r
- "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.\r
- This function will complete the other necessary checks, such as verifying the device supports\r
- the correct version of Opal. Upon verification, it will add the device to the\r
- Opal HII list in order to expose Opal managmeent options.\r
-\r
- @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
- @param[in] ControllerHandle The Handle of the controller to start. This Handle\r
- must support a protocol interface that supplies\r
- an I/O abstraction to the driver.\r
- @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
- parameter is ignored by device drivers, and is optional for bus\r
- drivers. For a bus driver, if this parameter is NULL, then handles\r
- for all the children of Controller are created by this driver.\r
- If this parameter is not NULL and the first Device Path Node is\r
- not the End of Device Path Node, then only the Handle for the\r
- child device specified by the first Device Path Node of\r
- RemainingDevicePath is created by this driver.\r
- If the first Device Path Node of RemainingDevicePath is\r
- the End of Device Path Node, no child Handle is created by this\r
- driver.\r
-\r
- @retval EFI_SUCCESS Opal management was enabled.\r
- @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
- @retval Others The driver failed to start the device.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalEfiDriverBindingStart(\r
- IN EFI_DRIVER_BINDING_PROTOCOL* This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
- OPAL_DRIVER_DEVICE *Dev;\r
- OPAL_DRIVER_DEVICE *Itr;\r
- BOOLEAN Result;\r
-\r
- Itr = mOpalDriver.DeviceList;\r
- while (Itr != NULL) {\r
- if (Controller == Itr->Handle) {\r
- return EFI_SUCCESS;\r
- }\r
- Itr = Itr->Next;\r
- }\r
-\r
- //\r
- // Create internal device for tracking. This allows all disks to be tracked\r
- // by same HII form\r
- //\r
- Dev = (OPAL_DRIVER_DEVICE*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE));\r
- if (Dev == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- Dev->Handle = Controller;\r
-\r
- //\r
- // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks\r
- //\r
- Status = gBS->OpenProtocol(\r
- Controller,\r
- &gEfiStorageSecurityCommandProtocolGuid,\r
- (VOID **)&Dev->Sscp,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (EFI_ERROR(Status)) {\r
- FreePool(Dev);\r
- return Status;\r
- }\r
-\r
- //\r
- // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL\r
- // function APIs\r
- //\r
- Status = gBS->OpenProtocol(\r
- Controller,\r
- &gEfiBlockIoProtocolGuid,\r
- (VOID **)&BlkIo,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (EFI_ERROR(Status)) {\r
- //\r
- // Close storage security that was opened\r
- //\r
- gBS->CloseProtocol(\r
- Controller,\r
- &gEfiStorageSecurityCommandProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- FreePool(Dev);\r
- return Status;\r
- }\r
-\r
- //\r
- // Save mediaId\r
- //\r
- Dev->MediaId = BlkIo->Media->MediaId;\r
-\r
- gBS->CloseProtocol(\r
- Controller,\r
- &gEfiBlockIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- //\r
- // Acquire Ascii printable name of child, if not found, then ignore device\r
- //\r
- Result = OpalDriverGetDriverDeviceName (Dev);\r
- if (!Result) {\r
- goto Done;\r
- }\r
-\r
- Status = OpalDiskInitialize (Dev);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- AddDeviceToTail(Dev);\r
-\r
- //\r
- // check if device is locked and prompt for password\r
- //\r
- OpalDriverRequestPassword (Dev);\r
-\r
- return EFI_SUCCESS;\r
-\r
-Done:\r
- //\r
- // free device, close protocols and exit\r
- //\r
- gBS->CloseProtocol(\r
- Controller,\r
- &gEfiStorageSecurityCommandProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- FreePool(Dev);\r
-\r
- return EFI_DEVICE_ERROR;\r
-}\r
-\r
-/**\r
- Stop this driver on Controller.\r
-\r
- @param This Protocol instance pointer.\r
- @param Controller Handle of device to stop driver on\r
- @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
- children is zero stop the entire bus driver.\r
- @param ChildHandleBuffer List of Child Handles to Stop.\r
-\r
- @retval EFI_SUCCESS This driver is removed Controller.\r
- @retval other This driver could not be removed from this device.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalEfiDriverBindingStop(\r
- EFI_DRIVER_BINDING_PROTOCOL* This,\r
- EFI_HANDLE Controller,\r
- UINTN NumberOfChildren,\r
- EFI_HANDLE* ChildHandleBuffer\r
- )\r
-{\r
- OPAL_DRIVER_DEVICE* Itr;\r
-\r
- Itr = mOpalDriver.DeviceList;\r
-\r
- //\r
- // does Controller match any of the devices we are managing for Opal\r
- //\r
- while (Itr != NULL) {\r
- if (Itr->Handle == Controller) {\r
- OpalDriverStopDevice (Itr);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Itr = Itr->Next;\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-\r
-/**\r
- Unloads UEFI Driver. Very useful for debugging and testing.\r
-\r
- @param ImageHandle Image Handle this driver.\r
-\r
- @retval EFI_SUCCESS This function always complete successfully.\r
- @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalEfiDriverUnload (\r
- IN EFI_HANDLE ImageHandle\r
- )\r
-{\r
- EFI_STATUS Status;\r
- OPAL_DRIVER_DEVICE *Itr;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- if (ImageHandle != gImageHandle) {\r
- return (EFI_INVALID_PARAMETER);\r
- }\r
-\r
- //\r
- // Uninstall any interface added to each device by us\r
- //\r
- while (mOpalDriver.DeviceList) {\r
- Itr = mOpalDriver.DeviceList;\r
- //\r
- // Remove OPAL_DRIVER_DEVICE from the list\r
- // it updates the controllerList pointer\r
- //\r
- OpalDriverStopDevice(Itr);\r
- }\r
-\r
- //\r
- // Uninstall the HII capability\r
- //\r
- Status = HiiUninstall();\r
-\r
- return Status;\r
-}\r
-\r
+++ /dev/null
-/** @file\r
- Values defined and used by the Opal UEFI Driver.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#ifndef _OPAL_DRIVER_H_\r
-#define _OPAL_DRIVER_H_\r
-\r
-#include <PiDxe.h>\r
-\r
-#include <Protocol/PciIo.h>\r
-#include <Protocol/SmmCommunication.h>\r
-#include <Protocol/BlockIo.h>\r
-#include <Protocol/LoadedImage.h>\r
-#include <Protocol/DevicePath.h>\r
-#include <Protocol/DevicePathToText.h>\r
-#include <Protocol/StorageSecurityCommand.h>\r
-\r
-#include <Library/UefiLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/PrintLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/HiiLib.h>\r
-#include <Library/UefiHiiServicesLib.h>\r
-#include <Library/TcgStorageOpalLib.h>\r
-#include <Library/OpalPasswordSupportLib.h>\r
-#include <Library/Tcg2PhysicalPresenceLib.h>\r
-\r
-#define EFI_DRIVER_NAME_UNICODE L"1.0 UEFI Opal Driver"\r
-\r
-// UEFI 2.1\r
-#define LANGUAGE_RFC_3066_ENGLISH ((CHAR8*)"en")\r
-\r
-// UEFI/EFI < 2.1\r
-#define LANGUAGE_ISO_639_2_ENGLISH ((CHAR8*)"eng")\r
-\r
-\r
-#define UNLOCK_VAR_NAME (const CHAR16*)L"UNLOCK"\r
-#define OPAL_FILTER_DRIVER_VAR_NAME L"FILTER_DRIVER"\r
-\r
-\r
-#define CONCAT_(x, y) x ## y\r
-#define CONCAT(x, y) CONCAT_(x, y)\r
-\r
-#define UNICODE_STR(x) CONCAT( L, x )\r
-\r
-extern EFI_DRIVER_BINDING_PROTOCOL gOpalDriverBinding;\r
-extern EFI_COMPONENT_NAME_PROTOCOL gOpalComponentName;\r
-extern EFI_COMPONENT_NAME2_PROTOCOL gOpalComponentName2;\r
-\r
-/**\r
- Unloads UEFI Driver. Very useful for debugging and testing.\r
-\r
- @param ImageHandle Image handle this driver.\r
-\r
- @retval EFI_SUCCESS This function always complete successfully.\r
- @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiDriverUnload(\r
- EFI_HANDLE ImageHandle\r
- );\r
-\r
-\r
-/**\r
- Test to see if this driver supports Controller.\r
-\r
- @param This Protocol instance pointer.\r
- @param ControllerHandle Handle of device to test\r
- @param RemainingDevicePath Optional parameter use to pick a specific child\r
- device to start.\r
-\r
- @retval EFI_SUCCESS This driver supports this device.\r
- @retval EFI_ALREADY_STARTED This driver is already running on this device.\r
- @retval other This driver does not support this device.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalEfiDriverBindingSupported(\r
- EFI_DRIVER_BINDING_PROTOCOL* This,\r
- EFI_HANDLE Controller,\r
- EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath\r
- );\r
-\r
-/**\r
- Enables Opal Management on a supported device if available.\r
-\r
- The start function is designed to be called after the Opal UEFI Driver has confirmed the\r
- "controller", which is a child handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.\r
- This function will complete the other necessary checks, such as verifying the device supports\r
- the correct version of Opal. Upon verification, it will add the device to the\r
- Opal HII list in order to expose Opal managmeent options.\r
-\r
- @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
- @param[in] ControllerHandle The handle of the controller to start. This handle\r
- must support a protocol interface that supplies\r
- an I/O abstraction to the driver.\r
- @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
- parameter is ignored by device drivers, and is optional for bus\r
- drivers. For a bus driver, if this parameter is NULL, then handles\r
- for all the children of Controller are created by this driver.\r
- If this parameter is not NULL and the first Device Path Node is\r
- not the End of Device Path Node, then only the handle for the\r
- child device specified by the first Device Path Node of\r
- RemainingDevicePath is created by this driver.\r
- If the first Device Path Node of RemainingDevicePath is\r
- the End of Device Path Node, no child handle is created by this\r
- driver.\r
-\r
- @retval EFI_SUCCESS Opal management was enabled.\r
- @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
- @retval Others The driver failed to start the device.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalEfiDriverBindingStart(\r
- EFI_DRIVER_BINDING_PROTOCOL* This,\r
- EFI_HANDLE Controller,\r
- EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath\r
- );\r
-\r
-/**\r
- Stop this driver on Controller.\r
-\r
- @param This Protocol instance pointer.\r
- @param Controller Handle of device to stop driver on\r
- @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
- children is zero stop the entire bus driver.\r
- @param ChildHandleBuffer List of Child Handles to Stop.\r
-\r
- @retval EFI_SUCCESS This driver is removed Controller.\r
- @retval other This driver could not be removed from this device.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalEfiDriverBindingStop(\r
- EFI_DRIVER_BINDING_PROTOCOL* This,\r
- EFI_HANDLE Controller,\r
- UINTN NumberOfChildren,\r
- EFI_HANDLE* ChildHandleBuffer\r
- );\r
-\r
-/**\r
- Retrieves a Unicode string that is the user readable name of the driver.\r
-\r
- This function retrieves the user readable name of a driver in the form of a\r
- Unicode string. If the driver specified by This has a user readable name in\r
- the language specified by Language, then a pointer to the driver name is\r
- returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
- by This does not support the language specified by Language,\r
- then EFI_UNSUPPORTED is returned.\r
-\r
- @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
- EFI_COMPONENT_NAME_PROTOCOL instance.\r
-\r
- @param Language[in] A pointer to a Null-terminated ASCII string\r
- array indicating the language. This is the\r
- language of the driver name that the caller is\r
- requesting, and it must match one of the\r
- languages specified in SupportedLanguages. The\r
- number of languages supported by a driver is up\r
- to the driver writer. Language is specified\r
- in RFC 4646 or ISO 639-2 language code format.\r
-\r
- @param DriverName[out] A pointer to the Unicode string to return.\r
- This Unicode string is the name of the\r
- driver specified by This in the language\r
- specified by Language.\r
-\r
- @retval EFI_SUCCESS The Unicode string for the Driver specified by\r
- This and the language specified by Language was\r
- returned in DriverName.\r
-\r
- @retval EFI_INVALID_PARAMETER Language is NULL.\r
-\r
- @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
-\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support\r
- the language specified by Language.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalEfiDriverComponentNameGetDriverName(\r
- EFI_COMPONENT_NAME_PROTOCOL* This,\r
- CHAR8* Language,\r
- CHAR16** DriverName\r
- );\r
-\r
-/**\r
- Retrieves a Unicode string that is the user readable name of the controller\r
- that is being managed by a driver.\r
-\r
- This function retrieves the user readable name of the controller specified by\r
- ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
- driver specified by This has a user readable name in the language specified by\r
- Language, then a pointer to the controller name is returned in ControllerName,\r
- and EFI_SUCCESS is returned. If the driver specified by This is not currently\r
- managing the controller specified by ControllerHandle and ChildHandle,\r
- then EFI_UNSUPPORTED is returned. If the driver specified by This does not\r
- support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
-\r
- @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
- EFI_COMPONENT_NAME_PROTOCOL instance.\r
-\r
- @param ControllerHandle[in] The handle of a controller that the driver\r
- specified by This is managing. This handle\r
- specifies the controller whose name is to be\r
- returned.\r
-\r
- @param ChildHandle[in] The handle of the child controller to retrieve\r
- the name of. This is an optional parameter that\r
- may be NULL. It will be NULL for device\r
- drivers. It will also be NULL for a bus drivers\r
- that wish to retrieve the name of the bus\r
- controller. It will not be NULL for a bus\r
- driver that wishes to retrieve the name of a\r
- child controller.\r
-\r
- @param Language[in] A pointer to a Null-terminated ASCII string\r
- array indicating the language. This is the\r
- language of the driver name that the caller is\r
- requesting, and it must match one of the\r
- languages specified in SupportedLanguages. The\r
- number of languages supported by a driver is up\r
- to the driver writer. Language is specified in\r
- RFC 4646 or ISO 639-2 language code format.\r
-\r
- @param ControllerName[out] A pointer to the Unicode string to return.\r
- This Unicode string is the name of the\r
- controller specified by ControllerHandle and\r
- ChildHandle in the language specified by\r
- Language from the point of view of the driver\r
- specified by This.\r
-\r
- @retval EFI_SUCCESS The Unicode string for the user readable name in\r
- the language specified by Language for the\r
- driver specified by This was returned in\r
- DriverName.\r
-\r
- @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
-\r
- @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
- EFI_HANDLE.\r
-\r
- @retval EFI_INVALID_PARAMETER Language is NULL.\r
-\r
- @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
-\r
- @retval EFI_UNSUPPORTED The driver specified by This is not currently\r
- managing the controller specified by\r
- ControllerHandle and ChildHandle.\r
-\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support\r
- the language specified by Language.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalEfiDriverComponentNameGetControllerName(\r
- EFI_COMPONENT_NAME_PROTOCOL* This,\r
- EFI_HANDLE ControllerHandle,\r
- EFI_HANDLE ChildHandle,\r
- CHAR8* Language,\r
- CHAR16** ControllerName\r
- );\r
-\r
-/**\r
- Retrieves a Unicode string that is the user readable name of the driver.\r
-\r
- This function retrieves the user readable name of a driver in the form of a\r
- Unicode string. If the driver specified by This has a user readable name in\r
- the language specified by Language, then a pointer to the driver name is\r
- returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
- by This does not support the language specified by Language,\r
- then EFI_UNSUPPORTED is returned.\r
-\r
- @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
- EFI_COMPONENT_NAME_PROTOCOL instance.\r
-\r
- @param Language[in] A pointer to a Null-terminated ASCII string\r
- array indicating the language. This is the\r
- language of the driver name that the caller is\r
- requesting, and it must match one of the\r
- languages specified in SupportedLanguages. The\r
- number of languages supported by a driver is up\r
- to the driver writer. Language is specified\r
- in RFC 4646 or ISO 639-2 language code format.\r
-\r
- @param DriverName[out] A pointer to the Unicode string to return.\r
- This Unicode string is the name of the\r
- driver specified by This in the language\r
- specified by Language.\r
-\r
- @retval EFI_SUCCESS The Unicode string for the Driver specified by\r
- This and the language specified by Language was\r
- returned in DriverName.\r
-\r
- @retval EFI_INVALID_PARAMETER Language is NULL.\r
-\r
- @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
-\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support\r
- the language specified by Language.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalEfiDriverComponentName2GetDriverName(\r
- EFI_COMPONENT_NAME2_PROTOCOL* This,\r
- CHAR8* Language,\r
- CHAR16** DriverName\r
- );\r
-\r
-/**\r
- Retrieves a Unicode string that is the user readable name of the controller\r
- that is being managed by a driver.\r
-\r
- This function retrieves the user readable name of the controller specified by\r
- ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
- driver specified by This has a user readable name in the language specified by\r
- Language, then a pointer to the controller name is returned in ControllerName,\r
- and EFI_SUCCESS is returned. If the driver specified by This is not currently\r
- managing the controller specified by ControllerHandle and ChildHandle,\r
- then EFI_UNSUPPORTED is returned. If the driver specified by This does not\r
- support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
-\r
- @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
- EFI_COMPONENT_NAME_PROTOCOL instance.\r
-\r
- @param ControllerHandle[in] The handle of a controller that the driver\r
- specified by This is managing. This handle\r
- specifies the controller whose name is to be\r
- returned.\r
-\r
- @param ChildHandle[in] The handle of the child controller to retrieve\r
- the name of. This is an optional parameter that\r
- may be NULL. It will be NULL for device\r
- drivers. It will also be NULL for a bus drivers\r
- that wish to retrieve the name of the bus\r
- controller. It will not be NULL for a bus\r
- driver that wishes to retrieve the name of a\r
- child controller.\r
-\r
- @param Language[in] A pointer to a Null-terminated ASCII string\r
- array indicating the language. This is the\r
- language of the driver name that the caller is\r
- requesting, and it must match one of the\r
- languages specified in SupportedLanguages. The\r
- number of languages supported by a driver is up\r
- to the driver writer. Language is specified in\r
- RFC 4646 or ISO 639-2 language code format.\r
-\r
- @param ControllerName[out] A pointer to the Unicode string to return.\r
- This Unicode string is the name of the\r
- controller specified by ControllerHandle and\r
- ChildHandle in the language specified by\r
- Language from the point of view of the driver\r
- specified by This.\r
-\r
- @retval EFI_SUCCESS The Unicode string for the user readable name in\r
- the language specified by Language for the\r
- driver specified by This was returned in\r
- DriverName.\r
-\r
- @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
-\r
- @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
- EFI_HANDLE.\r
-\r
- @retval EFI_INVALID_PARAMETER Language is NULL.\r
-\r
- @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
-\r
- @retval EFI_UNSUPPORTED The driver specified by This is not currently\r
- managing the controller specified by\r
- ControllerHandle and ChildHandle.\r
-\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support\r
- the language specified by Language.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalEfiDriverComponentName2GetControllerName(\r
- EFI_COMPONENT_NAME2_PROTOCOL* This,\r
- EFI_HANDLE ControllerHandle,\r
- EFI_HANDLE ChildHandle,\r
- CHAR8* Language,\r
- CHAR16** ControllerName\r
- );\r
-\r
-#endif //_OPAL_DRIVER_H_\r
+++ /dev/null
-/** @file\r
- Private structures and functions used within OPAL_DRIVER\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#ifndef _OPAL_DRIVER_PRIVATE_H_\r
-#define _OPAL_DRIVER_PRIVATE_H_\r
-#include "OpalDriver.h"\r
-\r
-#define OPAL_MSID_LENGHT 128\r
-\r
-#pragma pack(1)\r
-//\r
-// Structure that is used to represent an OPAL_DISK.\r
-//\r
-typedef struct {\r
- UINT32 MsidLength; // Byte length of MSID Pin for device\r
- UINT8 Msid[OPAL_MSID_LENGHT]; // MSID Pin for device\r
- EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *Sscp;\r
- UINT32 MediaId; // MediaId is used by Ssc Protocol.\r
- EFI_DEVICE_PATH_PROTOCOL *OpalDevicePath;\r
- UINT16 OpalBaseComId; // Opal SSC 1 base com id.\r
- OPAL_OWNER_SHIP Owner;\r
- OPAL_DISK_SUPPORT_ATTRIBUTE SupportedAttributes;\r
- TCG_LOCKING_FEATURE_DESCRIPTOR LockingFeature; // Locking Feature Descriptor retrieved from performing a Level 0 Discovery\r
-} OPAL_DISK;\r
-\r
-//\r
-// Device with block IO protocol\r
-//\r
-typedef struct _OPAL_DRIVER_DEVICE OPAL_DRIVER_DEVICE;\r
-\r
-struct _OPAL_DRIVER_DEVICE {\r
- OPAL_DRIVER_DEVICE *Next; ///< Linked list pointer\r
- EFI_HANDLE Handle; ///< Device handle\r
- OPAL_DISK OpalDisk; ///< User context\r
- CHAR16 *Name16; ///< Allocated/freed by UEFI Filter Driver at device creation/removal\r
- CHAR8 *NameZ; ///< Allocated/freed by UEFI Filter Driver at device creation/removal\r
- UINT32 MediaId; ///< Required parameter for EFI_STORAGE_SECURITY_COMMAND_PROTOCOL, from BLOCK_IO_MEDIA\r
-\r
- EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *Sscp; /// Device protocols consumed\r
- EFI_DEVICE_PATH_PROTOCOL *OpalDevicePath;\r
-};\r
-\r
-//\r
-// Opal Driver UEFI Driver Model\r
-//\r
-typedef struct {\r
- EFI_HANDLE Handle; ///< Driver image handle\r
- OPAL_DRIVER_DEVICE *DeviceList; ///< Linked list of controllers owned by this Driver\r
-} OPAL_DRIVER;\r
-#pragma pack()\r
-\r
-//\r
-// Retrieves a OPAL_DRIVER_DEVICE based on the pointer to its StorageSecurity protocol.\r
-//\r
-#define DRIVER_DEVICE_FROM_OPALDISK(OpalDiskPointer) (OPAL_DRIVER_DEVICE*)(BASE_CR(OpalDiskPointer, OPAL_DRIVER_DEVICE, OpalDisk))\r
-\r
-/**\r
- Get devcie list info.\r
-\r
- @retval return the device list pointer.\r
-**/\r
-OPAL_DRIVER_DEVICE*\r
-OpalDriverGetDeviceList(\r
- VOID\r
- );\r
-\r
-/**\r
- Get devcie name through the component name protocol.\r
-\r
- @param[in] Dev The device which need to get name.\r
-\r
- @retval TRUE Find the name for this device.\r
- @retval FALSE Not found the name for this device.\r
-**/\r
-BOOLEAN\r
-OpalDriverGetDriverDeviceName(\r
- OPAL_DRIVER_DEVICE *Dev\r
- );\r
-\r
-/**\r
- Get current device count.\r
-\r
- @retval return the current created device count.\r
-\r
-**/\r
-UINT8\r
-GetDeviceCount (\r
- VOID\r
- );\r
-\r
-#endif // _OPAL_DRIVER_P_H_\r
+++ /dev/null
-/** @file\r
- Implementation of the HII for the Opal UEFI Driver.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "OpalHii.h"\r
-#include "OpalDriver.h"\r
-#include "OpalHiiPrivate.h"\r
-\r
-//\r
-// This is the generated IFR binary Data for each formset defined in VFR.\r
-// This Data array is ready to be used as input of HiiAddPackages() to\r
-// create a packagelist (which contains Form packages, String packages, etc).\r
-//\r
-extern UINT8 OpalPasswordFormBin[];\r
-\r
-//\r
-// This is the generated String package Data for all .UNI files.\r
-// This Data array is ready to be used as input of HiiAddPackages() to\r
-// create a packagelist (which contains Form packages, String packages, etc).\r
-//\r
-extern UINT8 OpalPasswordDxeStrings[];\r
-\r
-CHAR16 OpalPasswordStorageName[] = L"OpalHiiConfig";\r
-\r
-EFI_HII_CONFIG_ACCESS_PROTOCOL gHiiConfigAccessProtocol;\r
-\r
-//\r
-// Handle to the list of HII packages (forms and strings) for this driver\r
-//\r
-EFI_HII_HANDLE gHiiPackageListHandle = NULL;\r
-\r
-//\r
-// Package List GUID containing all form and string packages\r
-//\r
-const EFI_GUID gHiiPackageListGuid = PACKAGE_LIST_GUID;\r
-const EFI_GUID gHiiSetupVariableGuid = SETUP_VARIABLE_GUID;\r
-\r
-//\r
-// Structure that contains state of the HII\r
-// This structure is updated by Hii.cpp and its contents\r
-// is rendered in the HII.\r
-//\r
-OPAL_HII_CONFIGURATION gHiiConfiguration;\r
-\r
-CHAR8 gHiiOldPassword[MAX_PASSWORD_CHARACTER_LENGTH] = {0};\r
-UINT32 gHiiOldPasswordLength = 0;\r
-\r
-//\r
-// The device path containing the VENDOR_DEVICE_PATH and EFI_DEVICE_PATH_PROTOCOL\r
-//\r
-HII_VENDOR_DEVICE_PATH gHiiVendorDevicePath = {\r
- {\r
- {\r
- HARDWARE_DEVICE_PATH,\r
- HW_VENDOR_DP,\r
- {\r
- (UINT8)(sizeof(VENDOR_DEVICE_PATH)),\r
- (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8)\r
- }\r
- },\r
- OPAL_PASSWORD_CONFIG_GUID\r
- },\r
- {\r
- END_DEVICE_PATH_TYPE,\r
- END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
- {\r
- (UINT8)(END_DEVICE_PATH_LENGTH),\r
- (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)\r
- }\r
- }\r
-};\r
-\r
-\r
-/**\r
- Sets the current system state of global config variables.\r
-\r
-**/\r
-VOID\r
-HiiSetCurrentConfiguration(\r
- VOID\r
- )\r
-{\r
- UINT32 PpStorageFlag;\r
- EFI_STRING NewString;\r
-\r
- gHiiConfiguration.NumDisks = GetDeviceCount();\r
-\r
- //\r
- // Update the BlockSID status string.\r
- //\r
- PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags ();\r
-\r
- if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) {\r
- NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_ENABLED), NULL);\r
- if (NewString == NULL) {\r
- DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));\r
- return;\r
- }\r
- } else {\r
- NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISABLED), NULL);\r
- if (NewString == NULL) {\r
- DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));\r
- return;\r
- }\r
- }\r
- HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS1), NewString, NULL);\r
- FreePool (NewString);\r
-\r
- if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) != 0) {\r
- NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID_TRUE), NULL);\r
- if (NewString == NULL) {\r
- DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));\r
- return;\r
- }\r
- } else {\r
- NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID_FALSE), NULL);\r
- if (NewString == NULL) {\r
- DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));\r
- return;\r
- }\r
- }\r
- HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS2), NewString, NULL);\r
- FreePool (NewString);\r
-\r
- if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) != 0) {\r
- NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_DISABLE_BLOCKSID_TRUE), NULL);\r
- if (NewString == NULL) {\r
- DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));\r
- return;\r
- }\r
- } else {\r
- NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_DISABLE_BLOCKSID_FALSE), NULL);\r
- if (NewString == NULL) {\r
- DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));\r
- return;\r
- }\r
- }\r
- HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS3), NewString, NULL);\r
- FreePool (NewString);\r
-}\r
-\r
-/**\r
- Install the HII related resources.\r
-\r
- @retval EFI_SUCCESS Install all the resources success.\r
- @retval other Error occur when install the resources.\r
-**/\r
-EFI_STATUS\r
-HiiInstall(\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HANDLE DriverHandle;\r
-\r
- //\r
- // Clear the global configuration.\r
- //\r
- ZeroMem(&gHiiConfiguration, sizeof(gHiiConfiguration));\r
-\r
- //\r
- // Obtain the driver handle that the BIOS assigned us\r
- //\r
- DriverHandle = HiiGetDriverImageHandleCB();\r
-\r
- //\r
- // Populate the config access protocol with the three functions we are publishing\r
- //\r
- gHiiConfigAccessProtocol.ExtractConfig = ExtractConfig;\r
- gHiiConfigAccessProtocol.RouteConfig = RouteConfig;\r
- gHiiConfigAccessProtocol.Callback = DriverCallback;\r
-\r
- //\r
- // Associate the required protocols with our driver handle\r
- //\r
- Status = gBS->InstallMultipleProtocolInterfaces(\r
- &DriverHandle,\r
- &gEfiHiiConfigAccessProtocolGuid,\r
- &gHiiConfigAccessProtocol, // HII callback\r
- &gEfiDevicePathProtocolGuid,\r
- &gHiiVendorDevicePath, // required for HII callback allow all disks to be shown in same hii\r
- NULL\r
- );\r
-\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- return OpalHiiAddPackages();\r
-}\r
-\r
-/**\r
- Install the HII form and string packages.\r
-\r
- @retval EFI_SUCCESS Install all the resources success.\r
- @retval EFI_OUT_OF_RESOURCES Out of resource error.\r
-**/\r
-EFI_STATUS\r
-OpalHiiAddPackages(\r
- VOID\r
- )\r
-{\r
- EFI_HANDLE DriverHandle;\r
- CHAR16 *NewString;\r
-\r
- DriverHandle = HiiGetDriverImageHandleCB();\r
-\r
- //\r
- // Publish the HII form and HII string packages\r
- //\r
- gHiiPackageListHandle = HiiAddPackages(\r
- &gHiiPackageListGuid,\r
- DriverHandle,\r
- OpalPasswordDxeStrings,\r
- OpalPasswordFormBin,\r
- (VOID*)NULL\r
- );\r
-\r
- //\r
- // Make sure the packages installed successfully\r
- //\r
- if (gHiiPackageListHandle == NULL) {\r
- DEBUG ((DEBUG_INFO, "OpalHiiAddPackages failed\n"));\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Update Version String in main window\r
- //\r
- NewString = HiiGetDriverNameCB ();\r
- if (HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_MAIN_OPAL_VERSION), NewString, NULL) == 0) {\r
- DEBUG ((DEBUG_INFO, "OpalHiiAddPackages: HiiSetString( ) failed\n"));\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Uninstall the HII capability.\r
-\r
- @retval EFI_SUCCESS Uninstall all the resources success.\r
- @retval others Other errors occur when unistall the hii resource.\r
-**/\r
-EFI_STATUS\r
-HiiUninstall(\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Remove the packages we've provided to the BIOS\r
- //\r
- HiiRemovePackages(gHiiPackageListHandle);\r
-\r
- //\r
- // Remove the protocols from our driver handle\r
- //\r
- Status = gBS->UninstallMultipleProtocolInterfaces(\r
- HiiGetDriverImageHandleCB(),\r
- &gEfiHiiConfigAccessProtocolGuid,\r
- &gHiiConfigAccessProtocol, // HII callback\r
- &gEfiDevicePathProtocolGuid,\r
- &gHiiVendorDevicePath, // required for HII callback\r
- NULL\r
- );\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_INFO, "Cannot uninstall Hii Protocols: %r\n", Status));\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Updates the main menu form.\r
-\r
- @retval EFI_SUCCESS update the main form success.\r
-**/\r
-EFI_STATUS\r
-HiiPopulateMainMenuForm (\r
- VOID\r
- )\r
-{\r
- UINT8 Index;\r
- CHAR8 *DiskName;\r
- EFI_STRING_ID DiskNameId;\r
- OPAL_DISK *OpalDisk;\r
-\r
- HiiSetCurrentConfiguration();\r
-\r
- gHiiConfiguration.SupportedDisks = 0;\r
-\r
- for (Index = 0; Index < gHiiConfiguration.NumDisks; Index++) {\r
- OpalDisk = HiiGetOpalDiskCB (Index);\r
- if ((OpalDisk != NULL) && OpalFeatureSupported (&OpalDisk->SupportedAttributes)) {\r
- gHiiConfiguration.SupportedDisks |= (1 << Index);\r
- DiskNameId = GetDiskNameStringId (Index);\r
- DiskName = HiiDiskGetNameCB (Index);\r
- if ((DiskName == NULL) || (DiskNameId == 0)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- HiiSetFormString(DiskNameId, DiskName);\r
- }\r
- }\r
-\r
- OpalHiiSetBrowserData ();\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Update the disk action info.\r
-\r
- @param ActionString\r
- @param SelectedAction\r
-\r
- @retval EFI_SUCCESS Uninstall all the resources success.\r
-**/\r
-EFI_STATUS\r
-HiiSelectDiskAction (\r
- CHAR8 *ActionString,\r
- UINT8 SelectedAction\r
- )\r
-{\r
- OPAL_DISK *OpalDisk;\r
- OPAL_DISK_ACTIONS AvailActions;\r
-\r
- OpalHiiGetBrowserData ();\r
-\r
- HiiSetFormString(STRING_TOKEN(STR_DISK_ACTION_LBL), ActionString);\r
- HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), " ");\r
-\r
- gHiiConfiguration.SelectedAction = SelectedAction;\r
- gHiiConfiguration.AvailableFields = 0;\r
-\r
- OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);\r
- if (OpalDisk == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (OpalSupportGetAvailableActions (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature, OpalDisk->Owner, &AvailActions) != TcgResultSuccess) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- switch (SelectedAction) {\r
- case HII_KEY_ID_GOTO_LOCK:\r
- case HII_KEY_ID_GOTO_UNLOCK:\r
- case HII_KEY_ID_GOTO_SET_ADMIN_PWD:\r
- case HII_KEY_ID_GOTO_SET_USER_PWD:\r
- case HII_KEY_ID_GOTO_SECURE_ERASE:\r
- case HII_KEY_ID_GOTO_DISABLE_USER:\r
- case HII_KEY_ID_GOTO_ENABLE_FEATURE: // User is required to enter Password to enable Feature\r
- gHiiConfiguration.AvailableFields |= HII_FIELD_PASSWORD;\r
- break;\r
-\r
- case HII_KEY_ID_GOTO_PSID_REVERT:\r
- gHiiConfiguration.AvailableFields |= HII_FIELD_PSID;\r
- break;\r
-\r
- case HII_KEY_ID_GOTO_REVERT:\r
- gHiiConfiguration.AvailableFields |= HII_FIELD_PASSWORD;\r
- gHiiConfiguration.AvailableFields |= HII_FIELD_KEEP_USER_DATA;\r
- if (AvailActions.RevertKeepDataForced) {\r
- gHiiConfiguration.AvailableFields |= HII_FIELD_KEEP_USER_DATA_FORCED;\r
- }\r
- break;\r
- }\r
-\r
- OpalHiiSetBrowserData ();\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Get disk name string id.\r
-\r
- @param DiskIndex The input disk index info.\r
-\r
- @retval The disk name string id.\r
-\r
-**/\r
-EFI_STRING_ID\r
-GetDiskNameStringId(\r
- UINT8 DiskIndex\r
- )\r
-{\r
- switch (DiskIndex) {\r
- case 0: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_0);\r
- case 1: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_1);\r
- case 2: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_2);\r
- case 3: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_3);\r
- case 4: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_4);\r
- case 5: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_5);\r
- }\r
- return 0;\r
-}\r
-\r
-/**\r
- This function processes the results of changes in configuration.\r
-\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Action Specifies the type of action taken by the browser.\r
- @param QuestionId A unique value which is sent to the original\r
- exporting driver so that it can identify the type\r
- of data to expect.\r
- @param Type The type of value for the question.\r
- @param Value A pointer to the data being sent to the original\r
- exporting driver.\r
- @param ActionRequest On return, points to the action requested by the\r
- callback function.\r
-\r
- @retval EFI_SUCCESS The callback successfully handled the action.\r
- @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
- variable and its data.\r
- @retval EFI_DEVICE_ERROR The variable could not be saved.\r
- @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
- callback.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DriverCallback(\r
- CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
- EFI_BROWSER_ACTION Action,\r
- EFI_QUESTION_ID QuestionId,\r
- UINT8 Type,\r
- EFI_IFR_TYPE_VALUE *Value,\r
- EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
- )\r
-{\r
- HII_KEY HiiKey;\r
- UINT8 HiiKeyId;\r
- UINT32 PpRequest;\r
-\r
- if (ActionRequest != NULL) {\r
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
- } else {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // If QuestionId is an auto-generated key (label, empty line, etc.), ignore it.\r
- //\r
- if ((QuestionId & HII_KEY_FLAG) == 0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- HiiKey.Raw = QuestionId;\r
- HiiKeyId = (UINT8) HiiKey.KeyBits.Id;\r
-\r
- if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
- switch (HiiKeyId) {\r
- case HII_KEY_ID_VAR_SUPPORTED_DISKS:\r
- DEBUG ((DEBUG_INFO, "HII_KEY_ID_VAR_SUPPORTED_DISKS\n"));\r
- return HiiPopulateMainMenuForm ();\r
-\r
- case HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS:\r
- return HiiPopulateDiskInfoForm();\r
- }\r
- } else if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
- switch (HiiKeyId) {\r
- case HII_KEY_ID_GOTO_DISK_INFO:\r
- return HiiSelectDisk((UINT8)HiiKey.KeyBits.Index);\r
-\r
- case HII_KEY_ID_GOTO_LOCK:\r
- return HiiSelectDiskAction("Action: Lock", HiiKeyId);\r
-\r
- case HII_KEY_ID_GOTO_UNLOCK:\r
- return HiiSelectDiskAction("Action: Unlock", HiiKeyId);\r
-\r
- case HII_KEY_ID_GOTO_SET_ADMIN_PWD:\r
- return HiiSelectDiskAction("Action: Set Administrator Password", HiiKeyId);\r
-\r
- case HII_KEY_ID_GOTO_SET_USER_PWD:\r
- return HiiSelectDiskAction("Action: Set User Password", HiiKeyId);\r
-\r
- case HII_KEY_ID_GOTO_SECURE_ERASE:\r
- return HiiSelectDiskAction("Action: Secure Erase", HiiKeyId);\r
-\r
- case HII_KEY_ID_GOTO_PSID_REVERT:\r
- return HiiSelectDiskAction("Action: Revert to Factory Defaults with PSID", HiiKeyId);\r
-\r
- case HII_KEY_ID_GOTO_REVERT:\r
- return HiiSelectDiskAction("Action: Revert to Factory Defaults", HiiKeyId);\r
-\r
- case HII_KEY_ID_GOTO_DISABLE_USER:\r
- return HiiSelectDiskAction("Action: Disable User", HiiKeyId);\r
-\r
- case HII_KEY_ID_GOTO_ENABLE_FEATURE:\r
- return HiiSelectDiskAction("Action: Enable Feature", HiiKeyId);\r
-\r
- case HII_KEY_ID_ENTER_PASSWORD:\r
- return HiiPasswordEntered(Value->string);\r
-\r
- case HII_KEY_ID_ENTER_PSID:\r
- return HiiPsidRevert(Value->string);\r
-\r
- }\r
- } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
- switch (HiiKeyId) {\r
- case HII_KEY_ID_BLOCKSID:\r
- switch (Value->u8) {\r
- case 0:\r
- PpRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;\r
- break;\r
-\r
- case 1:\r
- PpRequest = TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID;\r
- break;\r
-\r
- case 2:\r
- PpRequest = TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID;\r
- break;\r
-\r
- case 3:\r
- PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE;\r
- break;\r
-\r
- case 4:\r
- PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE;\r
- break;\r
-\r
- case 5:\r
- PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE;\r
- break;\r
-\r
- case 6:\r
- PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE;\r
- break;\r
-\r
- default:\r
- PpRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;\r
- DEBUG ((DEBUG_ERROR, "Invalid value input!\n"));\r
- break;\r
- }\r
- HiiSetBlockSidAction(PpRequest);\r
-\r
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
- return EFI_SUCCESS;\r
-\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-/**\r
- Update the global Disk index info.\r
-\r
- @param Index The input disk index info.\r
-\r
- @retval EFI_SUCCESS Update the disk index info success.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiSelectDisk(\r
- UINT8 Index\r
- )\r
-{\r
- OpalHiiGetBrowserData();\r
- gHiiConfiguration.SelectedDiskIndex = Index;\r
- OpalHiiSetBrowserData ();\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Draws the disk info form.\r
-\r
- @retval EFI_SUCCESS Draw the disk info success.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiPopulateDiskInfoForm(\r
- VOID\r
- )\r
-{\r
- OPAL_DISK* OpalDisk;\r
- OPAL_DISK_ACTIONS AvailActions;\r
- TCG_RESULT Ret;\r
- CHAR8 *DiskName;\r
-\r
- OpalHiiGetBrowserData();\r
-\r
- DiskName = HiiDiskGetNameCB (gHiiConfiguration.SelectedDiskIndex);\r
- if (DiskName == NULL) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- HiiSetFormString(STRING_TOKEN(STR_DISK_INFO_SELECTED_DISK_NAME), DiskName);\r
-\r
- ZeroMem(gHiiConfiguration.Psid, sizeof(gHiiConfiguration.Psid));\r
-\r
- gHiiConfiguration.SelectedDiskAvailableActions = HII_ACTION_NONE;\r
-\r
- OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);\r
-\r
- if (OpalDisk != NULL) {\r
- OpalDiskUpdateStatus (OpalDisk);\r
- Ret = OpalSupportGetAvailableActions(&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature, OpalDisk->Owner, &AvailActions);\r
- if (Ret == TcgResultSuccess) {\r
- //\r
- // Update actions, always allow PSID Revert\r
- //\r
- gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.PsidRevert == 1) ? HII_ACTION_PSID_REVERT : HII_ACTION_NONE;\r
-\r
- //\r
- // Always allow unlock to handle device migration\r
- //\r
- gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Unlock == 1) ? HII_ACTION_UNLOCK : HII_ACTION_NONE;\r
-\r
- if (!OpalFeatureEnabled (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) {\r
- if (OpalDisk->Owner == OpalOwnershipNobody) {\r
- gHiiConfiguration.SelectedDiskAvailableActions |= HII_ACTION_ENABLE_FEATURE;\r
-\r
- //\r
- // Update strings\r
- //\r
- HiiSetFormString( STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default");\r
- } else {\r
- DEBUG ((DEBUG_INFO, "Feature disabled but ownership != nobody\n"));\r
- }\r
- } else {\r
- gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Revert == 1) ? HII_ACTION_REVERT : HII_ACTION_NONE;\r
- gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.AdminPass == 1) ? HII_ACTION_SET_ADMIN_PWD : HII_ACTION_NONE;\r
- gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.UserPass == 1) ? HII_ACTION_SET_USER_PWD : HII_ACTION_NONE;\r
- gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.SecureErase == 1) ? HII_ACTION_SECURE_ERASE : HII_ACTION_NONE;\r
- gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.DisableUser == 1) ? HII_ACTION_DISABLE_USER : HII_ACTION_NONE;\r
-\r
- HiiSetFormString (STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default and Disable");\r
-\r
- //\r
- // Determine revert options for disk\r
- // Default initialize keep user Data to be true\r
- //\r
- gHiiConfiguration.KeepUserData = 1;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Pass the current configuration to the BIOS\r
- //\r
- OpalHiiSetBrowserData ();\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Reverts the Opal disk to factory default.\r
-\r
- @param PsidStringId The string id for the PSID info.\r
-\r
- @retval EFI_SUCCESS Do the required action success.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiPsidRevert(\r
- EFI_STRING_ID PsidStringId\r
- )\r
-{\r
- CHAR8 Response[DEFAULT_RESPONSE_SIZE];\r
- TCG_PSID Psid;\r
- OPAL_DISK *OpalDisk;\r
- TCG_RESULT Ret;\r
- OPAL_SESSION Session;\r
- CHAR16 *UnicodeStr;\r
- UINT8 TmpBuf[PSID_CHARACTER_STRING_END_LENGTH];\r
-\r
- Ret = TcgResultFailure;\r
-\r
- UnicodeStr = HiiGetString (gHiiPackageListHandle, PsidStringId, NULL);\r
- ZeroMem (TmpBuf, sizeof (TmpBuf));\r
- UnicodeStrToAsciiStrS (UnicodeStr, (CHAR8*)TmpBuf, PSID_CHARACTER_STRING_END_LENGTH);\r
- CopyMem (Psid.Psid, TmpBuf, PSID_CHARACTER_LENGTH);\r
- HiiSetString (gHiiPackageListHandle, PsidStringId, L"", NULL);\r
- ZeroMem (TmpBuf, sizeof (TmpBuf));\r
- ZeroMem (UnicodeStr, StrSize (UnicodeStr));\r
- FreePool (UnicodeStr);\r
-\r
- OpalDisk = HiiGetOpalDiskCB (gHiiConfiguration.SelectedDiskIndex);\r
- if (OpalDisk != NULL) {\r
- ZeroMem(&Session, sizeof(Session));\r
- Session.Sscp = OpalDisk->Sscp;\r
- Session.MediaId = OpalDisk->MediaId;\r
- Session.OpalBaseComId = OpalDisk->OpalBaseComId;\r
-\r
- Ret = OpalSupportPsidRevert(&Session, Psid.Psid, (UINT32)sizeof(Psid.Psid), OpalDisk->OpalDevicePath);\r
- }\r
-\r
- ZeroMem (Psid.Psid, PSID_CHARACTER_LENGTH);\r
-\r
- if (Ret == TcgResultSuccess) {\r
- AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "PSID Revert: Success" );\r
- } else {\r
- AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "PSID Revert: Failure" );\r
- }\r
-\r
- HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Set password for the disk.\r
-\r
- @param OpalDisk The disk need to set the password.\r
- @param Password The input password.\r
- @param PassLength The input password length.\r
-\r
- @retval EFI_SUCCESS Do the required action success.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiSetPassword(\r
- OPAL_DISK *OpalDisk,\r
- VOID *Password,\r
- UINT32 PassLength\r
- )\r
-{\r
- CHAR8 Response[DEFAULT_RESPONSE_SIZE];\r
- TCG_RESULT Ret;\r
- BOOLEAN ExistingPassword;\r
- OPAL_SESSION Session;\r
-\r
- ExistingPassword = FALSE;\r
-\r
- //\r
- // PassLength = 0 means check whether exist old password.\r
- //\r
- if (PassLength == 0) {\r
- ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));\r
- gHiiOldPasswordLength = 0;\r
-\r
- if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_ENABLE_FEATURE) {\r
- ExistingPassword = FALSE;\r
- } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_ADMIN_PWD) {\r
- ExistingPassword = OpalUtilAdminPasswordExists(OpalDisk->Owner, &OpalDisk->LockingFeature);\r
- } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {\r
- //\r
- // Set user Password option shall only be shown if an Admin Password exists\r
- // so a Password is always required (Admin or Existing User Password)\r
- //\r
- ExistingPassword = TRUE;\r
- }\r
-\r
- //\r
- // Return error if there is a previous Password\r
- // see UEFI 2.4 errata B, Figure 121. Password Flowchart\r
- //\r
- return ExistingPassword ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
- }\r
-\r
- ZeroMem(&Session, sizeof(Session));\r
- Session.Sscp = OpalDisk->Sscp;\r
- Session.MediaId = OpalDisk->MediaId;\r
- Session.OpalBaseComId = OpalDisk->OpalBaseComId;\r
-\r
- AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Failure");\r
- //\r
- // Password entered.\r
- // No current Owner, so set new Password, must be admin Password\r
- //\r
- if (OpalDisk->Owner == OpalOwnershipNobody) {\r
- Ret = OpalSupportEnableOpalFeature (&Session, OpalDisk->Msid, OpalDisk->MsidLength,Password, PassLength, OpalDisk->OpalDevicePath);\r
- if (Ret == TcgResultSuccess) {\r
- AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Success");\r
- }\r
-\r
- HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // 1st Password entered\r
- //\r
- if (OpalDisk->Owner == OpalOwnershipUnknown && gHiiOldPasswordLength == 0) {\r
-\r
- //\r
- // Unknown ownership - prompt for old Password, then new\r
- // old Password is not set yet - first time through\r
- // assume authority provided is admin1, overwritten if user1 authority works below\r
- //\r
- if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {\r
- //\r
- // First try to login as USER1 to Locking SP to see if we're simply updating its Password\r
- //\r
- Ret = OpalUtilVerifyPassword (&Session, Password, PassLength, OPAL_LOCKING_SP_USER1_AUTHORITY);\r
- if (Ret == TcgResultSuccess) {\r
- //\r
- // User1 worked so authority 1 means user 1\r
- //\r
- CopyMem(gHiiOldPassword, Password, PassLength);\r
- gHiiOldPasswordLength = PassLength;\r
-\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- //\r
- // Else try admin1 below\r
- //\r
- Ret = OpalUtilVerifyPassword (&Session, Password, PassLength, OPAL_LOCKING_SP_ADMIN1_AUTHORITY);\r
- if (Ret == TcgResultSuccess) {\r
- CopyMem(gHiiOldPassword, Password, PassLength);\r
- gHiiOldPasswordLength = PassLength;\r
-\r
- return EFI_SUCCESS;\r
- } else {\r
- DEBUG ((DEBUG_INFO, "start session with old PW failed - return EFI_NOT_READY - mistyped old PW\n"));\r
- HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), "Authentication Failure");\r
-\r
- ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));\r
- gHiiOldPasswordLength = 0;\r
-\r
- return EFI_NOT_READY;\r
- }\r
- }\r
-\r
- //\r
- // New Password entered\r
- //\r
- if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {\r
- Ret = OpalSupportSetPassword(\r
- &Session,\r
- gHiiOldPassword,\r
- gHiiOldPasswordLength,\r
- Password,\r
- PassLength,\r
- OpalDisk->OpalDevicePath,\r
- FALSE\r
- );\r
- } else {\r
- Ret = OpalSupportSetPassword(\r
- &Session,\r
- gHiiOldPassword,\r
- gHiiOldPasswordLength,\r
- Password,\r
- PassLength,\r
- OpalDisk->OpalDevicePath,\r
- TRUE\r
- );\r
- }\r
-\r
- if (Ret == TcgResultSuccess) {\r
- AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Success");\r
- }\r
-\r
- //\r
- // Reset old Password storage\r
- //\r
- ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));\r
- gHiiOldPasswordLength = 0;\r
-\r
- HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);\r
- return Ret == TcgResultSuccess ? EFI_SUCCESS : EFI_NOT_READY;\r
-}\r
-\r
-/**\r
- Secure Erases Opal Disk.\r
-\r
- @param OpalDisk The disk need to erase data.\r
- @param Password The input password.\r
- @param PassLength The input password length.\r
-\r
- @retval EFI_SUCCESS Do the required action success.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiSecureErase(\r
- OPAL_DISK *OpalDisk,\r
- const VOID *Password,\r
- UINT32 PassLength\r
- )\r
-{\r
- CHAR8 Response[DEFAULT_RESPONSE_SIZE];\r
- BOOLEAN PasswordFailed;\r
- TCG_RESULT Ret;\r
- OPAL_SESSION AdminSpSession;\r
-\r
- if (PassLength == 0) {\r
- return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password\r
- }\r
-\r
- ZeroMem(&AdminSpSession, sizeof(AdminSpSession));\r
- AdminSpSession.Sscp = OpalDisk->Sscp;\r
- AdminSpSession.MediaId = OpalDisk->MediaId;\r
- AdminSpSession.OpalBaseComId = OpalDisk->OpalBaseComId;\r
-\r
- Ret = OpalUtilSecureErase(&AdminSpSession, Password, PassLength, &PasswordFailed);\r
- if (Ret == TcgResultSuccess) {\r
- AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Secure Erase: Success" );\r
- } else {\r
- AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Secure Erase: Failure" );\r
- }\r
- HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);\r
-\r
- //\r
- // If Password failed, return invalid passowrd\r
- //\r
- if (PasswordFailed) {\r
- DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));\r
- return EFI_NOT_READY;\r
- }\r
-\r
- //\r
- // Indicates Password was valid and is not changing to UEFI\r
- // Response string will indicate action error\r
- //\r
- return EFI_DEVICE_ERROR;\r
-}\r
-\r
-\r
-/**\r
- Disables User for Opal Disk.\r
-\r
- @param OpalDisk The disk need to the action.\r
- @param Password The input password.\r
- @param PassLength The input password length.\r
-\r
- @retval EFI_SUCCESS Do the required action success.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiDisableUser(\r
- OPAL_DISK *OpalDisk,\r
- VOID *Password,\r
- UINT32 PassLength\r
- )\r
-{\r
- CHAR8 Response[ DEFAULT_RESPONSE_SIZE ];\r
- BOOLEAN PasswordFailed;\r
- TCG_RESULT Ret;\r
- OPAL_SESSION Session;\r
-\r
- if (PassLength == 0) {\r
- return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password\r
- }\r
-\r
- ZeroMem(&Session, sizeof(Session));\r
- Session.Sscp = OpalDisk->Sscp;\r
- Session.MediaId = OpalDisk->MediaId;\r
- Session.OpalBaseComId = OpalDisk->OpalBaseComId;\r
-\r
- Ret = OpalSupportDisableUser(&Session, Password, PassLength, &PasswordFailed, OpalDisk->OpalDevicePath);\r
- if (Ret == TcgResultSuccess) {\r
- AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Disable User: Success" );\r
- } else {\r
- AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Disable User: Failure" );\r
- }\r
- HiiSetFormString (STRING_TOKEN(STR_ACTION_STATUS), Response);\r
-\r
- //\r
- // If Password failed, return invalid passowrd\r
- //\r
- if (PasswordFailed) {\r
- DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));\r
- return EFI_NOT_READY;\r
- }\r
-\r
- //\r
- // Indicates Password was valid and is not changing to UEFI\r
- // Response string will indicate action error\r
- //\r
- return EFI_DEVICE_ERROR;\r
-}\r
-\r
-/**\r
- Revert Opal Disk as Admin1.\r
-\r
- @param OpalDisk The disk need to the action.\r
- @param Password The input password.\r
- @param PassLength The input password length.\r
- @param KeepUserData Whether need to keey user data.\r
-\r
- @retval EFI_SUCCESS Do the required action success.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiRevert(\r
- OPAL_DISK *OpalDisk,\r
- VOID *Password,\r
- UINT32 PassLength,\r
- BOOLEAN KeepUserData\r
- )\r
-{\r
- CHAR8 Response[ DEFAULT_RESPONSE_SIZE ];\r
- BOOLEAN PasswordFailed;\r
- TCG_RESULT Ret;\r
- OPAL_SESSION Session;\r
-\r
- if (PassLength == 0) {\r
- DEBUG ((DEBUG_INFO, "Returning error to indicate there is an existing Password\n"));\r
- // return error to indicate there is an existing Password\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- ZeroMem(&Session, sizeof(Session));\r
- Session.Sscp = OpalDisk->Sscp;\r
- Session.MediaId = OpalDisk->MediaId;\r
- Session.OpalBaseComId = OpalDisk->OpalBaseComId;\r
-\r
- Ret = OpalSupportRevert(\r
- &Session,\r
- KeepUserData,\r
- Password,\r
- PassLength,\r
- OpalDisk->Msid,\r
- OpalDisk->MsidLength,\r
- &PasswordFailed,\r
- OpalDisk->OpalDevicePath\r
- );\r
- if (Ret == TcgResultSuccess) {\r
- AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Revert: Success" );\r
- } else {\r
- AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Revert: Failure" );\r
- }\r
- HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);\r
-\r
- //\r
- // If Password failed, return invalid passowrd\r
- //\r
- if (PasswordFailed) {\r
- DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));\r
- return EFI_NOT_READY;\r
- }\r
-\r
- //\r
- // Indicates Password was valid and is not changing to UEFI\r
- // Response string will indicate action error\r
- //\r
- return EFI_DEVICE_ERROR;\r
-}\r
-\r
-/**\r
- Unlocks Opal Disk.\r
-\r
- @param OpalDisk The disk need to the action.\r
- @param Password The input password.\r
- @param PassLength The input password length.\r
-\r
- @retval EFI_SUCCESS Do the required action success.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiUnlock(\r
- OPAL_DISK *OpalDisk,\r
- VOID *Password,\r
- UINT32 PassLength\r
- )\r
-{\r
- CHAR8 Response[DEFAULT_RESPONSE_SIZE];\r
- TCG_RESULT Ret;\r
- OPAL_SESSION Session;\r
-\r
- if (PassLength == 0) {\r
- DEBUG ((DEBUG_INFO, "Returning error to indicate there is an existing Password\n"));\r
- return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password\r
- }\r
-\r
- ZeroMem(&Session, sizeof(Session));\r
- Session.Sscp = OpalDisk->Sscp;\r
- Session.MediaId = OpalDisk->MediaId;\r
- Session.OpalBaseComId = OpalDisk->OpalBaseComId;\r
-\r
- Ret = OpalSupportUnlock(&Session, Password, PassLength, OpalDisk->OpalDevicePath);\r
- if (Ret == TcgResultSuccess) {\r
- AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Unlock: Success" );\r
- } else {\r
- AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Unlock: Failure" );\r
- }\r
-\r
- HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);\r
-\r
- if (Ret == TcgResultSuccess) {\r
- DEBUG ((DEBUG_INFO, "returning error to indicate Password was correct but is not changing\n"));\r
- return EFI_DEVICE_ERROR;\r
- } else {\r
- DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));\r
- return EFI_NOT_READY;\r
- }\r
-}\r
-\r
-/**\r
- Use the input password to do the specified action.\r
-\r
- @param Str The input password saved in.\r
-\r
- @retval EFI_SUCCESS Do the required action success.\r
- @retval Others Other error occur.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiPasswordEntered(\r
- EFI_STRING_ID Str\r
- )\r
-{\r
- OPAL_DISK* OpalDisk;\r
- CHAR8 Password[MAX_PASSWORD_CHARACTER_LENGTH + 1];\r
- CHAR16* UniStr;\r
- UINT32 PassLength;\r
- EFI_STATUS Status;\r
-\r
- OpalHiiGetBrowserData();\r
-\r
- OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);\r
- if (OpalDisk == NULL) {\r
- DEBUG ((DEBUG_INFO, "ERROR: disk %u not found\n", gHiiConfiguration.SelectedDiskIndex));\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- if (Str == 0) {\r
- DEBUG ((DEBUG_INFO, "ERROR: str=NULL\n"));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- ZeroMem(Password, sizeof(Password));\r
-\r
- UniStr = HiiGetString(gHiiPackageListHandle, Str, NULL);\r
- if (UniStr == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- HiiSetString(gHiiPackageListHandle, Str, L"", NULL);\r
-\r
- PassLength = (UINT32) StrLen (UniStr);\r
- if (PassLength >= sizeof(Password)) {\r
- HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), "Password too long");\r
- ZeroMem (UniStr, StrSize (UniStr));\r
- FreePool(UniStr);\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
-\r
- UnicodeStrToAsciiStrS (UniStr, Password, sizeof (Password));\r
- ZeroMem (UniStr, StrSize (UniStr));\r
- FreePool(UniStr);\r
-\r
- if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_UNLOCK) {\r
- Status = HiiUnlock (OpalDisk, Password, PassLength);\r
- } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SECURE_ERASE) {\r
- Status = HiiSecureErase (OpalDisk, Password, PassLength);\r
- } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_DISABLE_USER) {\r
- Status = HiiDisableUser (OpalDisk, Password, PassLength);\r
- } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_REVERT) {\r
- if (OpalDisk->SupportedAttributes.PyriteSsc == 1 && OpalDisk->LockingFeature.MediaEncryption == 0) {\r
- //\r
- // For pyrite type device which also not supports media encryption, it not accept "Keep User Data" parameter.\r
- // So here hardcode a FALSE for this case.\r
- //\r
- Status = HiiRevert(OpalDisk, Password, PassLength, FALSE);\r
- } else {\r
- Status = HiiRevert(OpalDisk, Password, PassLength, gHiiConfiguration.KeepUserData);\r
- }\r
- } else {\r
- Status = HiiSetPassword(OpalDisk, Password, PassLength);\r
- }\r
-\r
- ZeroMem (Password, sizeof (Password));\r
-\r
- OpalHiiSetBrowserData ();\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Send BlockSid request through TPM physical presence module.\r
-\r
- @param PpRequest TPM physical presence operation request.\r
-\r
- @retval EFI_SUCCESS Do the required action success.\r
- @retval Others Other error occur.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiSetBlockSidAction (\r
- IN UINT32 PpRequest\r
- )\r
-{\r
- UINT32 ReturnCode;\r
- EFI_STATUS Status;\r
-\r
- ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (PpRequest, 0);\r
- if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {\r
- Status = EFI_SUCCESS;\r
- } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {\r
- Status = EFI_UNSUPPORTED;\r
- } else {\r
- Status = EFI_DEVICE_ERROR;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- This function processes the results of changes in configuration.\r
-\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Configuration A null-terminated Unicode string in <ConfigResp>\r
- format.\r
- @param Progress A pointer to a string filled in with the offset of\r
- the most recent '&' before the first failing\r
- name/value pair (or the beginning of the string if\r
- the failure is in the first name/value pair) or\r
- the terminating NULL if all was successful.\r
-\r
- @retval EFI_SUCCESS The Results is processed successfully.\r
- @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
- driver.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-RouteConfig(\r
- CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
- CONST EFI_STRING Configuration,\r
- EFI_STRING *Progress\r
- )\r
-{\r
- if (Configuration == NULL || Progress == NULL) {\r
- return (EFI_INVALID_PARAMETER);\r
- }\r
-\r
- *Progress = Configuration;\r
- if (!HiiIsConfigHdrMatch (Configuration, &gHiiSetupVariableGuid, OpalPasswordStorageName)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- *Progress = Configuration + StrLen (Configuration);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function allows a caller to extract the current configuration for one\r
- or more named elements from the target driver.\r
-\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Request A null-terminated Unicode string in\r
- <ConfigRequest> format.\r
- @param Progress On return, points to a character in the Request\r
- string. Points to the string's null terminator if\r
- request was successful. Points to the most recent\r
- '&' before the first failing name/value pair (or\r
- the beginning of the string if the failure is in\r
- the first name/value pair) if the request was not\r
- successful.\r
- @param Results A null-terminated Unicode string in\r
- <ConfigAltResp> format which has all values filled\r
- in for the names in the Request string. String to\r
- be allocated by the called function.\r
-\r
- @retval EFI_SUCCESS The Results is filled with the requested values.\r
- @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
- @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
- driver.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ExtractConfig(\r
- CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
- CONST EFI_STRING Request,\r
- EFI_STRING *Progress,\r
- EFI_STRING *Results\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_STRING ConfigRequest;\r
- EFI_STRING ConfigRequestHdr;\r
- UINTN BufferSize;\r
- UINTN Size;\r
- BOOLEAN AllocatedRequest;\r
- EFI_HANDLE DriverHandle;\r
-\r
- //\r
- // Check for valid parameters\r
- //\r
- if (Progress == NULL || Results == NULL) {\r
- return (EFI_INVALID_PARAMETER);\r
- }\r
-\r
- *Progress = Request;\r
- if ((Request != NULL) &&\r
- !HiiIsConfigHdrMatch (Request, &gHiiSetupVariableGuid, OpalPasswordStorageName)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- AllocatedRequest = FALSE;\r
- BufferSize = sizeof (OPAL_HII_CONFIGURATION);\r
- ConfigRequest = Request;\r
- if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
- //\r
- // Request has no request element, construct full request string.\r
- // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
- // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
- //\r
- DriverHandle = HiiGetDriverImageHandleCB();\r
- ConfigRequestHdr = HiiConstructConfigHdr (&gHiiSetupVariableGuid, OpalPasswordStorageName, DriverHandle);\r
- Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
- ConfigRequest = AllocateZeroPool (Size);\r
- if (ConfigRequest == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- AllocatedRequest = TRUE;\r
- UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
- FreePool (ConfigRequestHdr);\r
- }\r
-\r
- //\r
- // Convert Buffer Data to <ConfigResp> by helper function BlockToConfig( )\r
- //\r
- Status = gHiiConfigRouting->BlockToConfig(\r
- gHiiConfigRouting,\r
- ConfigRequest,\r
- (UINT8*)&gHiiConfiguration,\r
- sizeof(OPAL_HII_CONFIGURATION),\r
- Results,\r
- Progress\r
- );\r
-\r
- //\r
- // Free the allocated config request string.\r
- //\r
- if (AllocatedRequest) {\r
- FreePool (ConfigRequest);\r
- ConfigRequest = NULL;\r
- }\r
-\r
- //\r
- // Set Progress string to the original request string.\r
- //\r
- if (Request == NULL) {\r
- *Progress = NULL;\r
- } else if (StrStr (Request, L"OFFSET") == NULL) {\r
- *Progress = Request + StrLen (Request);\r
- }\r
-\r
- return (Status);\r
-}\r
-\r
-\r
-/**\r
-\r
- Pass the current system state to the bios via the hii_G_Configuration.\r
-\r
-**/\r
-VOID\r
-OpalHiiSetBrowserData (\r
- VOID\r
- )\r
-{\r
- HiiSetBrowserData(\r
- &gHiiSetupVariableGuid,\r
- (CHAR16*)L"OpalHiiConfig",\r
- sizeof(gHiiConfiguration),\r
- (UINT8*)&gHiiConfiguration,\r
- NULL\r
- );\r
-}\r
-\r
-\r
-/**\r
-\r
- Populate the hii_g_Configuraton with the browser Data.\r
-\r
-**/\r
-VOID\r
-OpalHiiGetBrowserData (\r
- VOID\r
- )\r
-{\r
- HiiGetBrowserData(\r
- &gHiiSetupVariableGuid,\r
- (CHAR16*)L"OpalHiiConfig",\r
- sizeof(gHiiConfiguration),\r
- (UINT8*)&gHiiConfiguration\r
- );\r
-}\r
-\r
-/**\r
- Set a string Value in a form.\r
-\r
- @param DestStringId The stringid which need to update.\r
- @param SrcAsciiStr The string nned to update.\r
-\r
- @retval EFI_SUCCESS Do the required action success.\r
- @retval Others Other error occur.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiSetFormString(\r
- EFI_STRING_ID DestStringId,\r
- CHAR8 *SrcAsciiStr\r
- )\r
-{\r
- UINT32 Len;\r
- UINT32 UniSize;\r
- CHAR16* UniStr;\r
-\r
- //\r
- // Determine the Length of the sting\r
- //\r
- Len = ( UINT32 )AsciiStrLen( SrcAsciiStr );\r
-\r
- //\r
- // Allocate space for the unicode string, including terminator\r
- //\r
- UniSize = (Len + 1) * sizeof(CHAR16);\r
- UniStr = (CHAR16*)AllocateZeroPool(UniSize);\r
-\r
- //\r
- // Copy into unicode string, then copy into string id\r
- //\r
- AsciiStrToUnicodeStrS ( SrcAsciiStr, UniStr, Len + 1);\r
-\r
- //\r
- // Update the string in the form\r
- //\r
- if (HiiSetString(gHiiPackageListHandle, DestStringId, UniStr, NULL) == 0) {\r
- DEBUG ((DEBUG_INFO, "HiiSetFormString( ) failed\n"));\r
- FreePool(UniStr);\r
- return (EFI_OUT_OF_RESOURCES);\r
- }\r
-\r
- //\r
- // Free the memory\r
- //\r
- FreePool(UniStr);\r
-\r
- return (EFI_SUCCESS);\r
-}\r
-\r
-/**\r
- Initialize the Opal disk base on the hardware info get from device.\r
-\r
- @param Dev The Opal device.\r
-\r
- @retval EFI_SUCESS Initialize the device success.\r
- @retval EFI_DEVICE_ERROR Get info from device failed.\r
-\r
-**/\r
-EFI_STATUS\r
-OpalDiskInitialize (\r
- IN OPAL_DRIVER_DEVICE *Dev\r
- )\r
-{\r
- TCG_RESULT TcgResult;\r
- OPAL_SESSION Session;\r
-\r
- ZeroMem(&Dev->OpalDisk, sizeof(OPAL_DISK));\r
- Dev->OpalDisk.Sscp = Dev->Sscp;\r
- Dev->OpalDisk.MediaId = Dev->MediaId;\r
- Dev->OpalDisk.OpalDevicePath = Dev->OpalDevicePath;\r
-\r
- ZeroMem(&Session, sizeof(Session));\r
- Session.Sscp = Dev->Sscp;\r
- Session.MediaId = Dev->MediaId;\r
-\r
- TcgResult = OpalGetSupportedAttributesInfo (&Session, &Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.OpalBaseComId);\r
- if (TcgResult != TcgResultSuccess) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
-\r
- TcgResult = OpalUtilGetMsid (&Session, Dev->OpalDisk.Msid, OPAL_MSID_LENGHT, &Dev->OpalDisk.MsidLength);\r
- if (TcgResult != TcgResultSuccess) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return OpalDiskUpdateStatus (&Dev->OpalDisk);\r
-}\r
-\r
-/**\r
- Update the device info.\r
-\r
- @param OpalDisk The Opal device.\r
-\r
- @retval EFI_SUCESS Initialize the device success.\r
- @retval EFI_DEVICE_ERROR Get info from device failed.\r
- @retval EFI_INVALID_PARAMETER Not get Msid info before get ownership info.\r
-\r
-**/\r
-EFI_STATUS\r
-OpalDiskUpdateStatus (\r
- OPAL_DISK *OpalDisk\r
- )\r
-{\r
- TCG_RESULT TcgResult;\r
- OPAL_SESSION Session;\r
-\r
- ZeroMem(&Session, sizeof(Session));\r
- Session.Sscp = OpalDisk->Sscp;\r
- Session.MediaId = OpalDisk->MediaId;\r
- Session.OpalBaseComId = OpalDisk->OpalBaseComId;\r
-\r
- TcgResult = OpalGetLockingInfo(&Session, &OpalDisk->LockingFeature);\r
- if (TcgResult != TcgResultSuccess) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- if (OpalDisk->MsidLength == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- } else {\r
- //\r
- // Base on the Msid info to get the ownership, so Msid info must get first.\r
- //\r
- OpalDisk->Owner = OpalUtilDetermineOwnership(&Session, OpalDisk->Msid, OpalDisk->MsidLength);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
+++ /dev/null
-/** @file\r
- Public Header file of HII library used by Opal UEFI Driver.\r
- Defines required callbacks of Opal HII library.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#ifndef _OPAL_HII_H_\r
-#define _OPAL_HII_H_\r
-\r
-#include <Library/OpalPasswordSupportLib.h>\r
-#include <OpalDriverPrivate.h>\r
-\r
-#define DEFAULT_RESPONSE_SIZE 200\r
-\r
-/**\r
- Get the driver image handle.\r
-\r
- @retval the driver image handle.\r
-\r
-**/\r
-EFI_HANDLE\r
-HiiGetDriverImageHandleCB(\r
- VOID\r
- );\r
-\r
-/**\r
- Install the HII form and string packages.\r
-\r
- @retval EFI_SUCCESS Install all the resources success.\r
- @retval EFI_OUT_OF_RESOURCES Out of resource error.\r
-**/\r
-EFI_STATUS\r
-OpalHiiAddPackages(\r
- VOID\r
- );\r
-\r
-/**\r
- Check whether enable feature or not.\r
-\r
- @retval Return the disk number.\r
-\r
-**/\r
-UINT8\r
-HiiGetNumConfigRequiredOpalDisksCB(\r
- VOID\r
- );\r
-\r
-/**\r
- Returns the driver name.\r
-\r
- @retval Returns the driver name.\r
-\r
-**/\r
-CHAR16*\r
-HiiGetDriverNameCB(\r
- VOID\r
- );\r
-\r
-/**\r
- Returns the opaque pointer to a physical disk context.\r
-\r
- @param DiskIndex Input the disk index.\r
-\r
- @retval The device pointer.\r
-\r
-**/\r
-OPAL_DISK*\r
-HiiGetOpalDiskCB(\r
- UINT8 DiskIndex\r
- );\r
-\r
-/**\r
- Returns the disk name.\r
-\r
- @param DiskIndex Input the disk index.\r
-\r
- @retval Returns the disk name.\r
-\r
-**/\r
-CHAR8*\r
-HiiDiskGetNameCB(\r
- UINT8 DiskIndex\r
- );\r
-\r
-/**\r
- Set a string Value in a form.\r
-\r
- @param DestStringId The stringid which need to update.\r
- @param SrcAsciiStr The string nned to update.\r
-\r
- @retval EFI_SUCCESS Do the required action success.\r
- @retval Others Other error occur.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiSetFormString(\r
- EFI_STRING_ID DestStringId,\r
- CHAR8 *SrcAsciiStr\r
- );\r
-\r
-/**\r
- Install the HII related resources.\r
-\r
- @retval EFI_SUCCESS Install all the resources success.\r
- @retval other Error occur when install the resources.\r
-**/\r
-EFI_STATUS\r
-HiiInstall(\r
- VOID\r
- );\r
-\r
-/**\r
- Uninstall the HII capability.\r
-\r
- @retval EFI_SUCCESS Uninstall all the resources success.\r
- @retval others Other errors occur when unistall the hii resource.\r
-**/\r
-EFI_STATUS\r
-HiiUninstall(\r
- VOID\r
- );\r
-\r
-/**\r
- Initialize the Opal disk base on the hardware info get from device.\r
-\r
- @param Dev The Opal device.\r
-\r
- @retval EFI_SUCESS Initialize the device success.\r
- @retval EFI_DEVICE_ERROR Get info from device failed.\r
-\r
-**/\r
-EFI_STATUS\r
-OpalDiskInitialize (\r
- IN OPAL_DRIVER_DEVICE *Dev\r
- );\r
-\r
-#endif // _HII_H_\r
+++ /dev/null
-/** @file\r
- Callbacks required by the HII of the Opal UEFI Driver to help display\r
- Opal device information and to send password to SMM handler.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "OpalHii.h"\r
-#include "OpalDriver.h"\r
-#include "OpalDriverPrivate.h"\r
-\r
-/**\r
- Get Opal var name.\r
- The return Value must be freed by caller if not NULL\r
-\r
- @param OpalDisk The disk.\r
- @param Prefix The prefix string.\r
-\r
- @retval The var name string.\r
-\r
-**/\r
-CHAR16*\r
-OpalDriverGetOpalVarName(\r
- OPAL_DISK *OpalDisk,\r
- const CHAR16 *Prefix\r
- )\r
-{\r
- OPAL_DRIVER_DEVICE* Dev;\r
- UINTN PrefixLen;\r
- UINTN NameLen;\r
- UINTN VarNameLen;\r
- CHAR16* VarName;\r
-\r
- Dev = DRIVER_DEVICE_FROM_OPALDISK(OpalDisk);\r
- if (Dev == NULL) {\r
- return NULL;\r
- }\r
-\r
- PrefixLen = StrLen(Prefix);\r
-\r
- NameLen = 0;\r
- if (Dev->Name16 != NULL) {\r
- NameLen = StrLen(Dev->Name16);\r
- }\r
-\r
- VarNameLen = PrefixLen + NameLen;\r
-\r
- VarName = (CHAR16*)AllocateZeroPool((VarNameLen + 1) * sizeof(CHAR16));\r
- if (VarName == NULL) {\r
- return NULL;\r
- }\r
-\r
- CopyMem(VarName, Prefix, PrefixLen * sizeof(CHAR16));\r
- if (Dev->Name16 != NULL) {\r
- CopyMem(VarName + PrefixLen, Dev->Name16, NameLen * sizeof(CHAR16));\r
- }\r
- VarName[VarNameLen] = 0;\r
-\r
- return VarName;\r
-}\r
-\r
-/**\r
- Get the driver image handle.\r
-\r
- @retval the driver image handle.\r
-\r
-**/\r
-EFI_HANDLE\r
-HiiGetDriverImageHandleCB(\r
- VOID\r
- )\r
-{\r
- return gImageHandle;\r
-}\r
-\r
-/**\r
- Check whether enable feature or not.\r
-\r
- @retval Return the disk number.\r
-\r
-**/\r
-UINT8\r
-HiiGetNumConfigRequiredOpalDisksCB(\r
- VOID\r
- )\r
-{\r
- UINT8 NumDisks;\r
- UINT8 NumLockedOpalDisks;\r
- OPAL_DISK *OpalDisk;\r
- UINT8 Index;\r
-\r
- NumLockedOpalDisks = 0;\r
-\r
- NumDisks = GetDeviceCount();\r
-\r
- for (Index = 0; Index < NumDisks; Index++) {\r
- OpalDisk = HiiGetOpalDiskCB(Index);\r
-\r
- if (OpalDisk != NULL) {\r
- if (!OpalFeatureEnabled (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) {\r
- DEBUG ((DEBUG_INFO, "Ignoring disk %u because feature is disabled or health has already been inspected\n", Index));\r
- } else if (OpalDeviceLocked (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) {\r
- NumLockedOpalDisks++;\r
- }\r
- }\r
- }\r
-\r
- return NumLockedOpalDisks;\r
-}\r
-\r
-\r
-\r
-/**\r
- Returns the opaque pointer to a physical disk context.\r
-\r
- @param DiskIndex Input the disk index.\r
-\r
- @retval The device pointer.\r
-\r
-**/\r
-VOID *\r
-HiiGetDiskContextCB(\r
- UINT8 DiskIndex\r
- )\r
-{\r
- OPAL_DRIVER_DEVICE* Dev;\r
- UINT8 CurrentDisk;\r
-\r
- Dev = OpalDriverGetDeviceList();\r
- CurrentDisk = 0;\r
-\r
- if (DiskIndex >= GetDeviceCount()) {\r
- return NULL;\r
- }\r
-\r
- while (Dev != NULL) {\r
- if (CurrentDisk == DiskIndex) {\r
- return Dev;\r
- } else {\r
- Dev = Dev->Next;\r
- CurrentDisk++;\r
- }\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-/**\r
- Returns the opaque pointer to a physical disk context.\r
-\r
- @param DiskIndex Input the disk index.\r
-\r
- @retval The device pointer.\r
-\r
-**/\r
-OPAL_DISK*\r
-HiiGetOpalDiskCB(\r
- UINT8 DiskIndex\r
- )\r
-{\r
- VOID *Ctx;\r
- OPAL_DRIVER_DEVICE *Tmp;\r
-\r
- Ctx = HiiGetDiskContextCB (DiskIndex);\r
-\r
- if (Ctx == NULL) {\r
- return NULL;\r
- }\r
-\r
- Tmp = (OPAL_DRIVER_DEVICE*) Ctx;\r
-\r
- return &Tmp->OpalDisk;\r
-}\r
-\r
-/**\r
- Returns the disk name.\r
-\r
- @param DiskIndex Input the disk index.\r
-\r
- @retval Returns the disk name.\r
-\r
-**/\r
-CHAR8*\r
-HiiDiskGetNameCB(\r
- UINT8 DiskIndex\r
- )\r
-{\r
- OPAL_DRIVER_DEVICE* Ctx;\r
-\r
- Ctx = (OPAL_DRIVER_DEVICE*) HiiGetDiskContextCB (DiskIndex);\r
-\r
- if (Ctx != NULL) {\r
- if (Ctx->NameZ == NULL) {\r
- OpalDriverGetDriverDeviceName (Ctx);\r
- }\r
- return Ctx->NameZ;\r
- }\r
- return NULL;\r
-}\r
-\r
-/**\r
- Returns the driver name.\r
-\r
- @retval Returns the driver name.\r
-\r
-**/\r
-CHAR16*\r
-HiiGetDriverNameCB(\r
- VOID\r
- )\r
-{\r
- return (CHAR16*)EFI_DRIVER_NAME_UNICODE;\r
-}\r
+++ /dev/null
-// /** @file\r
-//\r
-// String definitions for Setup formset.\r
-//\r
-// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-//\r
-// This program and the accompanying materials\r
-// are licensed and made available under the terms and conditions of the BSD License\r
-// which accompanies this distribution. The full text of the license may be found at\r
-// http://opensource.org/licenses/bsd-license.php\r
-//\r
-// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-//\r
-// **/\r
-\r
-/=#\r
-///////////////////////////////// GENERIC DEFINITIONS /////////////////////////////////\r
-#langdef en-US "English"\r
-#string STR_NULL #language en-US " "\r
-\r
-///////////////////////////////// FORM SET /////////////////////////////////\r
-#string STR_FORM_SET_HELP #language en-US "Manage Opal disks"\r
-\r
-///////////////////////////////// MULTIPLE FORMS /////////////////////////////////\r
-#string STR_OPAL #language en-US "Opal"\r
-#string STR_MAIN_OPAL_VERSION #language en-US "Version 00.0.0.0000"\r
-\r
-///////////////////////////////// MAIN MENU FORM /////////////////////////////////\r
-#string STR_MAIN_PHY_DISKS_LBL #language en-US "Physical Disks:"\r
-#string STR_MAIN_LOCKED_DISKS_LBL #language en-US "Locked Disks:"\r
-\r
-#string STR_MAIN_GOTO_DISK_INFO_0 #language en-US " "\r
-#string STR_MAIN_GOTO_DISK_INFO_1 #language en-US " "\r
-#string STR_MAIN_GOTO_DISK_INFO_2 #language en-US " "\r
-#string STR_MAIN_GOTO_DISK_INFO_3 #language en-US " "\r
-#string STR_MAIN_GOTO_DISK_INFO_4 #language en-US " "\r
-#string STR_MAIN_GOTO_DISK_INFO_5 #language en-US " "\r
-\r
-#string STR_MAIN_GOTO_DISK_INFO_HELP #language en-US "Select to see Opal disk actions"\r
-#string STR_MAIN_GOTO_DISK_HEALTH_HELP #language en-US "Select disk to unlock"\r
-\r
-#string STR_MAIN_NO_DISKS_PRESENT_LBL #language en-US "No disks connected to system"\r
-\r
-///////////////////////////////// DISK INFO MENU FORM /////////////////////////////////\r
-#string STR_DISK_INFO_SELECTED_DISK_NAME #language en-US " "\r
-\r
-#string STR_DISK_INFO_LOCK #language en-US "Lock"\r
-#string STR_DISK_INFO_UNLOCK #language en-US "Unlock"\r
-#string STR_DISK_INFO_SET_ADMIN_PSWD #language en-US "Update Drive Admin Password"\r
-#string STR_DISK_INFO_SET_USER_PSWD #language en-US "Set Drive User Password"\r
-#string STR_DISK_INFO_SECURE_ERASE #language en-US "Secure Erase User Data"\r
-#string STR_DISK_INFO_PSID_REVERT #language en-US "PSID Revert to factory default"\r
-#string STR_DISK_INFO_REVERT #language en-US "Admin Revert to factory default and Disable"\r
-#string STR_DISK_INFO_DISABLE_USER #language en-US "Disable User"\r
-#string STR_DISK_INFO_ENABLE_FEATURE #language en-US "Enable Feature"\r
-#string STR_DISK_INFO_ENABLE_BLOCKSID #language en-US "TCG Storage Action"\r
-#string STR_ENABLED #language en-US "Enable BlockSID"\r
-#string STR_DISABLED #language en-US "Disable BlockSID"\r
-\r
-#string STR_NONE #language en-US "None"\r
-#string STR_DISK_INFO_ENABLE_BLOCKSID_TRUE #language en-US "Require physical presence when remote enable BlockSID"\r
-#string STR_DISK_INFO_ENABLE_BLOCKSID_FALSE #language en-US "Not require physical presence when remote enable BlockSID"\r
-#string STR_DISK_INFO_DISABLE_BLOCKSID_TRUE #language en-US "Require physical presence when remote disable BlockSID"\r
-#string STR_DISK_INFO_DISABLE_BLOCKSID_FALSE #language en-US "Not require physical presence when remote disable BlockSID"\r
-\r
-#string STR_BLOCKSID_STATUS_HELP #language en-US "BlockSID action change status"\r
-#string STR_BLOCKSID_STATUS #language en-US "Current BlockSID Status:"\r
-#string STR_BLOCKSID_STATUS1 #language en-US ""\r
-#string STR_BLOCKSID_STATUS2 #language en-US ""\r
-#string STR_BLOCKSID_STATUS3 #language en-US ""\r
-\r
-#string STR_DISK_INFO_GOTO_LOCK_HELP #language en-US "Lock the disk"\r
-#string STR_DISK_INFO_GOTO_UNLOCK_HELP #language en-US "Unlock the disk"\r
-#string STR_DISK_INFO_GOTO_SET_ADMIN_PSWD_HELP #language en-US "Set password for the administrator"\r
-#string STR_DISK_INFO_GOTO_SET_USER_PSWD_HELP #language en-US "Set password for User 1"\r
-#string STR_DISK_INFO_GOTO_SECURE_ERASE_HELP #language en-US "Securely erase the disk"\r
-#string STR_DISK_INFO_GOTO_PSID_REVERT_HELP #language en-US "Revert the disk to factory defaults"\r
-#string STR_DISK_INFO_GOTO_DISABLE_USER_HELP #language en-US "Disable User"\r
-#string STR_DISK_INFO_GOTO_ENABLE_FEATURE_HELP #language en-US "Enable Feature"\r
-#string STR_DISK_INFO_GOTO_ENABLE_BLOCKSID_HELP #language en-US "Change BlockSID actions, includes enable or disable BlockSID, Require or not require physical presence when remote enable or disable BlockSID"\r
-\r
-///////////////////////////////// DISK ACTION MENU FORM /////////////////////////////////\r
-#string STR_DISK_ACTION_LBL #language en-US " "\r
-\r
-#string STR_PASSWORD_PROMPT #language en-US "Enter Password"\r
-#string STR_PASSWORD_HELP #language en-US "Password must be between 6 and 20 characters"\r
-\r
-#string STR_REVERT_PROMPT #language en-US "Enter PSID"\r
-#string STR_REVERT_HELP #language en-US "PSID is a 32 character case sensitive value"\r
-#string STR_ACTION_STATUS #language en-US " "\r
-\r
-#string STR_PASSWORD_SUBMIT #language en-US "Submit Password Changes"\r
-#string STR_PASSWORD_SUBMIT_HELP #language en-US "Submits Password Changes (new and update) after passwords have been entered"\r
-\r
-#string STR_GOTO_HOME #language en-US "Main Menu"\r
-#string STR_GOTO_HOME_HELP #language en-US "Return to the main menu"\r
-\r
-#string STR_KEEP_USER_DATA_PROMPT #language en-US "Keep User Data"\r
-#string STR_KEEP_USER_DATA_HELP #language en-US "Checkmark to keep user data, otherwise data will be lost"\r
-\r
-#string STR_OK #language en-US "OK"\r
-\r
+++ /dev/null
-/** @file\r
- Defines Opal HII form ids, structures and values.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-\r
-#ifndef _OPAL_HII_FORM_VALUES_H_\r
-#define _OPAL_HII_FORM_VALUES_H_\r
-\r
-// Maximum Opal password Length\r
-#define MAX_PASSWORD_CHARACTER_LENGTH 0x14\r
-\r
-// PSID Length\r
-#define PSID_CHARACTER_LENGTH 0x20\r
-#define PSID_CHARACTER_STRING_END_LENGTH 0x21\r
-\r
-// ID's for various forms that will be used by HII\r
-#define FORMID_VALUE_MAIN_MENU 0x01\r
-#define FORMID_VALUE_DISK_INFO_FORM_MAIN 0x02\r
-#define FORMID_VALUE_DISK_ACTION_FORM 0x03\r
-\r
-// Structure defining the OPAL_HII_CONFIGURATION\r
-#pragma pack(1)\r
-typedef struct {\r
- UINT8 NumDisks;\r
- UINT8 SelectedDiskIndex;\r
- UINT8 SelectedAction;\r
- UINT16 SelectedDiskAvailableActions;\r
- UINT16 SupportedDisks;\r
- UINT8 KeepUserData;\r
- UINT16 AvailableFields;\r
- UINT16 Password[MAX_PASSWORD_CHARACTER_LENGTH];\r
- UINT16 Psid[PSID_CHARACTER_STRING_END_LENGTH];\r
- UINT8 EnableBlockSid;\r
-} OPAL_HII_CONFIGURATION;\r
-#pragma pack()\r
-\r
-/* Action Flags */\r
-#define HII_ACTION_NONE 0x0000\r
-#define HII_ACTION_LOCK 0x0001\r
-#define HII_ACTION_UNLOCK 0x0002\r
-#define HII_ACTION_SET_ADMIN_PWD 0x0004\r
-#define HII_ACTION_SET_USER_PWD 0x0008\r
-#define HII_ACTION_SECURE_ERASE 0x0010\r
-#define HII_ACTION_PSID_REVERT 0x0020\r
-#define HII_ACTION_DISABLE_USER 0x0040\r
-#define HII_ACTION_REVERT 0x0080\r
-#define HII_ACTION_DISABLE_FEATURE 0x0100\r
-#define HII_ACTION_ENABLE_FEATURE 0x0200\r
-\r
-/* Flags for diskActionAvailableFields */\r
-#define HII_FIELD_PASSWORD 0x0001\r
-#define HII_FIELD_PSID 0x0002\r
-#define HII_FIELD_KEEP_USER_DATA 0x0004\r
-#define HII_FIELD_KEEP_USER_DATA_FORCED 0x0008\r
-\r
-/* Number of bits allocated for each part of a unique key for an HII_ITEM\r
- * all bits together must be <= 16 (EFI_QUESTION_ID is UINT16)\r
- * 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\r
- * | |-----------------------| |---------------------------|\r
- * FLG INDEX ID\r
- */\r
-#define HII_KEY_ID_BITS 8\r
-#define HII_KEY_INDEX_BITS 7\r
-#define HII_KEY_FLAG_BITS 1\r
-\r
-#define HII_KEY_FLAG 0x8000 // bit 15 (zero based)\r
-\r
-/***********/\r
-/* Key IDs */\r
-/***********/\r
-\r
-#define HII_KEY_ID_GOTO_MAIN_MENU 0\r
-#define HII_KEY_ID_GOTO_DISK_INFO 1\r
-#define HII_KEY_ID_GOTO_LOCK 2\r
-#define HII_KEY_ID_GOTO_UNLOCK 3\r
-#define HII_KEY_ID_GOTO_SET_ADMIN_PWD 4\r
-#define HII_KEY_ID_GOTO_SET_USER_PWD 5\r
-#define HII_KEY_ID_GOTO_SECURE_ERASE 6\r
-#define HII_KEY_ID_GOTO_PSID_REVERT 7\r
-#define HII_KEY_ID_GOTO_REVERT 8\r
-#define HII_KEY_ID_GOTO_DISABLE_USER 9\r
-#define HII_KEY_ID_GOTO_ENABLE_FEATURE 0xA //10\r
-#define HII_KEY_ID_GOTO_CONFIRM_TO_MAIN_MENU 0xB //11\r
-#define HII_KEY_ID_ENTER_PASSWORD 0xC //12\r
-#define HII_KEY_ID_ENTER_PSID 0xD //13\r
-#define HII_KEY_ID_VAR_SUPPORTED_DISKS 0xE //14\r
-#define HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS 0xF //15\r
-\r
-#define HII_KEY_ID_BLOCKSID 0x17 //23\r
-#define HII_KEY_ID_MAX 0x17 //23 // !!Update each time a new ID is added!!\r
-\r
-#define HII_KEY_WITH_INDEX(id, index) \\r
- ( \\r
- HII_KEY_FLAG | \\r
- (id) | \\r
- ((index) << HII_KEY_ID_BITS) \\r
- )\r
-\r
-#define HII_KEY(id) HII_KEY_WITH_INDEX(id, 0)\r
-\r
-#define PACKAGE_LIST_GUID { 0xf0308176, 0x9058, 0x4153, { 0x93, 0x3d, 0xda, 0x2f, 0xdc, 0xc8, 0x3e, 0x44 } }\r
-\r
-/* {410483CF-F4F9-4ece-848A-1958FD31CEB7} */\r
-#define SETUP_FORMSET_GUID { 0x410483cf, 0xf4f9, 0x4ece, { 0x84, 0x8a, 0x19, 0x58, 0xfd, 0x31, 0xce, 0xb7 } }\r
-\r
-// {BBF1ACD2-28D8-44ea-A291-58A237FEDF1A}\r
-#define SETUP_VARIABLE_GUID { 0xbbf1acd2, 0x28d8, 0x44ea, { 0xa2, 0x91, 0x58, 0xa2, 0x37, 0xfe, 0xdf, 0x1a } }\r
-\r
-#endif //_HII_FORM_VALUES_H_\r
-\r
+++ /dev/null
-/** @file\r
- Private functions and sturctures used by the Opal UEFI Driver.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#ifndef _OPAL_HII_PRIVATE_H_\r
-#define _OPAL_HII_PRIVATE_H_\r
-\r
-\r
-\r
-#include <Library/OpalPasswordSupportLib.h>\r
-#include <Protocol/HiiConfigAccess.h>\r
-\r
-#include "OpalHii.h"\r
-#include "OpalHiiFormValues.h"\r
-\r
-\r
-#define OPAL_PASSWORD_CONFIG_GUID \\r
- { \\r
- 0x0d510a4f, 0xa81b, 0x473f, { 0x87, 0x07, 0xb7, 0xfd, 0xfb, 0xc0, 0x45, 0xba } \\r
- }\r
-\r
-#pragma pack(1)\r
-\r
-typedef struct {\r
- UINT16 Id: HII_KEY_ID_BITS;\r
- UINT16 Index: HII_KEY_INDEX_BITS;\r
- UINT16 Flag: HII_KEY_FLAG_BITS;\r
-} KEY_BITS;\r
-\r
-typedef union {\r
- UINT16 Raw;\r
- KEY_BITS KeyBits;\r
-} HII_KEY;\r
-\r
-typedef struct {\r
- VENDOR_DEVICE_PATH VendorDevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL End;\r
-} HII_VENDOR_DEVICE_PATH;\r
-\r
-/**\r
-* Opal PSID Authority utilized for PSID revert\r
-*\r
-* The type indicates the structure of the PSID authority\r
-*/\r
-typedef struct {\r
- UINT8 Psid[PSID_CHARACTER_LENGTH];\r
-} TCG_PSID;\r
-\r
-/**\r
- This function processes the results of changes in configuration.\r
-\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Configuration A null-terminated Unicode string in <ConfigResp>\r
- format.\r
- @param Progress A pointer to a string filled in with the offset of\r
- the most recent '&' before the first failing\r
- name/value pair (or the beginning of the string if\r
- the failure is in the first name/value pair) or\r
- the terminating NULL if all was successful.\r
-\r
- @retval EFI_SUCCESS The Results is processed successfully.\r
- @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
- driver.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-RouteConfig(\r
- CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
- CONST EFI_STRING Configuration,\r
- EFI_STRING *Progress\r
- );\r
-\r
-/**\r
- This function allows a caller to extract the current configuration for one\r
- or more named elements from the target driver.\r
-\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Request A null-terminated Unicode string in\r
- <ConfigRequest> format.\r
- @param Progress On return, points to a character in the Request\r
- string. Points to the string's null terminator if\r
- request was successful. Points to the most recent\r
- '&' before the first failing name/value pair (or\r
- the beginning of the string if the failure is in\r
- the first name/value pair) if the request was not\r
- successful.\r
- @param Results A null-terminated Unicode string in\r
- <ConfigAltResp> format which has all values filled\r
- in for the names in the Request string. String to\r
- be allocated by the called function.\r
-\r
- @retval EFI_SUCCESS The Results is filled with the requested values.\r
- @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
- @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
- driver.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ExtractConfig(\r
- CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
- CONST EFI_STRING Request,\r
- EFI_STRING *Progress,\r
- EFI_STRING *Results\r
- );\r
-\r
-/**\r
- This function processes the results of changes in configuration.\r
-\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Action Specifies the type of action taken by the browser.\r
- @param QuestionId A unique value which is sent to the original\r
- exporting driver so that it can identify the type\r
- of data to expect.\r
- @param Type The type of value for the question.\r
- @param Value A pointer to the data being sent to the original\r
- exporting driver.\r
- @param ActionRequest On return, points to the action requested by the\r
- callback function.\r
-\r
- @retval EFI_SUCCESS The callback successfully handled the action.\r
- @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
- variable and its data.\r
- @retval EFI_DEVICE_ERROR The variable could not be saved.\r
- @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
- callback.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DriverCallback(\r
- CONST EFI_HII_CONFIG_ACCESS_PROTOCOL* This,\r
- EFI_BROWSER_ACTION Action,\r
- EFI_QUESTION_ID QuestionId,\r
- UINT8 Type,\r
- EFI_IFR_TYPE_VALUE* Value,\r
- EFI_BROWSER_ACTION_REQUEST* ActionRequest\r
- );\r
-\r
-/**\r
-\r
- Pass the current system state to the bios via the hii_G_Configuration.\r
-\r
-**/\r
-VOID\r
-OpalHiiSetBrowserData (\r
- VOID\r
- );\r
-\r
-/**\r
-\r
- Populate the hii_g_Configuraton with the browser Data.\r
-\r
-**/\r
-VOID\r
-OpalHiiGetBrowserData (\r
- VOID\r
- );\r
-\r
-/**\r
- Draws the disk info form.\r
-\r
- @retval EFI_SUCCESS Draw the disk info success.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiPopulateDiskInfoForm(\r
- VOID\r
- );\r
-\r
-/**\r
- Update the global Disk index info.\r
-\r
- @param Index The input disk index info.\r
-\r
- @retval EFI_SUCCESS Update the disk index info success.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiSelectDisk(\r
- UINT8 Index\r
- );\r
-\r
-/**\r
- Use the input password to do the specified action.\r
-\r
- @param Str The input password saved in.\r
-\r
- @retval EFI_SUCCESS Do the required action success.\r
- @retval Others Other error occur.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiPasswordEntered(\r
- EFI_STRING_ID Str\r
- );\r
-\r
-/**\r
- Update block sid info.\r
-\r
- @param PpRequest Input the Pp Request.\r
-\r
- @retval EFI_SUCCESS Do the required action success.\r
- @retval Others Other error occur.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiSetBlockSidAction (\r
- UINT32 PpRequest\r
- );\r
-\r
-/**\r
- Reverts the Opal disk to factory default.\r
-\r
- @param PsidStringId The string id for the PSID info.\r
-\r
- @retval EFI_SUCCESS Do the required action success.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiPsidRevert(\r
- EFI_STRING_ID PsidStringId\r
- );\r
-\r
-/**\r
- Get disk name string id.\r
-\r
- @param DiskIndex The input disk index info.\r
-\r
- @retval The disk name string id.\r
-\r
-**/\r
-EFI_STRING_ID\r
-GetDiskNameStringId(\r
- UINT8 DiskIndex\r
- );\r
-\r
-/**\r
- Update the device info.\r
-\r
- @param OpalDisk The Opal device.\r
-\r
- @retval EFI_SUCESS Initialize the device success.\r
- @retval EFI_DEVICE_ERROR Get info from device failed.\r
- @retval EFI_INVALID_PARAMETER Not get Msid info before get ownership info.\r
-\r
-**/\r
-EFI_STATUS\r
-OpalDiskUpdateStatus (\r
- OPAL_DISK *OpalDisk\r
- );\r
-\r
-#pragma pack()\r
-\r
-#endif // _HII_P_H_\r
+++ /dev/null
-## @file\r
-# This is a OpalPasswordDxe driver.\r
-#\r
-# This module is used to Management the Opal feature\r
-# for Opal supported devices.\r
-#\r
-#\r
-# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-##\r
-[Defines]\r
- INF_VERSION = 0x00010007\r
- BASE_NAME = OpalPasswordDxe\r
- FILE_GUID = E3E4048D-6C0C-43E4-AE1C-FFB579D8EF41\r
- MODULE_TYPE = DXE_DRIVER\r
- VERSION_STRING = 1.0\r
- ENTRY_POINT = EfiDriverEntryPoint\r
- UNLOAD_IMAGE = OpalEfiDriverUnload\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
-#\r
-\r
-[Sources]\r
- OpalDriver.h\r
- OpalHii.c\r
- OpalHiiCallbacks.c\r
- OpalDriver.c\r
- OpalDriverPrivate.h\r
- OpalHii.h\r
- OpalHiiPrivate.h\r
- OpalHiiFormValues.h\r
- OpalPasswordForm.vfr\r
- OpalHiiFormStrings.uni\r
- ComponentName.c\r
-\r
-[Packages]\r
- MdePkg/MdePkg.dec\r
- MdeModulePkg/MdeModulePkg.dec\r
- SecurityPkg/SecurityPkg.dec\r
-\r
-[LibraryClasses]\r
- BaseLib\r
- MemoryAllocationLib\r
- UefiBootServicesTableLib\r
- UefiDriverEntryPoint\r
- UefiHiiServicesLib\r
- UefiRuntimeServicesTableLib\r
- BaseMemoryLib\r
- DebugLib\r
- HiiLib\r
- PrintLib\r
- DevicePathLib\r
- OpalPasswordSupportLib\r
- UefiLib\r
- TcgStorageOpalLib\r
- Tcg2PhysicalPresenceLib\r
-\r
-[Protocols]\r
- gEfiHiiConfigAccessProtocolGuid ## PRODUCES\r
- gEfiStorageSecurityCommandProtocolGuid ## CONSUMES\r
- gEfiComponentNameProtocolGuid ## PRODUCES\r
- gEfiComponentName2ProtocolGuid ## PRODUCES\r
- gEfiBlockIoProtocolGuid ## CONSUMES\r
- gEfiSmmCommunicationProtocolGuid ## PRODUCES\r
- gEfiPciIoProtocolGuid ## CONSUMES\r
- gEfiDevicePathToTextProtocolGuid ## CONSUMES\r
-\r
-[Guids]\r
- gEfiEventExitBootServicesGuid ## CONSUMES ## Event\r
- gOpalExtraInfoVariableGuid ## PRODUCES ## GUID\r
-\r
-[Depex]\r
- gEfiSmmCommunicationProtocolGuid AND gEfiHiiStringProtocolGuid AND gEfiHiiDatabaseProtocolGuid\r
+++ /dev/null
-/** @file\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-#include "OpalHiiFormValues.h"\r
-\r
-\r
-#define EFI_HII_PLATFORM_SETUP_FORMSET_GUID \\r
- { 0x93039971, 0x8545, 0x4b04, { 0xb4, 0x5e, 0x32, 0xeb, 0x83, 0x26, 0x4, 0xe } }\r
-\r
-formset\r
- guid = SETUP_FORMSET_GUID,\r
- title = STRING_TOKEN(STR_OPAL),\r
- help = STRING_TOKEN(STR_FORM_SET_HELP),\r
- classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,\r
-\r
- // Define a Buffer Storage (EFI_IFR_VARSTORE) that will be filled\r
- // out initially through extractConfig call\r
- varstore OPAL_HII_CONFIGURATION, // This is the Data structure type\r
- name = OpalHiiConfig, // Define referenced name in vfr\r
- guid = SETUP_VARIABLE_GUID; // GUID of this Buffer storage\r
-\r
-form formid = FORMID_VALUE_MAIN_MENU,\r
- title = STRING_TOKEN(STR_OPAL);\r
-\r
- //CONFIG_VARIABLE(HII_KEY(HII_KEY_ID_VAR_SUPPORTED_DISKS), SupportedDisks, 0x0, 0xFFFF);\r
- suppressif TRUE;\r
- numeric\r
- name = SupportedDisks,\r
- varid = OpalHiiConfig.SupportedDisks,\r
- prompt = STRING_TOKEN(STR_NULL),\r
- help = STRING_TOKEN(STR_NULL),\r
- flags = INTERACTIVE,\r
- key = 0x800E, //32782,\r
- minimum = 0x0,\r
- maximum = 0xFFFF,\r
- endnumeric;\r
- endif;\r
-\r
- subtitle text = STRING_TOKEN(STR_MAIN_OPAL_VERSION);\r
-\r
- subtitle text = STRING_TOKEN(STR_NULL);\r
-\r
- text\r
- help = STRING_TOKEN(STR_NULL),\r
- text = STRING_TOKEN(STR_MAIN_PHY_DISKS_LBL);\r
-\r
- subtitle text = STRING_TOKEN(STR_NULL);\r
-\r
- //DISK( 0 );\r
- suppressif ( questionref(SupportedDisks) & ( 0x1 ) ) == 0;\r
- goto FORMID_VALUE_DISK_INFO_FORM_MAIN,\r
- prompt = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_0 ),\r
- help = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP),\r
- flags = INTERACTIVE, \\r
- key = 0x8001; //32769\r
- endif;\r
-\r
- //DISK( 1 );\r
- suppressif ( questionref(SupportedDisks) & ( 0x2 ) ) == 0;\r
- goto FORMID_VALUE_DISK_INFO_FORM_MAIN,\r
- prompt = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_1 ),\r
- help = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP),\r
- flags = INTERACTIVE, \\r
- key = 0x8101; //33025\r
- endif;\r
-\r
- //DISK( 2 );\r
- suppressif ( questionref(SupportedDisks) & ( 0x4 ) ) == 0;\r
- goto FORMID_VALUE_DISK_INFO_FORM_MAIN,\r
- prompt = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_2 ),\r
- help = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP),\r
- flags = INTERACTIVE, \\r
- key = 0x8201; //33281\r
- endif;\r
-\r
- //DISK( 3 );\r
- suppressif ( questionref(SupportedDisks) & ( 0x8 ) ) == 0;\r
- goto FORMID_VALUE_DISK_INFO_FORM_MAIN,\r
- prompt = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_3 ),\r
- help = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP),\r
- flags = INTERACTIVE, \\r
- key = 0x8301; // 33537\r
- endif;\r
-\r
- //DISK( 4 );\r
- suppressif ( questionref(SupportedDisks) & ( 0x10 ) ) == 0;\r
- goto FORMID_VALUE_DISK_INFO_FORM_MAIN,\r
- prompt = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_4 ),\r
- help = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP),\r
- flags = INTERACTIVE, \\r
- key = 0x8401; // 33793\r
- endif;\r
-\r
- //DISK( 5 );\r
- suppressif ( questionref(SupportedDisks) & ( 0x20 ) ) == 0;\r
- goto FORMID_VALUE_DISK_INFO_FORM_MAIN,\r
- prompt = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_5 ),\r
- help = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP),\r
- flags = INTERACTIVE, \\r
- key = 0x8501; // 34049\r
- endif;\r
-\r
- //No disks on system\r
- suppressif ideqval OpalHiiConfig.NumDisks > 0;\r
- text\r
- help = STRING_TOKEN(STR_NULL),\r
- text = STRING_TOKEN(STR_MAIN_NO_DISKS_PRESENT_LBL);\r
- endif;\r
-\r
- subtitle text = STRING_TOKEN(STR_NULL);\r
-\r
- grayoutif TRUE;\r
- text\r
- help = STRING_TOKEN(STR_BLOCKSID_STATUS_HELP),\r
- text = STRING_TOKEN(STR_BLOCKSID_STATUS);\r
- text\r
- help = STRING_TOKEN(STR_BLOCKSID_STATUS_HELP),\r
- text = STRING_TOKEN(STR_BLOCKSID_STATUS1);\r
- text\r
- help = STRING_TOKEN(STR_BLOCKSID_STATUS_HELP),\r
- text = STRING_TOKEN(STR_BLOCKSID_STATUS2);\r
- text\r
- help = STRING_TOKEN(STR_BLOCKSID_STATUS_HELP),\r
- text = STRING_TOKEN(STR_BLOCKSID_STATUS3);\r
- subtitle text = STRING_TOKEN(STR_NULL);\r
- endif;\r
-\r
- oneof varid = OpalHiiConfig.EnableBlockSid,\r
- questionid = 0x8017, // 32791,\r
- prompt = STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID),\r
- help = STRING_TOKEN(STR_DISK_INFO_GOTO_ENABLE_BLOCKSID_HELP),\r
- flags = INTERACTIVE,\r
- option text = STRING_TOKEN(STR_NONE), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\r
- option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\r
- option text = STRING_TOKEN(STR_DISABLED), value = 2, flags = RESET_REQUIRED;\r
- option text = STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID_TRUE), value = 3, flags = RESET_REQUIRED;\r
- option text = STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID_FALSE), value = 4, flags = RESET_REQUIRED;\r
- option text = STRING_TOKEN(STR_DISK_INFO_DISABLE_BLOCKSID_TRUE), value = 5, flags = RESET_REQUIRED;\r
- option text = STRING_TOKEN(STR_DISK_INFO_DISABLE_BLOCKSID_FALSE), value = 6, flags = RESET_REQUIRED;\r
- endoneof;\r
-\r
-\r
-\r
-endform; // MAIN MENU FORM\r
-\r
-//\r
-///////////////// DISK INFO FORM /////////////////\r
-//\r
-form formid = FORMID_VALUE_DISK_INFO_FORM_MAIN,\r
- title = STRING_TOKEN(STR_OPAL);\r
-\r
- suppressif TRUE;\r
- numeric\r
- name = SelectedDiskAvailableActions,\r
- varid = OpalHiiConfig.SelectedDiskAvailableActions,\r
- prompt = STRING_TOKEN(STR_NULL),\r
- help = STRING_TOKEN(STR_NULL),\r
- flags = INTERACTIVE,\r
- key = 0x800F, // 32783\r
- minimum = 0x0,\r
- maximum = 0xFFFF,\r
- endnumeric;\r
- endif;\r
-\r
- subtitle text = STRING_TOKEN(STR_MAIN_OPAL_VERSION);\r
-\r
- subtitle text = STRING_TOKEN(STR_NULL);\r
-\r
- text\r
- help = STRING_TOKEN(STR_NULL),\r
- text = STRING_TOKEN(STR_DISK_INFO_SELECTED_DISK_NAME);\r
-\r
- subtitle text = STRING_TOKEN(STR_NULL);\r
-\r
- suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_LOCK ) == 0;\r
- goto FORMID_VALUE_DISK_ACTION_FORM,\r
- prompt = STRING_TOKEN(STR_DISK_INFO_LOCK),\r
- help = STRING_TOKEN(STR_DISK_INFO_GOTO_LOCK_HELP),\r
- flags = INTERACTIVE,\r
- key = 0x8002; // 32770\r
- endif;\r
-\r
- suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_UNLOCK ) == 0;\r
- goto FORMID_VALUE_DISK_ACTION_FORM,\r
- prompt = STRING_TOKEN(STR_DISK_INFO_UNLOCK),\r
- help = STRING_TOKEN(STR_DISK_INFO_GOTO_UNLOCK_HELP),\r
- flags = INTERACTIVE,\r
- key = 0x8003; //32771;\r
- endif;\r
-\r
- suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_SET_ADMIN_PWD ) == 0;\r
- goto FORMID_VALUE_DISK_ACTION_FORM,\r
- prompt = STRING_TOKEN(STR_DISK_INFO_SET_ADMIN_PSWD),\r
- help = STRING_TOKEN(STR_DISK_INFO_GOTO_SET_ADMIN_PSWD_HELP),\r
- flags = INTERACTIVE,\r
- key = 0x8004; //32772;\r
- endif;\r
-\r
- suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_SET_USER_PWD ) == 0;\r
- goto FORMID_VALUE_DISK_ACTION_FORM,\r
- prompt = STRING_TOKEN(STR_DISK_INFO_SET_USER_PSWD),\r
- help = STRING_TOKEN(STR_DISK_INFO_GOTO_SET_USER_PSWD_HELP),\r
- flags = INTERACTIVE,\r
- key = 0x8005; //32773;\r
- endif;\r
-\r
- suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_SECURE_ERASE ) == 0;\r
- goto FORMID_VALUE_DISK_ACTION_FORM,\r
- prompt = STRING_TOKEN(STR_DISK_INFO_SECURE_ERASE),\r
- help = STRING_TOKEN(STR_DISK_INFO_GOTO_SECURE_ERASE_HELP),\r
- flags = INTERACTIVE,\r
- key = 0x8006; //32774;\r
- endif;\r
-\r
- suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_REVERT ) == 0;\r
- goto FORMID_VALUE_DISK_ACTION_FORM,\r
- prompt = STRING_TOKEN(STR_DISK_INFO_REVERT),\r
- help = STRING_TOKEN(STR_DISK_INFO_GOTO_PSID_REVERT_HELP),\r
- flags = INTERACTIVE,\r
- key = 0x8008; //32776;\r
- endif;\r
-\r
- suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_PSID_REVERT ) == 0;\r
- goto FORMID_VALUE_DISK_ACTION_FORM,\r
- prompt = STRING_TOKEN(STR_DISK_INFO_PSID_REVERT),\r
- help = STRING_TOKEN(STR_DISK_INFO_GOTO_PSID_REVERT_HELP),\r
- flags = INTERACTIVE,\r
- key = 0x8007; //32775;\r
- endif;\r
-\r
- suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_DISABLE_USER ) == 0;\r
- goto FORMID_VALUE_DISK_ACTION_FORM,\r
- prompt = STRING_TOKEN(STR_DISK_INFO_DISABLE_USER),\r
- help = STRING_TOKEN(STR_DISK_INFO_GOTO_DISABLE_USER_HELP),\r
- flags = INTERACTIVE,\r
- key = 0x8009; //32777;\r
- endif;\r
-\r
- suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_ENABLE_FEATURE ) == 0;\r
- goto FORMID_VALUE_DISK_ACTION_FORM,\r
- prompt = STRING_TOKEN(STR_DISK_INFO_ENABLE_FEATURE),\r
- help = STRING_TOKEN(STR_DISK_INFO_GOTO_ENABLE_FEATURE_HELP),\r
- flags = INTERACTIVE,\r
- key = 0x800A; //32778;\r
- endif;\r
-\r
-endform; // DISK INFO FORM\r
-\r
-//\r
-///////////////// DISK ACTION FORM /////////////////\r
-//\r
-form formid = FORMID_VALUE_DISK_ACTION_FORM,\r
- title = STRING_TOKEN(STR_OPAL);\r
-\r
- suppressif TRUE;\r
- numeric\r
- name = AvailableFields,\r
- varid = OpalHiiConfig.AvailableFields,\r
- prompt = STRING_TOKEN(STR_NULL),\r
- help = STRING_TOKEN(STR_NULL),\r
- flags = INTERACTIVE,\r
- key = 0x8012, //32786,\r
- minimum = 0x0,\r
- maximum = 0xFFFF,\r
- endnumeric;\r
- endif;\r
-\r
- subtitle text = STRING_TOKEN(STR_MAIN_OPAL_VERSION);\r
-\r
- subtitle text = STRING_TOKEN(STR_NULL);\r
-\r
- text\r
- help = STRING_TOKEN(STR_NULL),\r
- text = STRING_TOKEN(STR_DISK_INFO_SELECTED_DISK_NAME);\r
-\r
- subtitle text = STRING_TOKEN(STR_NULL);\r
-\r
- text\r
- help = STRING_TOKEN(STR_NULL),\r
- text = STRING_TOKEN(STR_DISK_ACTION_LBL);\r
-\r
- subtitle text = STRING_TOKEN(STR_NULL);\r
-\r
- suppressif (questionref(AvailableFields) & HII_FIELD_KEEP_USER_DATA) == 0;\r
- grayoutif (questionref(AvailableFields) & HII_FIELD_KEEP_USER_DATA_FORCED) != 0;\r
- checkbox\r
- name = MyCheckbox,\r
- varid = OpalHiiConfig.KeepUserData,\r
- prompt = STRING_TOKEN(STR_KEEP_USER_DATA_PROMPT),\r
- help = STRING_TOKEN(STR_KEEP_USER_DATA_HELP),\r
- key = 0x8011, //32785,\r
- endcheckbox;\r
-\r
- //EMPTY_LINE;\r
- text\r
- help = STRING_TOKEN(STR_NULL),\r
- text = STRING_TOKEN(STR_NULL);\r
- endif;\r
- endif;\r
-\r
- suppressif (questionref(AvailableFields) & HII_FIELD_PASSWORD) == 0;\r
- password\r
- varid = OpalHiiConfig.Password,\r
- prompt = STRING_TOKEN(STR_PASSWORD_PROMPT),\r
- help = STRING_TOKEN(STR_PASSWORD_HELP),\r
- flags = INTERACTIVE,\r
- key = 0x800C, //32780,\r
- minsize = 6,\r
- maxsize = 20,\r
- endpassword;\r
- endif;\r
-\r
- suppressif (questionref(AvailableFields) & HII_FIELD_PSID) == 0;\r
- string\r
- varid = OpalHiiConfig.Psid,\r
- prompt = STRING_TOKEN(STR_REVERT_PROMPT),\r
- help = STRING_TOKEN(STR_REVERT_HELP),\r
- flags = INTERACTIVE,\r
- key = 0x800D, //32781,\r
- minsize = PSID_CHARACTER_LENGTH,\r
- maxsize = PSID_CHARACTER_LENGTH,\r
- endstring;\r
- endif;\r
-\r
- subtitle text = STRING_TOKEN(STR_NULL);\r
-\r
- text\r
- help = STRING_TOKEN(STR_NULL),\r
- text = STRING_TOKEN(STR_ACTION_STATUS);\r
-\r
- subtitle text = STRING_TOKEN(STR_NULL);\r
-\r
- goto FORMID_VALUE_MAIN_MENU,\r
- prompt = STRING_TOKEN(STR_GOTO_HOME),\r
- help = STRING_TOKEN(STR_GOTO_HOME_HELP),\r
- flags = INTERACTIVE,\r
- key = 0x8000; //32768;\r
-\r
-endform; // DISK ACTION FORM\r
-\r
-endformset;\r
+++ /dev/null
-/** @file\r
- This driver is used for Opal Password Feature support at AHCI mode.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-\r
-#include "OpalPasswordSmm.h"\r
-\r
-/**\r
- Start command for give slot on specific port.\r
-\r
- @param Port The number of port.\r
- @param CommandSlot The number of CommandSlot.\r
- @param Timeout The timeout Value of start.\r
-\r
- @retval EFI_DEVICE_ERROR The command start unsuccessfully.\r
- @retval EFI_TIMEOUT The operation is time out.\r
- @retval EFI_SUCCESS The command start successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciStartCommand (\r
- IN UINT8 Port,\r
- IN UINT8 CommandSlot,\r
- IN UINT64 Timeout\r
- );\r
-\r
-/**\r
- Stop command running for giving port\r
-\r
- @param Port The number of port.\r
- @param Timeout The timeout Value of stop.\r
-\r
- @retval EFI_DEVICE_ERROR The command stop unsuccessfully.\r
- @retval EFI_TIMEOUT The operation is time out.\r
- @retval EFI_SUCCESS The command stop successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciStopCommand (\r
- IN UINT8 Port,\r
- IN UINT64 Timeout\r
- );\r
-\r
-/**\r
- Read AHCI Operation register.\r
-\r
- @param Offset The operation register offset.\r
-\r
- @return The register content read.\r
-\r
-**/\r
-UINT32\r
-EFIAPI\r
-AhciReadReg (\r
- IN UINT32 Offset\r
- )\r
-{\r
- UINT32 Data;\r
-\r
- Data = 0;\r
-\r
- Data = MmioRead32 (mAhciBar + Offset);\r
-\r
- return Data;\r
-}\r
-\r
-/**\r
- Write AHCI Operation register.\r
-\r
- @param Offset The operation register offset.\r
- @param Data The Data used to write down.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-AhciWriteReg (\r
- IN UINT32 Offset,\r
- IN UINT32 Data\r
- )\r
-{\r
- MmioWrite32 (mAhciBar + Offset, Data);\r
-\r
- return ;\r
-}\r
-\r
-/**\r
- Do AND operation with the Value of AHCI Operation register.\r
-\r
- @param Offset The operation register offset.\r
- @param AndData The Data used to do AND operation.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-AhciAndReg (\r
- IN UINT32 Offset,\r
- IN UINT32 AndData\r
- )\r
-{\r
- UINT32 Data;\r
-\r
- Data = AhciReadReg (Offset);\r
-\r
- Data &= AndData;\r
-\r
- AhciWriteReg (Offset, Data);\r
-}\r
-\r
-/**\r
- Do OR operation with the Value of AHCI Operation register.\r
-\r
- @param Offset The operation register offset.\r
- @param OrData The Data used to do OR operation.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-AhciOrReg (\r
- IN UINT32 Offset,\r
- IN UINT32 OrData\r
- )\r
-{\r
- UINT32 Data;\r
-\r
- Data = AhciReadReg (Offset);\r
-\r
- Data |= OrData;\r
-\r
- AhciWriteReg (Offset, Data);\r
-}\r
-\r
-/**\r
- Wait for memory set to the test Value.\r
-\r
- @param Offset The memory address to test.\r
- @param MaskValue The mask Value of memory.\r
- @param TestValue The test Value of memory.\r
- @param Timeout The time out Value for wait memory set.\r
-\r
- @retval EFI_DEVICE_ERROR The memory is not set.\r
- @retval EFI_TIMEOUT The memory setting is time out.\r
- @retval EFI_SUCCESS The memory is correct set.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciWaitMmioSet (\r
- IN UINT32 Offset,\r
- IN UINT32 MaskValue,\r
- IN UINT32 TestValue,\r
- IN UINT64 Timeout\r
- )\r
-{\r
- UINT32 Value;\r
- UINT32 Delay;\r
-\r
- Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
-\r
- do {\r
- Value = AhciReadReg (Offset) & MaskValue;\r
-\r
- if (Value == TestValue) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Stall for 100 microseconds.\r
- //\r
- MicroSecondDelay (100);\r
-\r
- Delay--;\r
-\r
- } while (Delay > 0);\r
-\r
- return EFI_TIMEOUT;\r
-}\r
-/**\r
- Wait for the Value of the specified system memory set to the test Value.\r
-\r
- @param Address The system memory address to test.\r
- @param MaskValue The mask Value of memory.\r
- @param TestValue The test Value of memory.\r
- @param Timeout The time out Value for wait memory set, uses 100ns as a unit.\r
-\r
- @retval EFI_TIMEOUT The system memory setting is time out.\r
- @retval EFI_SUCCESS The system memory is correct set.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciWaitMemSet (\r
- IN EFI_PHYSICAL_ADDRESS Address,\r
- IN UINT32 MaskValue,\r
- IN UINT32 TestValue,\r
- IN UINT64 Timeout\r
- )\r
-{\r
- UINT32 Value;\r
- UINT32 Delay;\r
-\r
- Delay = (UINT32) (DivU64x32 (Timeout, 1000) + 1);\r
-\r
- do {\r
- //\r
- // Access sytem memory to see if the Value is the tested one.\r
- //\r
- // The system memory pointed by Address will be updated by the\r
- // SATA Host Controller, "volatile" is introduced to prevent\r
- // compiler from optimizing the access to the memory address\r
- // to only read once.\r
- //\r
- Value = *(volatile UINT32 *) (UINTN) Address;\r
- Value &= MaskValue;\r
-\r
- if (Value == TestValue) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Stall for 100 microseconds.\r
- //\r
- MicroSecondDelay (100);\r
-\r
- Delay--;\r
-\r
- } while (Delay > 0);\r
-\r
- return EFI_TIMEOUT;\r
-}\r
-\r
-/**\r
- Check the memory status to the test Value.\r
-\r
- @param[in] Address The memory address to test.\r
- @param[in] MaskValue The mask Value of memory.\r
- @param[in] TestValue The test Value of memory.\r
- @param[in, out] RetryTimes The retry times Value for waitting memory set. If 0, then just try once.\r
-\r
- @retval EFI_NOTREADY The memory is not set.\r
- @retval EFI_TIMEOUT The memory setting retry times out.\r
- @retval EFI_SUCCESS The memory is correct set.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciCheckMemSet (\r
- IN UINTN Address,\r
- IN UINT32 MaskValue,\r
- IN UINT32 TestValue,\r
- IN OUT UINTN *RetryTimes OPTIONAL\r
- )\r
-{\r
- UINT32 Value;\r
-\r
- if (RetryTimes != NULL) {\r
- (*RetryTimes)--;\r
- }\r
-\r
- Value = *(volatile UINT32 *) Address;\r
- Value &= MaskValue;\r
-\r
- if (Value == TestValue) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if ((RetryTimes != NULL) && (*RetryTimes == 0)) {\r
- return EFI_TIMEOUT;\r
- } else {\r
- return EFI_NOT_READY;\r
- }\r
-}\r
-\r
-/**\r
- Clear the port interrupt and error status. It will also clear\r
- HBA interrupt status.\r
-\r
- @param Port The number of port.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-AhciClearPortStatus (\r
- IN UINT8 Port\r
- )\r
-{\r
- UINT32 Offset;\r
-\r
- //\r
- // Clear any error status\r
- //\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SERR;\r
- AhciWriteReg (Offset, AhciReadReg (Offset));\r
-\r
- //\r
- // Clear any port interrupt status\r
- //\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;\r
- AhciWriteReg (Offset, AhciReadReg (Offset));\r
-\r
- //\r
- // Clear any HBA interrupt status\r
- //\r
- AhciWriteReg (EFI_AHCI_IS_OFFSET, AhciReadReg (EFI_AHCI_IS_OFFSET));\r
-}\r
-\r
-/**\r
- Enable the FIS running for giving port.\r
-\r
- @param Port The number of port.\r
- @param Timeout The timeout Value of enabling FIS.\r
-\r
- @retval EFI_DEVICE_ERROR The FIS enable setting fails.\r
- @retval EFI_TIMEOUT The FIS enable setting is time out.\r
- @retval EFI_SUCCESS The FIS enable successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciEnableFisReceive (\r
- IN UINT8 Port,\r
- IN UINT64 Timeout\r
- )\r
-{\r
- UINT32 Offset;\r
-\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;\r
- AhciOrReg (Offset, EFI_AHCI_PORT_CMD_FRE);\r
-\r
- return AhciWaitMmioSet (\r
- Offset,\r
- EFI_AHCI_PORT_CMD_FR,\r
- EFI_AHCI_PORT_CMD_FR,\r
- Timeout\r
- );\r
-}\r
-\r
-/**\r
- Disable the FIS running for giving port.\r
-\r
- @param Port The number of port.\r
- @param Timeout The timeout Value of disabling FIS.\r
-\r
- @retval EFI_DEVICE_ERROR The FIS disable setting fails.\r
- @retval EFI_TIMEOUT The FIS disable setting is time out.\r
- @retval EFI_UNSUPPORTED The port is in running state.\r
- @retval EFI_SUCCESS The FIS disable successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciDisableFisReceive (\r
- IN UINT8 Port,\r
- IN UINT64 Timeout\r
- )\r
-{\r
- UINT32 Offset;\r
- UINT32 Data;\r
-\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;\r
- Data = AhciReadReg (Offset);\r
-\r
- //\r
- // Before disabling Fis receive, the DMA engine of the port should NOT be in running status.\r
- //\r
- if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) != 0) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Check if the Fis receive DMA engine for the port is running.\r
- //\r
- if ((Data & EFI_AHCI_PORT_CMD_FR) != EFI_AHCI_PORT_CMD_FR) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- AhciAndReg (Offset, (UINT32)~(EFI_AHCI_PORT_CMD_FRE));\r
-\r
- return AhciWaitMmioSet (\r
- Offset,\r
- EFI_AHCI_PORT_CMD_FR,\r
- 0,\r
- Timeout\r
- );\r
-}\r
-\r
-/**\r
- Build the command list, command table and prepare the fis receiver.\r
-\r
- @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.\r
- @param Port The number of port.\r
- @param PortMultiplier The timeout Value of stop.\r
- @param CommandFis The control fis will be used for the transfer.\r
- @param CommandList The command list will be used for the transfer.\r
- @param AtapiCommand The atapi command will be used for the transfer.\r
- @param AtapiCommandLength The Length of the atapi command.\r
- @param CommandSlotNumber The command slot will be used for the transfer.\r
- @param DataPhysicalAddr The pointer to the Data Buffer pci bus master address.\r
- @param DataLength The Data count to be transferred.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-AhciBuildCommand (\r
- IN EFI_AHCI_REGISTERS *AhciRegisters,\r
- IN UINT8 Port,\r
- IN UINT8 PortMultiplier,\r
- IN EFI_AHCI_COMMAND_FIS *CommandFis,\r
- IN EFI_AHCI_COMMAND_LIST *CommandList,\r
- IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,\r
- IN UINT8 AtapiCommandLength,\r
- IN UINT8 CommandSlotNumber,\r
- IN OUT VOID *DataPhysicalAddr,\r
- IN UINT64 DataLength\r
- )\r
-{\r
- UINT64 BaseAddr;\r
- UINT64 PrdtNumber;\r
- UINTN RemainedData;\r
- UINTN MemAddr;\r
- DATA_64 Data64;\r
- UINT32 Offset;\r
-\r
- //\r
- // Filling the PRDT\r
- //\r
- PrdtNumber = DivU64x32 (DataLength + EFI_AHCI_MAX_DATA_PER_PRDT - 1, EFI_AHCI_MAX_DATA_PER_PRDT);\r
-\r
- //\r
- // According to AHCI 1.3 spec, a PRDT entry can point to a maximum 4MB Data block.\r
- // It also limits that the maximum amount of the PRDT entry in the command table\r
- // is 65535.\r
- //\r
- ASSERT (PrdtNumber <= 1);\r
-\r
- Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFis);\r
-\r
- BaseAddr = Data64.Uint64;\r
-\r
- ZeroMem ((VOID *)((UINTN) BaseAddr), sizeof (EFI_AHCI_RECEIVED_FIS));\r
-\r
- ZeroMem (AhciRegisters->AhciCommandTable, sizeof (EFI_AHCI_COMMAND_TABLE));\r
-\r
- CommandFis->AhciCFisPmNum = PortMultiplier;\r
-\r
- CopyMem (&AhciRegisters->AhciCommandTable->CommandFis, CommandFis, sizeof (EFI_AHCI_COMMAND_FIS));\r
-\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;\r
- if (AtapiCommand != NULL) {\r
- CopyMem (\r
- &AhciRegisters->AhciCommandTable->AtapiCmd,\r
- AtapiCommand,\r
- AtapiCommandLength\r
- );\r
-\r
- CommandList->AhciCmdA = 1;\r
- CommandList->AhciCmdP = 1;\r
-\r
- AhciOrReg (Offset, (EFI_AHCI_PORT_CMD_DLAE | EFI_AHCI_PORT_CMD_ATAPI));\r
- } else {\r
- AhciAndReg (Offset, (UINT32)~(EFI_AHCI_PORT_CMD_DLAE | EFI_AHCI_PORT_CMD_ATAPI));\r
- }\r
-\r
- RemainedData = (UINTN) DataLength;\r
- MemAddr = (UINTN) DataPhysicalAddr;\r
- CommandList->AhciCmdPrdtl = (UINT32)PrdtNumber;\r
-\r
- AhciRegisters->AhciCommandTable->PrdtTable.AhciPrdtDbc = (UINT32)RemainedData - 1;\r
-\r
- Data64.Uint64 = (UINT64)MemAddr;\r
- AhciRegisters->AhciCommandTable->PrdtTable.AhciPrdtDba = Data64.Uint32.Lower32;\r
- AhciRegisters->AhciCommandTable->PrdtTable.AhciPrdtDbau = Data64.Uint32.Upper32;\r
-\r
- //\r
- // Set the last PRDT to Interrupt On Complete\r
- //\r
- AhciRegisters->AhciCommandTable->PrdtTable.AhciPrdtIoc = 1;\r
-\r
- CopyMem (\r
- (VOID *) ((UINTN) AhciRegisters->AhciCmdList + (UINTN) CommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST)),\r
- CommandList,\r
- sizeof (EFI_AHCI_COMMAND_LIST)\r
- );\r
-\r
- Data64.Uint64 = (UINT64)(UINTN) AhciRegisters->AhciCommandTable;\r
- AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtba = Data64.Uint32.Lower32;\r
- AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtbau = Data64.Uint32.Upper32;\r
- AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdPmp = PortMultiplier;\r
-\r
-}\r
-\r
-/**\r
- Buid a command FIS.\r
-\r
- @param CmdFis A pointer to the EFI_AHCI_COMMAND_FIS Data structure.\r
- @param AtaCommandBlock A pointer to the AhciBuildCommandFis Data structure.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-AhciBuildCommandFis (\r
- IN OUT EFI_AHCI_COMMAND_FIS *CmdFis,\r
- IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock\r
- )\r
-{\r
- ZeroMem (CmdFis, sizeof (EFI_AHCI_COMMAND_FIS));\r
-\r
- CmdFis->AhciCFisType = EFI_AHCI_FIS_REGISTER_H2D;\r
- //\r
- // Indicator it's a command\r
- //\r
- CmdFis->AhciCFisCmdInd = 0x1;\r
- CmdFis->AhciCFisCmd = AtaCommandBlock->AtaCommand;\r
-\r
- CmdFis->AhciCFisFeature = AtaCommandBlock->AtaFeatures;\r
- CmdFis->AhciCFisFeatureExp = AtaCommandBlock->AtaFeaturesExp;\r
-\r
- CmdFis->AhciCFisSecNum = AtaCommandBlock->AtaSectorNumber;\r
- CmdFis->AhciCFisSecNumExp = AtaCommandBlock->AtaSectorNumberExp;\r
-\r
- CmdFis->AhciCFisClyLow = AtaCommandBlock->AtaCylinderLow;\r
- CmdFis->AhciCFisClyLowExp = AtaCommandBlock->AtaCylinderLowExp;\r
-\r
- CmdFis->AhciCFisClyHigh = AtaCommandBlock->AtaCylinderHigh;\r
- CmdFis->AhciCFisClyHighExp = AtaCommandBlock->AtaCylinderHighExp;\r
-\r
- CmdFis->AhciCFisSecCount = AtaCommandBlock->AtaSectorCount;\r
- CmdFis->AhciCFisSecCountExp = AtaCommandBlock->AtaSectorCountExp;\r
-\r
- CmdFis->AhciCFisDevHead = (UINT8) (AtaCommandBlock->AtaDeviceHead | 0xE0);\r
-}\r
-\r
-/**\r
- Start a PIO Data transfer on specific port.\r
-\r
- @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.\r
- @param Port The number of port.\r
- @param PortMultiplier The timeout Value of stop.\r
- @param AtapiCommand The atapi command will be used for the transfer.\r
- @param AtapiCommandLength The Length of the atapi command.\r
- @param Read The transfer direction.\r
- @param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK Data.\r
- @param AtaStatusBlock The EFI_ATA_STATUS_BLOCK Data.\r
- @param MemoryAddr The pointer to the Data Buffer.\r
- @param DataCount The Data count to be transferred.\r
- @param Timeout The timeout Value of non Data transfer.\r
-\r
- @retval EFI_DEVICE_ERROR The PIO Data transfer abort with error occurs.\r
- @retval EFI_TIMEOUT The operation is time out.\r
- @retval EFI_UNSUPPORTED The device is not ready for transfer.\r
- @retval EFI_SUCCESS The PIO Data transfer executes successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciPioTransfer (\r
- IN EFI_AHCI_REGISTERS *AhciRegisters,\r
- IN UINT8 Port,\r
- IN UINT8 PortMultiplier,\r
- IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,\r
- IN UINT8 AtapiCommandLength,\r
- IN BOOLEAN Read,\r
- IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,\r
- IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,\r
- IN OUT VOID *MemoryAddr,\r
- IN UINT32 DataCount,\r
- IN UINT64 Timeout\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 FisBaseAddr;\r
- UINT32 Offset;\r
- UINT32 Delay;\r
- EFI_AHCI_COMMAND_FIS CFis;\r
- EFI_AHCI_COMMAND_LIST CmdList;\r
- UINT32 PortTfd;\r
- UINT32 PrdCount;\r
- UINT32 OldRfisLo;\r
- UINT32 OldRfisHi;\r
- UINT32 OldCmdListLo;\r
- UINT32 OldCmdListHi;\r
-\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FB;\r
- OldRfisLo = AhciReadReg (Offset);\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FBU;\r
- OldRfisHi = AhciReadReg (Offset);\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FB;\r
- AhciWriteReg (Offset, (UINT32)(UINTN)AhciRegisters->AhciRFis);\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FBU;\r
- AhciWriteReg (Offset, 0);\r
-\r
- //\r
- // Single task envrionment, we only use one command table for all port\r
- //\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLB;\r
- OldCmdListLo = AhciReadReg (Offset);\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLBU;\r
- OldCmdListHi = AhciReadReg (Offset);\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLB;\r
- AhciWriteReg (Offset, (UINT32)(UINTN)AhciRegisters->AhciCmdList);\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLBU;\r
- AhciWriteReg (Offset, 0);\r
-\r
- //\r
- // Package read needed\r
- //\r
- AhciBuildCommandFis (&CFis, AtaCommandBlock);\r
-\r
- ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));\r
-\r
- CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;\r
- CmdList.AhciCmdW = Read ? 0 : 1;\r
-\r
- AhciBuildCommand (\r
- AhciRegisters,\r
- Port,\r
- PortMultiplier,\r
- &CFis,\r
- &CmdList,\r
- AtapiCommand,\r
- AtapiCommandLength,\r
- 0,\r
- (VOID *)(UINTN)MemoryAddr,\r
- DataCount\r
- );\r
-\r
- Status = AhciStartCommand (\r
- Port,\r
- 0,\r
- Timeout\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto Exit;\r
- }\r
-\r
- //\r
- // Checking the status and wait the driver sending Data\r
- //\r
- FisBaseAddr = (UINT32)(UINTN)AhciRegisters->AhciRFis;\r
- if (Read && (AtapiCommand == 0)) {\r
- //\r
- // Wait device sends the PIO setup fis before Data transfer\r
- //\r
- Status = EFI_TIMEOUT;\r
- Delay = (UINT32) (DivU64x32 (Timeout, 1000) + 1);\r
- do {\r
- Offset = FisBaseAddr + EFI_AHCI_PIO_FIS_OFFSET;\r
-\r
- Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, EFI_AHCI_FIS_PIO_SETUP, 0);\r
- if (!EFI_ERROR (Status)) {\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;\r
- PortTfd = AhciReadReg ((UINT32) Offset);\r
- //\r
- // PxTFD will be updated if there is a D2H or SetupFIS received.\r
- // For PIO IN transfer, D2H means a device error. Therefore we only need to check the TFD after receiving a SetupFIS.\r
- //\r
- if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) {\r
- Status = EFI_DEVICE_ERROR;\r
- break;\r
- }\r
-\r
- PrdCount = *(volatile UINT32 *) (&(AhciRegisters->AhciCmdList[0].AhciCmdPrdbc));\r
- if (PrdCount == DataCount) {\r
- break;\r
- }\r
- }\r
-\r
- Offset = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET;\r
- Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, EFI_AHCI_FIS_REGISTER_D2H, 0);\r
- if (!EFI_ERROR (Status)) {\r
- Status = EFI_DEVICE_ERROR;\r
- break;\r
- }\r
-\r
- //\r
- // Stall for 100 microseconds.\r
- //\r
- MicroSecondDelay(100);\r
-\r
- Delay--;\r
- } while (Delay > 0);\r
- } else {\r
- //\r
- // Wait for D2H Fis is received\r
- //\r
- Offset = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET;\r
- Status = AhciWaitMemSet (\r
- Offset,\r
- EFI_AHCI_FIS_TYPE_MASK,\r
- EFI_AHCI_FIS_REGISTER_D2H,\r
- Timeout\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto Exit;\r
- }\r
-\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;\r
- PortTfd = AhciReadReg ((UINT32) Offset);\r
- if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) {\r
- Status = EFI_DEVICE_ERROR;\r
- }\r
- }\r
-\r
-Exit:\r
- AhciStopCommand (\r
- Port,\r
- Timeout\r
- );\r
-\r
- AhciDisableFisReceive (\r
- Port,\r
- Timeout\r
- );\r
-\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FB;\r
- AhciWriteReg (Offset, OldRfisLo);\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FBU;\r
- AhciWriteReg (Offset, OldRfisHi);\r
-\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLB;\r
- AhciWriteReg (Offset, OldCmdListLo);\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLBU;\r
- AhciWriteReg (Offset, OldCmdListHi);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Stop command running for giving port\r
-\r
- @param Port The number of port.\r
- @param Timeout The timeout Value of stop.\r
-\r
- @retval EFI_DEVICE_ERROR The command stop unsuccessfully.\r
- @retval EFI_TIMEOUT The operation is time out.\r
- @retval EFI_SUCCESS The command stop successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciStopCommand (\r
- IN UINT8 Port,\r
- IN UINT64 Timeout\r
- )\r
-{\r
- UINT32 Offset;\r
- UINT32 Data;\r
-\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;\r
- Data = AhciReadReg (Offset);\r
-\r
- if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) == 0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if ((Data & EFI_AHCI_PORT_CMD_ST) != 0) {\r
- AhciAndReg (Offset, (UINT32)~(EFI_AHCI_PORT_CMD_ST));\r
- }\r
-\r
- return AhciWaitMmioSet (\r
- Offset,\r
- EFI_AHCI_PORT_CMD_CR,\r
- 0,\r
- Timeout\r
- );\r
-}\r
-\r
-/**\r
- Start command for give slot on specific port.\r
-\r
- @param Port The number of port.\r
- @param CommandSlot The number of CommandSlot.\r
- @param Timeout The timeout Value of start.\r
-\r
- @retval EFI_DEVICE_ERROR The command start unsuccessfully.\r
- @retval EFI_TIMEOUT The operation is time out.\r
- @retval EFI_SUCCESS The command start successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciStartCommand (\r
- IN UINT8 Port,\r
- IN UINT8 CommandSlot,\r
- IN UINT64 Timeout\r
- )\r
-{\r
- UINT32 CmdSlotBit;\r
- EFI_STATUS Status;\r
- UINT32 PortStatus;\r
- UINT32 StartCmd;\r
- UINT32 PortTfd;\r
- UINT32 Offset;\r
- UINT32 Capability;\r
-\r
- //\r
- // Collect AHCI controller information\r
- //\r
- Capability = AhciReadReg(EFI_AHCI_CAPABILITY_OFFSET);\r
-\r
- CmdSlotBit = (UINT32) (1 << CommandSlot);\r
-\r
- AhciClearPortStatus (\r
- Port\r
- );\r
-\r
- Status = AhciEnableFisReceive (\r
- Port,\r
- Timeout\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;\r
- PortStatus = AhciReadReg (Offset);\r
-\r
- StartCmd = 0;\r
- if ((PortStatus & EFI_AHCI_PORT_CMD_ALPE) != 0) {\r
- StartCmd = AhciReadReg (Offset);\r
- StartCmd &= ~EFI_AHCI_PORT_CMD_ICC_MASK;\r
- StartCmd |= EFI_AHCI_PORT_CMD_ACTIVE;\r
- }\r
-\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;\r
- PortTfd = AhciReadReg (Offset);\r
-\r
- if ((PortTfd & (EFI_AHCI_PORT_TFD_BSY | EFI_AHCI_PORT_TFD_DRQ)) != 0) {\r
- if ((Capability & BIT24) != 0) {\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;\r
- AhciOrReg (Offset, EFI_AHCI_PORT_CMD_COL);\r
-\r
- AhciWaitMmioSet (\r
- Offset,\r
- EFI_AHCI_PORT_CMD_COL,\r
- 0,\r
- Timeout\r
- );\r
- }\r
- }\r
-\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;\r
- AhciOrReg (Offset, EFI_AHCI_PORT_CMD_ST | StartCmd);\r
-\r
- //\r
- // Setting the command\r
- //\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SACT;\r
- AhciAndReg (Offset, 0);\r
- AhciOrReg (Offset, CmdSlotBit);\r
-\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI;\r
- AhciAndReg (Offset, 0);\r
- AhciOrReg (Offset, CmdSlotBit);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Do AHCI HBA reset.\r
-\r
- @param[in] Timeout The timeout Value of reset.\r
-\r
- @retval EFI_DEVICE_ERROR AHCI controller is failed to complete hardware reset.\r
- @retval EFI_TIMEOUT The reset operation is time out.\r
- @retval EFI_SUCCESS AHCI controller is reset successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciReset (\r
- IN UINT64 Timeout\r
- )\r
-{\r
- UINT32 Delay;\r
- UINT32 Value;\r
- UINT32 Capability;\r
-\r
- //\r
- // Collect AHCI controller information\r
- //\r
- Capability = AhciReadReg (EFI_AHCI_CAPABILITY_OFFSET);\r
-\r
- //\r
- // Enable AE before accessing any AHCI registers if Supports AHCI Mode Only is not set\r
- //\r
- if ((Capability & EFI_AHCI_CAP_SAM) == 0) {\r
- AhciOrReg (EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE);\r
- }\r
-\r
- AhciOrReg (EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_RESET);\r
-\r
- Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
-\r
- do {\r
- Value = AhciReadReg(EFI_AHCI_GHC_OFFSET);\r
- if ((Value & EFI_AHCI_GHC_RESET) == 0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Stall for 100 microseconds.\r
- //\r
- MicroSecondDelay(100);\r
-\r
- Delay--;\r
- } while (Delay > 0);\r
-\r
- return EFI_TIMEOUT;\r
-\r
-\r
-}\r
-\r
-/**\r
- Send Buffer cmd to specific device.\r
-\r
- @param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.\r
- @param[in] Port The port number of attached ATA device.\r
- @param[in] PortMultiplier The port number of port multiplier of attached ATA device.\r
- @param[in, out] Buffer The Data Buffer to store IDENTIFY PACKET Data.\r
-\r
- @retval EFI_DEVICE_ERROR The cmd abort with error occurs.\r
- @retval EFI_TIMEOUT The operation is time out.\r
- @retval EFI_UNSUPPORTED The device is not ready for executing.\r
- @retval EFI_SUCCESS The cmd executes successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciIdentify (\r
- IN EFI_AHCI_REGISTERS *AhciRegisters,\r
- IN UINT8 Port,\r
- IN UINT8 PortMultiplier,\r
- IN OUT ATA_IDENTIFY_DATA *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_ATA_COMMAND_BLOCK AtaCommandBlock;\r
-\r
- if (AhciRegisters == NULL || Buffer == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));\r
-\r
- AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DRIVE;\r
- AtaCommandBlock.AtaSectorCount = 1;\r
-\r
- Status = AhciPioTransfer (\r
- AhciRegisters,\r
- Port,\r
- PortMultiplier,\r
- NULL,\r
- 0,\r
- TRUE,\r
- &AtaCommandBlock,\r
- NULL,\r
- Buffer,\r
- sizeof (ATA_IDENTIFY_DATA),\r
- ATA_TIMEOUT\r
- );\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Get AHCI mode MMIO Bar Size.\r
-\r
- @param[in] Bus The bus number of ata host controller.\r
- @param[in] Device The device number of ata host controller.\r
- @param[in] Function The function number of ata host controller.\r
-\r
- @retval The Size of AHCI MMIO BAR.\r
-\r
-**/\r
-UINT32\r
-EFIAPI\r
-GetAhciBarSize (\r
- IN UINTN Bus,\r
- IN UINTN Device,\r
- IN UINTN Function\r
- )\r
-{\r
- UINT32 Size;\r
- UINT32 OldBar;\r
-\r
- OldBar = PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x24));\r
- //\r
- // Disable PCI CMD.MSE bit before calculating MMIO Bar Size as it needs write all 1 to BAR register.\r
- //\r
- PciAnd32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x04), (UINT32)~BIT1);\r
-\r
- //\r
- // Get AHCI MMIO Bar Size.\r
- //\r
- PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x24), 0xFFFFFFFF);\r
- Size = PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x24));\r
- Size = (~(Size & 0xFFFFFFF0)) + 1;\r
-\r
- //\r
- // Restore old MMIO Bar.\r
- //\r
- PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x24), OldBar);\r
- //\r
- // Enable PCI CMD.MSE bit after restoring MMIO Bar.\r
- //\r
- PciOr32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x04), BIT1);\r
-\r
- return Size;\r
-}\r
-\r
-/**\r
- Get AHCI mode base address registers' Value.\r
-\r
- @param[in] Bus The bus number of ata host controller.\r
- @param[in] Device The device number of ata host controller.\r
- @param[in] Function The function number of ata host controller.\r
-\r
- @retval EFI_UNSUPPORTED Return this Value when the BARs is not IO type\r
- @retval EFI_SUCCESS Get the Base address successfully\r
- @retval Other Read the pci configureation Data error\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetAhciBaseAddress (\r
- IN UINTN Bus,\r
- IN UINTN Device,\r
- IN UINTN Function\r
- )\r
-{\r
- UINT32 Size;\r
-\r
- //\r
- // Get AHCI MMIO Bar\r
- //\r
- mAhciBar = PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x24));\r
- //\r
- // Get AHCI MMIO Bar Size\r
- //\r
- Size = GetAhciBarSize (Bus, Device, Function);\r
- //\r
- // Check if the AHCI Bar region is in SMRAM to avoid malicious attack by modifying MMIO Bar to point to SMRAM.\r
- //\r
- if (!SmmIsMmioValid ((EFI_PHYSICAL_ADDRESS)mAhciBar, Size, NULL)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Allocate transfer-related Data struct which is used at AHCI mode.\r
-\r
- @retval EFI_OUT_OF_RESOURCE The allocation is failure.\r
- @retval EFI_SUCCESS Successful to allocate memory.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciAllocateResource (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_PHYSICAL_ADDRESS Base;\r
-\r
- //\r
- // Allocate resources required by AHCI host controller.\r
- //\r
- Base = 0xFFFFFFFF;\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiACPIMemoryNVS,\r
- EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_RECEIVED_FIS)),\r
- &Base\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- ZeroMem ((VOID *)(UINTN)Base, EFI_PAGE_SIZE * EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_RECEIVED_FIS)));\r
- mAhciRegisters.AhciRFis = (VOID *)(UINTN)Base;\r
-\r
- Base = 0xFFFFFFFF;\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiACPIMemoryNVS,\r
- EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_LIST)),\r
- &Base\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)mAhciRegisters.AhciRFis, EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_RECEIVED_FIS)));\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- ZeroMem ((VOID *)(UINTN)Base, EFI_PAGE_SIZE * EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_LIST)));\r
- mAhciRegisters.AhciCmdList = (VOID *)(UINTN)Base;\r
-\r
- Base = 0xFFFFFFFF;\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiACPIMemoryNVS,\r
- EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_TABLE)),\r
- &Base\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)mAhciRegisters.AhciRFis, EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_RECEIVED_FIS)));\r
- gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)mAhciRegisters.AhciCmdList, EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_LIST)));\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- ZeroMem ((VOID *)(UINTN)Base, EFI_PAGE_SIZE * EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_TABLE)));\r
- mAhciRegisters.AhciCommandTable = (VOID *)(UINTN)Base;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Free allocated transfer-related Data struct which is used at AHCI mode.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-AhciFreeResource (\r
- VOID\r
- )\r
-{\r
- if (mAhciRegisters.AhciRFis != NULL) {\r
- gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)mAhciRegisters.AhciRFis, EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_RECEIVED_FIS)));\r
- }\r
-\r
- if (mAhciRegisters.AhciCmdList != NULL) {\r
- gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)mAhciRegisters.AhciCmdList, EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_LIST)));\r
- }\r
-\r
- if (mAhciRegisters.AhciCommandTable != NULL) {\r
- gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)mAhciRegisters.AhciCommandTable, EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_TABLE)));\r
- }\r
-}\r
-\r
-/**\r
- Initialize ATA host controller at AHCI mode.\r
-\r
- The function is designed to initialize ATA host controller.\r
-\r
- @param[in] Port The port number to do initialization.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciModeInitialize (\r
- UINT8 Port\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 Capability;\r
- UINT32 Offset;\r
- UINT32 Data;\r
- UINT32 PhyDetectDelay;\r
-\r
- Status = AhciReset (ATA_TIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Collect AHCI controller information\r
- //\r
- Capability = AhciReadReg (EFI_AHCI_CAPABILITY_OFFSET);\r
-\r
- //\r
- // Enable AE before accessing any AHCI registers if Supports AHCI Mode Only is not set\r
- //\r
- if ((Capability & EFI_AHCI_CAP_SAM) == 0) {\r
- AhciOrReg (EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE);\r
- }\r
-\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FB;\r
- AhciWriteReg (Offset, (UINT32)(UINTN)mAhciRegisters.AhciRFis);\r
-\r
- //\r
- // Single task envrionment, we only use one command table for all port\r
- //\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLB;\r
- AhciWriteReg (Offset, (UINT32)(UINTN)mAhciRegisters.AhciCmdList);\r
-\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;\r
- Data = AhciReadReg (Offset);\r
- if ((Data & EFI_AHCI_PORT_CMD_CPD) != 0) {\r
- AhciOrReg (Offset, EFI_AHCI_PORT_CMD_POD);\r
- }\r
-\r
- if ((Capability & BIT27) != 0) {\r
- AhciOrReg (Offset, EFI_AHCI_PORT_CMD_SUD);\r
- }\r
-\r
- //\r
- // Disable aggressive power management.\r
- //\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SCTL;\r
- AhciOrReg (Offset, EFI_AHCI_PORT_SCTL_IPM_INIT);\r
- //\r
- // Disable the reporting of the corresponding interrupt to system software.\r
- //\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IE;\r
- AhciAndReg (Offset, 0);\r
-\r
- Status = AhciEnableFisReceive (\r
- Port,\r
- EFI_TIMER_PERIOD_MILLISECONDS(500)\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // According to SATA1.0a spec section 5.2, we need to wait for PxTFD.BSY and PxTFD.DRQ\r
- // and PxTFD.ERR to be zero. The maximum wait time is 16s which is defined at ATA spec.\r
- //\r
- PhyDetectDelay = 16 * 1000;\r
- do {\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SERR;\r
- if (AhciReadReg(Offset) != 0) {\r
- AhciWriteReg (Offset, AhciReadReg(Offset));\r
- }\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;\r
-\r
- Data = AhciReadReg (Offset) & EFI_AHCI_PORT_TFD_MASK;\r
- if (Data == 0) {\r
- break;\r
- }\r
-\r
- MicroSecondDelay (1000);\r
- PhyDetectDelay--;\r
- } while (PhyDetectDelay > 0);\r
-\r
- if (PhyDetectDelay == 0) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SIG;\r
- Status = AhciWaitMmioSet (\r
- Offset,\r
- 0x0000FFFF,\r
- 0x00000101,\r
- EFI_TIMER_PERIOD_SECONDS(16)\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
+++ /dev/null
-/** @file\r
- Header file for AHCI mode of ATA host controller.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-\r
-#ifndef __OPAL_PASSWORD_AHCI_MODE_H__\r
-#define __OPAL_PASSWORD_AHCI_MODE_H__\r
-\r
-//\r
-// OPAL LIBRARY CALLBACKS\r
-//\r
-#define ATA_COMMAND_TRUSTED_RECEIVE 0x5C\r
-#define ATA_COMMAND_TRUSTED_SEND 0x5E\r
-\r
-//\r
-// ATA TRUSTED commands express transfer Length in 512 byte multiple\r
-//\r
-#define ATA_TRUSTED_TRANSFER_LENGTH_MULTIPLE 512\r
-#define ATA_DEVICE_LBA 0x40 ///< Set for commands with LBA (rather than CHS) addresses\r
-\r
-\r
-#define EFI_AHCI_BAR_INDEX 0x05\r
-\r
-#define EFI_AHCI_CAPABILITY_OFFSET 0x0000\r
-#define EFI_AHCI_CAP_SAM BIT18\r
-#define EFI_AHCI_GHC_OFFSET 0x0004\r
-#define EFI_AHCI_GHC_RESET BIT0\r
-#define EFI_AHCI_GHC_IE BIT1\r
-#define EFI_AHCI_GHC_ENABLE BIT31\r
-#define EFI_AHCI_IS_OFFSET 0x0008\r
-#define EFI_AHCI_PI_OFFSET 0x000C\r
-\r
-typedef struct {\r
- UINT32 Lower32;\r
- UINT32 Upper32;\r
-} DATA_32;\r
-\r
-typedef union {\r
- DATA_32 Uint32;\r
- UINT64 Uint64;\r
-} DATA_64;\r
-\r
-//\r
-// Each PRDT entry can point to a memory block up to 4M byte\r
-//\r
-#define EFI_AHCI_MAX_DATA_PER_PRDT 0x400000\r
-\r
-#define EFI_AHCI_FIS_REGISTER_H2D 0x27 //Register FIS - Host to Device\r
-#define EFI_AHCI_FIS_REGISTER_H2D_LENGTH 20\r
-#define EFI_AHCI_FIS_REGISTER_D2H 0x34 //Register FIS - Device to Host\r
-#define EFI_AHCI_FIS_REGISTER_D2H_LENGTH 20\r
-#define EFI_AHCI_FIS_DMA_ACTIVATE 0x39 //DMA Activate FIS - Device to Host\r
-#define EFI_AHCI_FIS_DMA_ACTIVATE_LENGTH 4\r
-#define EFI_AHCI_FIS_DMA_SETUP 0x41 //DMA Setup FIS - Bi-directional\r
-#define EFI_AHCI_FIS_DMA_SETUP_LENGTH 28\r
-#define EFI_AHCI_FIS_DATA 0x46 //Data FIS - Bi-directional\r
-#define EFI_AHCI_FIS_BIST 0x58 //BIST Activate FIS - Bi-directional\r
-#define EFI_AHCI_FIS_BIST_LENGTH 12\r
-#define EFI_AHCI_FIS_PIO_SETUP 0x5F //PIO Setup FIS - Device to Host\r
-#define EFI_AHCI_FIS_PIO_SETUP_LENGTH 20\r
-#define EFI_AHCI_FIS_SET_DEVICE 0xA1 //Set Device Bits FIS - Device to Host\r
-#define EFI_AHCI_FIS_SET_DEVICE_LENGTH 8\r
-\r
-#define EFI_AHCI_D2H_FIS_OFFSET 0x40\r
-#define EFI_AHCI_DMA_FIS_OFFSET 0x00\r
-#define EFI_AHCI_PIO_FIS_OFFSET 0x20\r
-#define EFI_AHCI_SDB_FIS_OFFSET 0x58\r
-#define EFI_AHCI_FIS_TYPE_MASK 0xFF\r
-#define EFI_AHCI_U_FIS_OFFSET 0x60\r
-\r
-//\r
-// Port register\r
-//\r
-#define EFI_AHCI_PORT_START 0x0100\r
-#define EFI_AHCI_PORT_REG_WIDTH 0x0080\r
-#define EFI_AHCI_PORT_CLB 0x0000\r
-#define EFI_AHCI_PORT_CLBU 0x0004\r
-#define EFI_AHCI_PORT_FB 0x0008\r
-#define EFI_AHCI_PORT_FBU 0x000C\r
-#define EFI_AHCI_PORT_IS 0x0010\r
-#define EFI_AHCI_PORT_IS_DHRS BIT0\r
-#define EFI_AHCI_PORT_IS_PSS BIT1\r
-#define EFI_AHCI_PORT_IS_SSS BIT2\r
-#define EFI_AHCI_PORT_IS_SDBS BIT3\r
-#define EFI_AHCI_PORT_IS_UFS BIT4\r
-#define EFI_AHCI_PORT_IS_DPS BIT5\r
-#define EFI_AHCI_PORT_IS_PCS BIT6\r
-#define EFI_AHCI_PORT_IS_DIS BIT7\r
-#define EFI_AHCI_PORT_IS_PRCS BIT22\r
-#define EFI_AHCI_PORT_IS_IPMS BIT23\r
-#define EFI_AHCI_PORT_IS_OFS BIT24\r
-#define EFI_AHCI_PORT_IS_INFS BIT26\r
-#define EFI_AHCI_PORT_IS_IFS BIT27\r
-#define EFI_AHCI_PORT_IS_HBDS BIT28\r
-#define EFI_AHCI_PORT_IS_HBFS BIT29\r
-#define EFI_AHCI_PORT_IS_TFES BIT30\r
-#define EFI_AHCI_PORT_IS_CPDS BIT31\r
-#define EFI_AHCI_PORT_IS_CLEAR 0xFFFFFFFF\r
-#define EFI_AHCI_PORT_IS_FIS_CLEAR 0x0000000F\r
-\r
-#define EFI_AHCI_PORT_IE 0x0014\r
-#define EFI_AHCI_PORT_CMD 0x0018\r
-#define EFI_AHCI_PORT_CMD_ST_MASK 0xFFFFFFFE\r
-#define EFI_AHCI_PORT_CMD_ST BIT0\r
-#define EFI_AHCI_PORT_CMD_SUD BIT1\r
-#define EFI_AHCI_PORT_CMD_POD BIT2\r
-#define EFI_AHCI_PORT_CMD_COL BIT3\r
-#define EFI_AHCI_PORT_CMD_CR BIT15\r
-#define EFI_AHCI_PORT_CMD_FRE BIT4\r
-#define EFI_AHCI_PORT_CMD_FR BIT14\r
-#define EFI_AHCI_PORT_CMD_MASK ~(EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_FRE | EFI_AHCI_PORT_CMD_COL)\r
-#define EFI_AHCI_PORT_CMD_PMA BIT17\r
-#define EFI_AHCI_PORT_CMD_HPCP BIT18\r
-#define EFI_AHCI_PORT_CMD_MPSP BIT19\r
-#define EFI_AHCI_PORT_CMD_CPD BIT20\r
-#define EFI_AHCI_PORT_CMD_ESP BIT21\r
-#define EFI_AHCI_PORT_CMD_ATAPI BIT24\r
-#define EFI_AHCI_PORT_CMD_DLAE BIT25\r
-#define EFI_AHCI_PORT_CMD_ALPE BIT26\r
-#define EFI_AHCI_PORT_CMD_ASP BIT27\r
-#define EFI_AHCI_PORT_CMD_ICC_MASK (BIT28 | BIT29 | BIT30 | BIT31)\r
-#define EFI_AHCI_PORT_CMD_ACTIVE (1 << 28 )\r
-#define EFI_AHCI_PORT_TFD 0x0020\r
-#define EFI_AHCI_PORT_TFD_MASK (BIT7 | BIT3 | BIT0)\r
-#define EFI_AHCI_PORT_TFD_BSY BIT7\r
-#define EFI_AHCI_PORT_TFD_DRQ BIT3\r
-#define EFI_AHCI_PORT_TFD_ERR BIT0\r
-#define EFI_AHCI_PORT_TFD_ERR_MASK 0x00FF00\r
-#define EFI_AHCI_PORT_SIG 0x0024\r
-#define EFI_AHCI_PORT_SSTS 0x0028\r
-#define EFI_AHCI_PORT_SSTS_DET_MASK 0x000F\r
-#define EFI_AHCI_PORT_SSTS_DET 0x0001\r
-#define EFI_AHCI_PORT_SSTS_DET_PCE 0x0003\r
-#define EFI_AHCI_PORT_SSTS_SPD_MASK 0x00F0\r
-#define EFI_AHCI_PORT_SCTL 0x002C\r
-#define EFI_AHCI_PORT_SCTL_DET_MASK 0x000F\r
-#define EFI_AHCI_PORT_SCTL_MASK (~EFI_AHCI_PORT_SCTL_DET_MASK)\r
-#define EFI_AHCI_PORT_SCTL_DET_INIT 0x0001\r
-#define EFI_AHCI_PORT_SCTL_DET_PHYCOMM 0x0003\r
-#define EFI_AHCI_PORT_SCTL_SPD_MASK 0x00F0\r
-#define EFI_AHCI_PORT_SCTL_IPM_MASK 0x0F00\r
-#define EFI_AHCI_PORT_SCTL_IPM_INIT 0x0300\r
-#define EFI_AHCI_PORT_SCTL_IPM_PSD 0x0100\r
-#define EFI_AHCI_PORT_SCTL_IPM_SSD 0x0200\r
-#define EFI_AHCI_PORT_SERR 0x0030\r
-#define EFI_AHCI_PORT_SERR_RDIE BIT0\r
-#define EFI_AHCI_PORT_SERR_RCE BIT1\r
-#define EFI_AHCI_PORT_SERR_TDIE BIT8\r
-#define EFI_AHCI_PORT_SERR_PCDIE BIT9\r
-#define EFI_AHCI_PORT_SERR_PE BIT10\r
-#define EFI_AHCI_PORT_SERR_IE BIT11\r
-#define EFI_AHCI_PORT_SERR_PRC BIT16\r
-#define EFI_AHCI_PORT_SERR_PIE BIT17\r
-#define EFI_AHCI_PORT_SERR_CW BIT18\r
-#define EFI_AHCI_PORT_SERR_BDE BIT19\r
-#define EFI_AHCI_PORT_SERR_DE BIT20\r
-#define EFI_AHCI_PORT_SERR_CRCE BIT21\r
-#define EFI_AHCI_PORT_SERR_HE BIT22\r
-#define EFI_AHCI_PORT_SERR_LSE BIT23\r
-#define EFI_AHCI_PORT_SERR_TSTE BIT24\r
-#define EFI_AHCI_PORT_SERR_UFT BIT25\r
-#define EFI_AHCI_PORT_SERR_EX BIT26\r
-#define EFI_AHCI_PORT_ERR_CLEAR 0xFFFFFFFF\r
-#define EFI_AHCI_PORT_SACT 0x0034\r
-#define EFI_AHCI_PORT_CI 0x0038\r
-#define EFI_AHCI_PORT_SNTF 0x003C\r
-\r
-\r
-#pragma pack(1)\r
-//\r
-// Command List structure includes total 32 entries.\r
-// The entry Data structure is listed at the following.\r
-//\r
-typedef struct {\r
- UINT32 AhciCmdCfl:5; //Command FIS Length\r
- UINT32 AhciCmdA:1; //ATAPI\r
- UINT32 AhciCmdW:1; //Write\r
- UINT32 AhciCmdP:1; //Prefetchable\r
- UINT32 AhciCmdR:1; //Reset\r
- UINT32 AhciCmdB:1; //BIST\r
- UINT32 AhciCmdC:1; //Clear Busy upon R_OK\r
- UINT32 AhciCmdRsvd:1;\r
- UINT32 AhciCmdPmp:4; //Port Multiplier Port\r
- UINT32 AhciCmdPrdtl:16; //Physical Region Descriptor Table Length\r
- UINT32 AhciCmdPrdbc; //Physical Region Descriptor Byte Count\r
- UINT32 AhciCmdCtba; //Command Table Descriptor Base Address\r
- UINT32 AhciCmdCtbau; //Command Table Descriptor Base Address Upper 32-BITs\r
- UINT32 AhciCmdRsvd1[4];\r
-} EFI_AHCI_COMMAND_LIST;\r
-\r
-//\r
-// This is a software constructed FIS.\r
-// For Data transfer operations, this is the H2D Register FIS format as\r
-// specified in the Serial ATA Revision 2.6 specification.\r
-//\r
-typedef struct {\r
- UINT8 AhciCFisType;\r
- UINT8 AhciCFisPmNum:4;\r
- UINT8 AhciCFisRsvd:1;\r
- UINT8 AhciCFisRsvd1:1;\r
- UINT8 AhciCFisRsvd2:1;\r
- UINT8 AhciCFisCmdInd:1;\r
- UINT8 AhciCFisCmd;\r
- UINT8 AhciCFisFeature;\r
- UINT8 AhciCFisSecNum;\r
- UINT8 AhciCFisClyLow;\r
- UINT8 AhciCFisClyHigh;\r
- UINT8 AhciCFisDevHead;\r
- UINT8 AhciCFisSecNumExp;\r
- UINT8 AhciCFisClyLowExp;\r
- UINT8 AhciCFisClyHighExp;\r
- UINT8 AhciCFisFeatureExp;\r
- UINT8 AhciCFisSecCount;\r
- UINT8 AhciCFisSecCountExp;\r
- UINT8 AhciCFisRsvd3;\r
- UINT8 AhciCFisControl;\r
- UINT8 AhciCFisRsvd4[4];\r
- UINT8 AhciCFisRsvd5[44];\r
-} EFI_AHCI_COMMAND_FIS;\r
-\r
-//\r
-// ACMD: ATAPI command (12 or 16 bytes)\r
-//\r
-typedef struct {\r
- UINT8 AtapiCmd[0x10];\r
-} EFI_AHCI_ATAPI_COMMAND;\r
-\r
-//\r
-// Physical Region Descriptor Table includes up to 65535 entries\r
-// The entry Data structure is listed at the following.\r
-// the actual entry number comes from the PRDTL field in the command\r
-// list entry for this command slot.\r
-//\r
-typedef struct {\r
- UINT32 AhciPrdtDba; //Data Base Address\r
- UINT32 AhciPrdtDbau; //Data Base Address Upper 32-BITs\r
- UINT32 AhciPrdtRsvd;\r
- UINT32 AhciPrdtDbc:22; //Data Byte Count\r
- UINT32 AhciPrdtRsvd1:9;\r
- UINT32 AhciPrdtIoc:1; //Interrupt on Completion\r
-} EFI_AHCI_COMMAND_PRDT;\r
-\r
-//\r
-// Command table Data strucute which is pointed to by the entry in the command list\r
-//\r
-typedef struct {\r
- EFI_AHCI_COMMAND_FIS CommandFis; // A software constructed FIS.\r
- EFI_AHCI_ATAPI_COMMAND AtapiCmd; // 12 or 16 bytes ATAPI cmd.\r
- UINT8 Reserved[0x30];\r
- EFI_AHCI_COMMAND_PRDT PrdtTable; // The scatter/gather list for Data transfer\r
-} EFI_AHCI_COMMAND_TABLE;\r
-\r
-//\r
-// Received FIS structure\r
-//\r
-typedef struct {\r
- UINT8 AhciDmaSetupFis[0x1C]; // Dma Setup Fis: offset 0x00\r
- UINT8 AhciDmaSetupFisRsvd[0x04];\r
- UINT8 AhciPioSetupFis[0x14]; // Pio Setup Fis: offset 0x20\r
- UINT8 AhciPioSetupFisRsvd[0x0C];\r
- UINT8 AhciD2HRegisterFis[0x14]; // D2H Register Fis: offset 0x40\r
- UINT8 AhciD2HRegisterFisRsvd[0x04];\r
- UINT64 AhciSetDeviceBitsFis; // Set Device Bits Fix: offset 0x58\r
- UINT8 AhciUnknownFis[0x40]; // Unkonwn Fis: offset 0x60\r
- UINT8 AhciUnknownFisRsvd[0x60];\r
-} EFI_AHCI_RECEIVED_FIS;\r
-\r
-#pragma pack()\r
-\r
-typedef struct {\r
- EFI_AHCI_RECEIVED_FIS *AhciRFis;\r
- EFI_AHCI_COMMAND_LIST *AhciCmdList;\r
- EFI_AHCI_COMMAND_TABLE *AhciCommandTable;\r
-} EFI_AHCI_REGISTERS;\r
-\r
-extern EFI_AHCI_REGISTERS mAhciRegisters;\r
-extern UINT32 mAhciBar;\r
-\r
-/**\r
- Send Buffer cmd to specific device.\r
-\r
- @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.\r
- @param Port The number of port.\r
- @param PortMultiplier The timeout Value of stop.\r
- @param Buffer The Data Buffer to store IDENTIFY PACKET Data.\r
-\r
- @retval EFI_DEVICE_ERROR The cmd abort with error occurs.\r
- @retval EFI_TIMEOUT The operation is time out.\r
- @retval EFI_UNSUPPORTED The device is not ready for executing.\r
- @retval EFI_SUCCESS The cmd executes successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciIdentify (\r
- IN EFI_AHCI_REGISTERS *AhciRegisters,\r
- IN UINT8 Port,\r
- IN UINT8 PortMultiplier,\r
- IN OUT ATA_IDENTIFY_DATA *Buffer\r
- );\r
-\r
-/**\r
- Get AHCI mode base address registers' Value.\r
-\r
- @param[in] Bus The bus number of ata host controller.\r
- @param[in] Device The device number of ata host controller.\r
- @param[in] Function The function number of ata host controller.\r
-\r
- @retval EFI_UNSUPPORTED Return this Value when the BARs is not IO type\r
- @retval EFI_SUCCESS Get the Base address successfully\r
- @retval Other Read the pci configureation Data error\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetAhciBaseAddress (\r
- IN UINTN Bus,\r
- IN UINTN Device,\r
- IN UINTN Function\r
- );\r
-\r
-/**\r
- Allocate transfer-related Data struct which is used at AHCI mode.\r
-\r
- @retval EFI_OUT_OF_RESOURCE The allocation is failure.\r
- @retval EFI_SUCCESS Successful to allocate memory.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciAllocateResource (\r
- VOID\r
- );\r
-\r
-/**\r
- Free allocated transfer-related Data struct which is used at AHCI mode.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-AhciFreeResource (\r
- VOID\r
- );\r
-\r
-/**\r
- Initialize ATA host controller at AHCI mode.\r
-\r
- The function is designed to initialize ATA host controller.\r
-\r
- @param[in] Port The port number to do initialization.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciModeInitialize (\r
- UINT8 Port\r
- );\r
-\r
-/**\r
- Start a PIO Data transfer on specific port.\r
-\r
- @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.\r
- @param Port The number of port.\r
- @param PortMultiplier The timeout Value of stop.\r
- @param AtapiCommand The atapi command will be used for the transfer.\r
- @param AtapiCommandLength The Length of the atapi command.\r
- @param Read The transfer direction.\r
- @param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK Data.\r
- @param AtaStatusBlock The EFI_ATA_STATUS_BLOCK Data.\r
- @param MemoryAddr The pointer to the Data Buffer.\r
- @param DataCount The Data count to be transferred.\r
- @param Timeout The timeout Value of non Data transfer.\r
-\r
- @retval EFI_DEVICE_ERROR The PIO Data transfer abort with error occurs.\r
- @retval EFI_TIMEOUT The operation is time out.\r
- @retval EFI_UNSUPPORTED The device is not ready for transfer.\r
- @retval EFI_SUCCESS The PIO Data transfer executes successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AhciPioTransfer (\r
- IN EFI_AHCI_REGISTERS *AhciRegisters,\r
- IN UINT8 Port,\r
- IN UINT8 PortMultiplier,\r
- IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,\r
- IN UINT8 AtapiCommandLength,\r
- IN BOOLEAN Read,\r
- IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,\r
- IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,\r
- IN OUT VOID *MemoryAddr,\r
- IN UINT32 DataCount,\r
- IN UINT64 Timeout\r
- );\r
-\r
-\r
-#endif\r
-\r
+++ /dev/null
-/** @file\r
- This driver is used for Opal Password Feature support at IDE mode.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "OpalPasswordSmm.h"\r
-\r
-/**\r
- Write multiple words of Data to the IDE Data port.\r
- Call the IO abstraction once to do the complete read,\r
- not one word at a time\r
-\r
- @param Port IO port to read\r
- @param Count No. of UINT16's to read\r
- @param Buffer Pointer to the Data Buffer for read\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-IdeWritePortWMultiple (\r
- IN UINT16 Port,\r
- IN UINTN Count,\r
- IN UINT16 *Buffer\r
- )\r
-{\r
- UINTN Index;\r
-\r
- for (Index = 0; Index < Count; Index++) {\r
- IoWrite16 (Port, Buffer[Index]);\r
- }\r
-}\r
-\r
-/**\r
- Reads multiple words of Data from the IDE Data port.\r
- Call the IO abstraction once to do the complete read,\r
- not one word at a time\r
-\r
- @param Port IO port to read\r
- @param Count Number of UINT16's to read\r
- @param Buffer Pointer to the Data Buffer for read\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-IdeReadPortWMultiple (\r
- IN UINT16 Port,\r
- IN UINTN Count,\r
- IN UINT16 *Buffer\r
- )\r
-{\r
- UINTN Index;\r
-\r
- for (Index = 0; Index < Count; Index++) {\r
- Buffer[Count] = IoRead16 (Port);\r
- }\r
-}\r
-\r
-/**\r
- This function is used to analyze the Status Register and print out\r
- some debug information and if there is ERR bit set in the Status\r
- Register, the Error Register's Value is also be parsed and print out.\r
-\r
- @param IdeRegisters A pointer to EFI_IDE_REGISTERS Data structure.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-DumpAllIdeRegisters (\r
- IN EFI_IDE_REGISTERS *IdeRegisters\r
- )\r
-{\r
- ASSERT (IdeRegisters != NULL);\r
-\r
- DEBUG_CODE_BEGIN ();\r
- if ((IoRead8 (IdeRegisters->CmdOrStatus) & ATA_STSREG_DWF) != 0) {\r
- DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Write Fault\n", IoRead8 (IdeRegisters->CmdOrStatus)));\r
- }\r
-\r
- if ((IoRead8 (IdeRegisters->CmdOrStatus) & ATA_STSREG_CORR) != 0) {\r
- DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Corrected Data\n", IoRead8 (IdeRegisters->CmdOrStatus)));\r
- }\r
-\r
- if ((IoRead8 (IdeRegisters->CmdOrStatus) & ATA_STSREG_ERR) != 0) {\r
- if ((IoRead8 (IdeRegisters->ErrOrFeature) & ATA_ERRREG_BBK) != 0) {\r
- DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Bad Block Detected\n", IoRead8 (IdeRegisters->ErrOrFeature)));\r
- }\r
-\r
- if ((IoRead8 (IdeRegisters->ErrOrFeature) & ATA_ERRREG_UNC) != 0) {\r
- DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Uncorrectable Data\n", IoRead8 (IdeRegisters->ErrOrFeature)));\r
- }\r
-\r
- if ((IoRead8 (IdeRegisters->ErrOrFeature) & ATA_ERRREG_MC) != 0) {\r
- DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Media Change\n", IoRead8 (IdeRegisters->ErrOrFeature)));\r
- }\r
-\r
- if ((IoRead8 (IdeRegisters->ErrOrFeature) & ATA_ERRREG_ABRT) != 0) {\r
- DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Abort\n", IoRead8 (IdeRegisters->ErrOrFeature)));\r
- }\r
-\r
- if ((IoRead8 (IdeRegisters->ErrOrFeature) & ATA_ERRREG_TK0NF) != 0) {\r
- DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Track 0 Not Found\n", IoRead8 (IdeRegisters->ErrOrFeature)));\r
- }\r
-\r
- if ((IoRead8 (IdeRegisters->ErrOrFeature) & ATA_ERRREG_AMNF) != 0) {\r
- DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Address Mark Not Found\n", IoRead8 (IdeRegisters->ErrOrFeature)));\r
- }\r
- }\r
- DEBUG_CODE_END ();\r
-}\r
-\r
-/**\r
- This function is used to analyze the Status Register and print out\r
- some debug information and if there is ERR bit set in the Status\r
- Register, the Error Register's Value is also be parsed and print out.\r
-\r
- @param IdeRegisters A pointer to EFI_IDE_REGISTERS Data structure.\r
-\r
- @retval EFI_SUCCESS No err information in the Status Register.\r
- @retval EFI_DEVICE_ERROR Any err information in the Status Register.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CheckStatusRegister (\r
- IN EFI_IDE_REGISTERS *IdeRegisters\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 StatusRegister;\r
-\r
- ASSERT (IdeRegisters != NULL);\r
-\r
- StatusRegister = IoRead8 (IdeRegisters->CmdOrStatus);\r
-\r
- if ((StatusRegister & (ATA_STSREG_ERR | ATA_STSREG_DWF | ATA_STSREG_CORR)) == 0) {\r
- Status = EFI_SUCCESS;\r
- } else {\r
- Status = EFI_DEVICE_ERROR;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- This function is used to poll for the DRQ bit clear in the Status\r
- Register. DRQ is cleared when the device is finished transferring Data.\r
- So this function is called after Data transfer is finished.\r
-\r
- @param IdeRegisters A pointer to EFI_IDE_REGISTERS Data structure.\r
- @param Timeout The time to complete the command.\r
-\r
- @retval EFI_SUCCESS DRQ bit clear within the time out.\r
- @retval EFI_TIMEOUT DRQ bit not clear within the time out.\r
-\r
- @note\r
- Read Status Register will clear interrupt status.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DRQClear (\r
- IN EFI_IDE_REGISTERS *IdeRegisters,\r
- IN UINT64 Timeout\r
- )\r
-{\r
- UINT32 Delay;\r
- UINT8 StatusRegister;\r
-\r
- ASSERT (IdeRegisters != NULL);\r
-\r
- Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
- do {\r
- StatusRegister = IoRead8 (IdeRegisters->CmdOrStatus);\r
-\r
- //\r
- // wait for BSY == 0 and DRQ == 0\r
- //\r
- if ((StatusRegister & ATA_STSREG_BSY) == 0) {\r
-\r
- if ((StatusRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {\r
- return EFI_DEVICE_ERROR;\r
- } else {\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- //\r
- // Stall for 100 microseconds.\r
- //\r
- MicroSecondDelay (100);\r
-\r
- Delay--;\r
-\r
- } while (Delay > 0);\r
-\r
- return EFI_TIMEOUT;\r
-}\r
-/**\r
- This function is used to poll for the DRQ bit clear in the Alternate\r
- Status Register. DRQ is cleared when the device is finished\r
- transferring Data. So this function is called after Data transfer\r
- is finished.\r
-\r
- @param IdeRegisters A pointer to EFI_IDE_REGISTERS Data structure.\r
- @param Timeout The time to complete the command.\r
-\r
- @retval EFI_SUCCESS DRQ bit clear within the time out.\r
-\r
- @retval EFI_TIMEOUT DRQ bit not clear within the time out.\r
- @note Read Alternate Status Register will not clear interrupt status.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DRQClear2 (\r
- IN EFI_IDE_REGISTERS *IdeRegisters,\r
- IN UINT64 Timeout\r
- )\r
-{\r
- UINT32 Delay;\r
- UINT8 AltRegister;\r
-\r
- ASSERT (IdeRegisters != NULL);\r
-\r
- Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
- do {\r
- AltRegister = IoRead8 (IdeRegisters->AltOrDev);\r
-\r
- //\r
- // wait for BSY == 0 and DRQ == 0\r
- //\r
- if ((AltRegister & ATA_STSREG_BSY) == 0) {\r
- if ((AltRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {\r
- return EFI_DEVICE_ERROR;\r
- } else {\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- //\r
- // Stall for 100 microseconds.\r
- //\r
- MicroSecondDelay (100);\r
-\r
- Delay--;\r
-\r
- } while (Delay > 0);\r
-\r
- return EFI_TIMEOUT;\r
-}\r
-\r
-\r
-/**\r
- This function is used to poll for the DRQ bit set in the Alternate Status Register.\r
- DRQ is set when the device is ready to transfer Data. So this function is called after\r
- the command is sent to the device and before required Data is transferred.\r
-\r
- @param IdeRegisters A pointer to EFI_IDE_REGISTERS Data structure.\r
- @param Timeout The time to complete the command.\r
-\r
- @retval EFI_SUCCESS DRQ bit set within the time out.\r
- @retval EFI_TIMEOUT DRQ bit not set within the time out.\r
- @retval EFI_ABORTED DRQ bit not set caused by the command abort.\r
- @note Read Alternate Status Register will not clear interrupt status.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DRQReady2 (\r
- IN EFI_IDE_REGISTERS *IdeRegisters,\r
- IN UINT64 Timeout\r
- )\r
-{\r
- UINT32 Delay;\r
- UINT8 AltRegister;\r
- UINT8 ErrorRegister;\r
-\r
- ASSERT (IdeRegisters != NULL);\r
-\r
- Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
-\r
- do {\r
- //\r
- // Read Alternate Status Register will not clear interrupt status\r
- //\r
- AltRegister = IoRead8 (IdeRegisters->AltOrDev);\r
- //\r
- // BSY == 0 , DRQ == 1\r
- //\r
- if ((AltRegister & ATA_STSREG_BSY) == 0) {\r
- if ((AltRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {\r
- ErrorRegister = IoRead8 (IdeRegisters->ErrOrFeature);\r
-\r
- if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
- return EFI_ABORTED;\r
- }\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- if ((AltRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {\r
- return EFI_SUCCESS;\r
- } else {\r
- return EFI_NOT_READY;\r
- }\r
- }\r
-\r
- //\r
- // Stall for 100 microseconds.\r
- //\r
- MicroSecondDelay (100);\r
-\r
- Delay--;\r
- } while (Delay > 0);\r
-\r
- return EFI_TIMEOUT;\r
-}\r
-\r
-/**\r
- This function is used to poll for the BSY bit clear in the Status Register. BSY\r
- is clear when the device is not busy. Every command must be sent after device is not busy.\r
-\r
- @param IdeRegisters A pointer to EFI_IDE_REGISTERS Data structure.\r
- @param Timeout The time to complete the command.\r
-\r
- @retval EFI_SUCCESS BSY bit clear within the time out.\r
- @retval EFI_TIMEOUT BSY bit not clear within the time out.\r
-\r
- @note Read Status Register will clear interrupt status.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-WaitForBSYClear (\r
- IN EFI_IDE_REGISTERS *IdeRegisters,\r
- IN UINT64 Timeout\r
- )\r
-{\r
- UINT32 Delay;\r
- UINT8 StatusRegister;\r
-\r
- ASSERT (IdeRegisters != NULL);\r
-\r
- Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
- do {\r
- StatusRegister = IoRead8 (IdeRegisters->CmdOrStatus);\r
-\r
- if ((StatusRegister & ATA_STSREG_BSY) == 0x00) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Stall for 100 microseconds.\r
- //\r
- MicroSecondDelay (100);\r
-\r
- Delay--;\r
-\r
- } while (Delay > 0);\r
-\r
- return EFI_TIMEOUT;\r
-}\r
-\r
-/**\r
- Get IDE i/o port registers' base addresses by mode.\r
-\r
- In 'Compatibility' mode, use fixed addresses.\r
- In Native-PCI mode, get base addresses from BARs in the PCI IDE controller's\r
- Configuration Space.\r
-\r
- The steps to get IDE i/o port registers' base addresses for each channel\r
- as follows:\r
-\r
- 1. Examine the Programming Interface byte of the Class Code fields in PCI IDE\r
- controller's Configuration Space to determine the operating mode.\r
-\r
- 2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.\r
- ___________________________________________\r
- | | Command Block | Control Block |\r
- | Channel | Registers | Registers |\r
- |___________|_______________|_______________|\r
- | Primary | 1F0h - 1F7h | 3F6h - 3F7h |\r
- |___________|_______________|_______________|\r
- | Secondary | 170h - 177h | 376h - 377h |\r
- |___________|_______________|_______________|\r
-\r
- Table 1. Compatibility resource mappings\r
-\r
- b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs\r
- in IDE controller's PCI Configuration Space, shown in the Table 2 below.\r
- ___________________________________________________\r
- | | Command Block | Control Block |\r
- | Channel | Registers | Registers |\r
- |___________|___________________|___________________|\r
- | Primary | BAR at offset 0x10| BAR at offset 0x14|\r
- |___________|___________________|___________________|\r
- | Secondary | BAR at offset 0x18| BAR at offset 0x1C|\r
- |___________|___________________|___________________|\r
-\r
- Table 2. BARs for Register Mapping\r
-\r
- @param[in] Bus The bus number of ata host controller.\r
- @param[in] Device The device number of ata host controller.\r
- @param[in] Function The function number of ata host controller.\r
- @param[in, out] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to\r
- store the IDE i/o port registers' base addresses\r
-\r
- @retval EFI_UNSUPPORTED Return this Value when the BARs is not IO type\r
- @retval EFI_SUCCESS Get the Base address successfully\r
- @retval Other Read the pci configureation Data error\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetIdeRegisterIoAddr (\r
- IN UINTN Bus,\r
- IN UINTN Device,\r
- IN UINTN Function,\r
- IN OUT EFI_IDE_REGISTERS *IdeRegisters\r
- )\r
-{\r
- UINT16 CommandBlockBaseAddr;\r
- UINT16 ControlBlockBaseAddr;\r
- UINT8 ClassCode;\r
- UINT32 BaseAddress[4];\r
-\r
- if (IdeRegisters == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- ClassCode = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x9));\r
- BaseAddress[0] = PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x10));\r
- BaseAddress[1] = PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x14));\r
- BaseAddress[2] = PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x18));\r
- BaseAddress[3] = PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x1C));\r
-\r
- if ((ClassCode & IDE_PRIMARY_OPERATING_MODE) == 0) {\r
- CommandBlockBaseAddr = 0x1f0;\r
- ControlBlockBaseAddr = 0x3f6;\r
- } else {\r
- //\r
- // The BARs should be of IO type\r
- //\r
- if ((BaseAddress[0] & BIT0) == 0 ||\r
- (BaseAddress[1] & BIT0) == 0) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- CommandBlockBaseAddr = (UINT16) (BaseAddress[0] & 0x0000fff8);\r
- ControlBlockBaseAddr = (UINT16) ((BaseAddress[1] & 0x0000fffc) + 2);\r
- }\r
-\r
- //\r
- // Calculate IDE primary channel I/O register base address.\r
- //\r
- IdeRegisters[EfiIdePrimary].Data = CommandBlockBaseAddr;\r
- IdeRegisters[EfiIdePrimary].ErrOrFeature = (UINT16) (CommandBlockBaseAddr + 0x01);\r
- IdeRegisters[EfiIdePrimary].SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);\r
- IdeRegisters[EfiIdePrimary].SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);\r
- IdeRegisters[EfiIdePrimary].CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);\r
- IdeRegisters[EfiIdePrimary].CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);\r
- IdeRegisters[EfiIdePrimary].Head = (UINT16) (CommandBlockBaseAddr + 0x06);\r
- IdeRegisters[EfiIdePrimary].CmdOrStatus = (UINT16) (CommandBlockBaseAddr + 0x07);\r
- IdeRegisters[EfiIdePrimary].AltOrDev = ControlBlockBaseAddr;\r
-\r
- if ((ClassCode & IDE_SECONDARY_OPERATING_MODE) == 0) {\r
- CommandBlockBaseAddr = 0x170;\r
- ControlBlockBaseAddr = 0x376;\r
- } else {\r
- //\r
- // The BARs should be of IO type\r
- //\r
- if ((BaseAddress[2] & BIT0) == 0 ||\r
- (BaseAddress[3] & BIT0) == 0) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- CommandBlockBaseAddr = (UINT16) (BaseAddress[2] & 0x0000fff8);\r
- ControlBlockBaseAddr = (UINT16) ((BaseAddress[3] & 0x0000fffc) + 2);\r
- }\r
-\r
- //\r
- // Calculate IDE secondary channel I/O register base address.\r
- //\r
- IdeRegisters[EfiIdeSecondary].Data = CommandBlockBaseAddr;\r
- IdeRegisters[EfiIdeSecondary].ErrOrFeature = (UINT16) (CommandBlockBaseAddr + 0x01);\r
- IdeRegisters[EfiIdeSecondary].SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);\r
- IdeRegisters[EfiIdeSecondary].SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);\r
- IdeRegisters[EfiIdeSecondary].CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);\r
- IdeRegisters[EfiIdeSecondary].CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);\r
- IdeRegisters[EfiIdeSecondary].Head = (UINT16) (CommandBlockBaseAddr + 0x06);\r
- IdeRegisters[EfiIdeSecondary].CmdOrStatus = (UINT16) (CommandBlockBaseAddr + 0x07);\r
- IdeRegisters[EfiIdeSecondary].AltOrDev = ControlBlockBaseAddr;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Send ATA Ext command into device with NON_DATA protocol.\r
-\r
- @param IdeRegisters A pointer to EFI_IDE_REGISTERS Data structure.\r
- @param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK Data structure.\r
- @param Timeout The time to complete the command.\r
-\r
- @retval EFI_SUCCESS Reading succeed\r
- @retval EFI_DEVICE_ERROR Error executing commands on this device.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AtaIssueCommand (\r
- IN EFI_IDE_REGISTERS *IdeRegisters,\r
- IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,\r
- IN UINT64 Timeout\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 DeviceHead;\r
- UINT8 AtaCommand;\r
-\r
- ASSERT (IdeRegisters != NULL);\r
- ASSERT (AtaCommandBlock != NULL);\r
-\r
- DeviceHead = AtaCommandBlock->AtaDeviceHead;\r
- AtaCommand = AtaCommandBlock->AtaCommand;\r
-\r
- Status = WaitForBSYClear (IdeRegisters, Timeout);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
- //\r
- IoWrite8 (IdeRegisters->Head, (UINT8) (0xe0 | DeviceHead));\r
-\r
- //\r
- // set all the command parameters\r
- // Before write to all the following registers, BSY and DRQ must be 0.\r
- //\r
- Status = DRQClear2 (IdeRegisters, Timeout);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Fill the feature register, which is a two-byte FIFO. Need write twice.\r
- //\r
- IoWrite8 (IdeRegisters->ErrOrFeature, AtaCommandBlock->AtaFeaturesExp);\r
- IoWrite8 (IdeRegisters->ErrOrFeature, AtaCommandBlock->AtaFeatures);\r
-\r
- //\r
- // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
- //\r
- IoWrite8 (IdeRegisters->SectorCount, AtaCommandBlock->AtaSectorCountExp);\r
- IoWrite8 (IdeRegisters->SectorCount, AtaCommandBlock->AtaSectorCount);\r
-\r
- //\r
- // Fill the start LBA registers, which are also two-byte FIFO\r
- //\r
- IoWrite8 (IdeRegisters->SectorNumber, AtaCommandBlock->AtaSectorNumberExp);\r
- IoWrite8 (IdeRegisters->SectorNumber, AtaCommandBlock->AtaSectorNumber);\r
-\r
- IoWrite8 (IdeRegisters->CylinderLsb, AtaCommandBlock->AtaCylinderLowExp);\r
- IoWrite8 (IdeRegisters->CylinderLsb, AtaCommandBlock->AtaCylinderLow);\r
-\r
- IoWrite8 (IdeRegisters->CylinderMsb, AtaCommandBlock->AtaCylinderHighExp);\r
- IoWrite8 (IdeRegisters->CylinderMsb, AtaCommandBlock->AtaCylinderHigh);\r
-\r
- //\r
- // Send command via Command Register\r
- //\r
- IoWrite8 (IdeRegisters->CmdOrStatus, AtaCommand);\r
-\r
- //\r
- // Stall at least 400 microseconds.\r
- //\r
- MicroSecondDelay (400);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is used to send out ATA commands conforms to the PIO Data In Protocol.\r
-\r
- @param IdeRegisters A pointer to EFI_IDE_REGISTERS Data structure.\r
- @param Buffer A pointer to the source Buffer for the Data.\r
- @param ByteCount The Length of the Data.\r
- @param Read Flag used to determine the Data transfer direction.\r
- Read equals 1, means Data transferred from device to host;\r
- Read equals 0, means Data transferred from host to device.\r
- @param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK Data structure.\r
- @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK Data structure.\r
- @param Timeout The time to complete the command.\r
-\r
- @retval EFI_SUCCESS send out the ATA command and device send required Data successfully.\r
- @retval EFI_DEVICE_ERROR command sent failed.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AtaPioDataInOut (\r
- IN EFI_IDE_REGISTERS *IdeRegisters,\r
- IN OUT VOID *Buffer,\r
- IN UINT64 ByteCount,\r
- IN BOOLEAN Read,\r
- IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,\r
- IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,\r
- IN UINT64 Timeout\r
- )\r
-{\r
- UINTN WordCount;\r
- UINTN Increment;\r
- UINT16 *Buffer16;\r
- EFI_STATUS Status;\r
-\r
- if ((IdeRegisters == NULL) || (Buffer == NULL) || (AtaCommandBlock == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Issue ATA command\r
- //\r
- Status = AtaIssueCommand (IdeRegisters, AtaCommandBlock, Timeout);\r
- if (EFI_ERROR (Status)) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Exit;\r
- }\r
-\r
- Buffer16 = (UINT16 *) Buffer;\r
-\r
- //\r
- // According to PIO Data in protocol, host can perform a series of reads to\r
- // the Data register after each time device set DRQ ready;\r
- // The Data Size of "a series of read" is command specific.\r
- // For most ATA command, Data Size received from device will not exceed\r
- // 1 sector, hence the Data Size for "a series of read" can be the whole Data\r
- // Size of one command request.\r
- // For ATA command such as Read Sector command, the Data Size of one ATA\r
- // command request is often larger than 1 sector, according to the\r
- // Read Sector command, the Data Size of "a series of read" is exactly 1\r
- // sector.\r
- // Here for simplification reason, we specify the Data Size for\r
- // "a series of read" to 1 sector (256 words) if Data Size of one ATA command\r
- // request is larger than 256 words.\r
- //\r
- Increment = 256;\r
-\r
- //\r
- // used to record bytes of currently transfered Data\r
- //\r
- WordCount = 0;\r
-\r
- while (WordCount < RShiftU64(ByteCount, 1)) {\r
- //\r
- // Poll DRQ bit set, Data transfer can be performed only when DRQ is ready\r
- //\r
- Status = DRQReady2 (IdeRegisters, Timeout);\r
- if (EFI_ERROR (Status)) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Exit;\r
- }\r
-\r
- //\r
- // Get the byte count for one series of read\r
- //\r
- if ((WordCount + Increment) > RShiftU64(ByteCount, 1)) {\r
- Increment = (UINTN)(RShiftU64(ByteCount, 1) - WordCount);\r
- }\r
-\r
- if (Read) {\r
- IdeReadPortWMultiple (\r
- IdeRegisters->Data,\r
- Increment,\r
- Buffer16\r
- );\r
- } else {\r
- IdeWritePortWMultiple (\r
- IdeRegisters->Data,\r
- Increment,\r
- Buffer16\r
- );\r
- }\r
-\r
- Status = CheckStatusRegister (IdeRegisters);\r
- if (EFI_ERROR (Status)) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Exit;\r
- }\r
-\r
- WordCount += Increment;\r
- Buffer16 += Increment;\r
- }\r
-\r
- Status = DRQClear (IdeRegisters, Timeout);\r
- if (EFI_ERROR (Status)) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Exit;\r
- }\r
-\r
-Exit:\r
- //\r
- // Dump All Ide registers to ATA_STATUS_BLOCK\r
- //\r
- DumpAllIdeRegisters (IdeRegisters);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Sends out an ATA Identify Command to the specified device.\r
-\r
- This function sends out the ATA Identify Command to the\r
- specified device. Only ATA device responses to this command. If\r
- the command succeeds, it returns the Identify Data structure which\r
- contains information about the device. This function extracts the\r
- information it needs to fill the IDE_BLK_IO_DEV Data structure,\r
- including device type, media block Size, media capacity, and etc.\r
-\r
- @param IdeRegisters A pointer to EFI_IDE_REGISTERS Data structure.\r
- @param Channel The channel number of device.\r
- @param Device The device number of device.\r
- @param Buffer A pointer to Data Buffer which is used to contain IDENTIFY Data.\r
-\r
- @retval EFI_SUCCESS Identify ATA device successfully.\r
- @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.\r
- @retval EFI_OUT_OF_RESOURCES Allocate memory failed.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AtaIdentify (\r
- IN EFI_IDE_REGISTERS *IdeRegisters,\r
- IN UINT8 Channel,\r
- IN UINT8 Device,\r
- IN OUT ATA_IDENTIFY_DATA *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_ATA_COMMAND_BLOCK AtaCommandBlock;\r
-\r
- ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));\r
-\r
- AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DRIVE;\r
- AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);\r
-\r
- Status = AtaPioDataInOut (\r
- IdeRegisters,\r
- Buffer,\r
- sizeof (ATA_IDENTIFY_DATA),\r
- TRUE,\r
- &AtaCommandBlock,\r
- NULL,\r
- ATA_TIMEOUT\r
- );\r
-\r
- return Status;\r
-}\r
-\r
-\r
-\r
+++ /dev/null
-/** @file\r
- Header file for IDE mode of ATA host controller.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-\r
-\r
-#ifndef __OPAL_PASSWORD_IDE_MODE_H__\r
-#define __OPAL_PASSWORD_IDE_MODE_H__\r
-\r
-typedef enum {\r
- EfiIdePrimary = 0,\r
- EfiIdeSecondary = 1,\r
- EfiIdeMaxChannel = 2\r
-} EFI_IDE_CHANNEL;\r
-\r
-typedef enum {\r
- EfiIdeMaster = 0,\r
- EfiIdeSlave = 1,\r
- EfiIdeMaxDevice = 2\r
-} EFI_IDE_DEVICE;\r
-\r
-//\r
-// IDE registers set\r
-//\r
-typedef struct {\r
- UINT16 Data;\r
- UINT16 ErrOrFeature;\r
- UINT16 SectorCount;\r
- UINT16 SectorNumber;\r
- UINT16 CylinderLsb;\r
- UINT16 CylinderMsb;\r
- UINT16 Head;\r
- UINT16 CmdOrStatus;\r
- UINT16 AltOrDev;\r
-} EFI_IDE_REGISTERS;\r
-\r
-//\r
-// Bit definitions in Programming Interface byte of the Class Code field\r
-// in PCI IDE controller's Configuration Space\r
-//\r
-#define IDE_PRIMARY_OPERATING_MODE BIT0\r
-#define IDE_PRIMARY_PROGRAMMABLE_INDICATOR BIT1\r
-#define IDE_SECONDARY_OPERATING_MODE BIT2\r
-#define IDE_SECONDARY_PROGRAMMABLE_INDICATOR BIT3\r
-\r
-/**\r
- Get IDE i/o port registers' base addresses by mode.\r
-\r
- In 'Compatibility' mode, use fixed addresses.\r
- In Native-PCI mode, get base addresses from BARs in the PCI IDE controller's\r
- Configuration Space.\r
-\r
- The steps to get IDE i/o port registers' base addresses for each channel\r
- as follows:\r
-\r
- 1. Examine the Programming Interface byte of the Class Code fields in PCI IDE\r
- controller's Configuration Space to determine the operating mode.\r
-\r
- 2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.\r
- ___________________________________________\r
- | | Command Block | Control Block |\r
- | Channel | Registers | Registers |\r
- |___________|_______________|_______________|\r
- | Primary | 1F0h - 1F7h | 3F6h - 3F7h |\r
- |___________|_______________|_______________|\r
- | Secondary | 170h - 177h | 376h - 377h |\r
- |___________|_______________|_______________|\r
-\r
- Table 1. Compatibility resource mappings\r
-\r
- b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs\r
- in IDE controller's PCI Configuration Space, shown in the Table 2 below.\r
- ___________________________________________________\r
- | | Command Block | Control Block |\r
- | Channel | Registers | Registers |\r
- |___________|___________________|___________________|\r
- | Primary | BAR at offset 0x10| BAR at offset 0x14|\r
- |___________|___________________|___________________|\r
- | Secondary | BAR at offset 0x18| BAR at offset 0x1C|\r
- |___________|___________________|___________________|\r
-\r
- Table 2. BARs for Register Mapping\r
-\r
- @param[in] Bus The bus number of ata host controller.\r
- @param[in] Device The device number of ata host controller.\r
- @param[in] Function The function number of ata host controller.\r
- @param[in, out] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to\r
- store the IDE i/o port registers' base addresses\r
-\r
- @retval EFI_UNSUPPORTED Return this Value when the BARs is not IO type\r
- @retval EFI_SUCCESS Get the Base address successfully\r
- @retval Other Read the pci configureation Data error\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetIdeRegisterIoAddr (\r
- IN UINTN Bus,\r
- IN UINTN Device,\r
- IN UINTN Function,\r
- IN OUT EFI_IDE_REGISTERS *IdeRegisters\r
- );\r
-\r
-/**\r
- Sends out an ATA Identify Command to the specified device.\r
-\r
- This function sends out the ATA Identify Command to the\r
- specified device. Only ATA device responses to this command. If\r
- the command succeeds, it returns the Identify Data structure which\r
- contains information about the device. This function extracts the\r
- information it needs to fill the IDE_BLK_IO_DEV Data structure,\r
- including device type, media block Size, media capacity, and etc.\r
-\r
- @param IdeRegisters A pointer to EFI_IDE_REGISTERS Data structure.\r
- @param Channel The channel number of device.\r
- @param Device The device number of device.\r
- @param Buffer A pointer to Data Buffer which is used to contain IDENTIFY Data.\r
-\r
- @retval EFI_SUCCESS Identify ATA device successfully.\r
- @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.\r
- @retval EFI_OUT_OF_RESOURCES Allocate memory failed.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AtaIdentify (\r
- IN EFI_IDE_REGISTERS *IdeRegisters,\r
- IN UINT8 Channel,\r
- IN UINT8 Device,\r
- IN OUT ATA_IDENTIFY_DATA *Buffer\r
- );\r
-\r
-/**\r
- This function is used to send out ATA commands conforms to the PIO Data In Protocol.\r
-\r
- @param IdeRegisters A pointer to EFI_IDE_REGISTERS Data structure.\r
- @param Buffer A pointer to the source Buffer for the Data.\r
- @param ByteCount The Length of the Data.\r
- @param Read Flag used to determine the Data transfer direction.\r
- Read equals 1, means Data transferred from device to host;\r
- Read equals 0, means Data transferred from host to device.\r
- @param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK Data structure.\r
- @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK Data structure.\r
- @param Timeout The time to complete the command.\r
-\r
- @retval EFI_SUCCESS send out the ATA command and device send required Data successfully.\r
- @retval EFI_DEVICE_ERROR command sent failed.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AtaPioDataInOut (\r
- IN EFI_IDE_REGISTERS *IdeRegisters,\r
- IN OUT VOID *Buffer,\r
- IN UINT64 ByteCount,\r
- IN BOOLEAN Read,\r
- IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,\r
- IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,\r
- IN UINT64 Timeout\r
- );\r
-\r
-\r
-#endif\r
-\r
+++ /dev/null
-/** @file\r
- Provide functions to initialize NVME controller and perform NVME commands\r
-\r
-Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "OpalPasswordSmm.h"\r
-\r
-\r
-#define ALIGN(v, a) (UINTN)((((v) - 1) | ((a) - 1)) + 1)\r
-\r
-///\r
-/// NVME Host controller registers operation\r
-///\r
-#define NVME_GET_CAP(Nvme, Cap) NvmeMmioRead (Cap, Nvme->Nbar + NVME_CAP_OFFSET, sizeof (NVME_CAP))\r
-#define NVME_GET_CC(Nvme, Cc) NvmeMmioRead (Cc, Nvme->Nbar + NVME_CC_OFFSET, sizeof (NVME_CC))\r
-#define NVME_SET_CC(Nvme, Cc) NvmeMmioWrite (Nvme->Nbar + NVME_CC_OFFSET, Cc, sizeof (NVME_CC))\r
-#define NVME_GET_CSTS(Nvme, Csts) NvmeMmioRead (Csts, Nvme->Nbar + NVME_CSTS_OFFSET, sizeof (NVME_CSTS))\r
-#define NVME_GET_AQA(Nvme, Aqa) NvmeMmioRead (Aqa, Nvme->Nbar + NVME_AQA_OFFSET, sizeof (NVME_AQA))\r
-#define NVME_SET_AQA(Nvme, Aqa) NvmeMmioWrite (Nvme->Nbar + NVME_AQA_OFFSET, Aqa, sizeof (NVME_AQA))\r
-#define NVME_GET_ASQ(Nvme, Asq) NvmeMmioRead (Asq, Nvme->Nbar + NVME_ASQ_OFFSET, sizeof (NVME_ASQ))\r
-#define NVME_SET_ASQ(Nvme, Asq) NvmeMmioWrite (Nvme->Nbar + NVME_ASQ_OFFSET, Asq, sizeof (NVME_ASQ))\r
-#define NVME_GET_ACQ(Nvme, Acq) NvmeMmioRead (Acq, Nvme->Nbar + NVME_ACQ_OFFSET, sizeof (NVME_ACQ))\r
-#define NVME_SET_ACQ(Nvme, Acq) NvmeMmioWrite (Nvme->Nbar + NVME_ACQ_OFFSET, Acq, sizeof (NVME_ACQ))\r
-#define NVME_GET_VER(Nvme, Ver) NvmeMmioRead (Ver, Nvme->Nbar + NVME_VER_OFFSET, sizeof (NVME_VER))\r
-#define NVME_SET_SQTDBL(Nvme, Qid, Sqtdbl) NvmeMmioWrite (Nvme->Nbar + NVME_SQTDBL_OFFSET(Qid, Nvme->Cap.Dstrd), Sqtdbl, sizeof (NVME_SQTDBL))\r
-#define NVME_SET_CQHDBL(Nvme, Qid, Cqhdbl) NvmeMmioWrite (Nvme->Nbar + NVME_CQHDBL_OFFSET(Qid, Nvme->Cap.Dstrd), Cqhdbl, sizeof (NVME_CQHDBL))\r
-\r
-///\r
-/// Base memory address\r
-///\r
-enum {\r
- BASEMEM_CONTROLLER_DATA,\r
- BASEMEM_IDENTIFY_DATA,\r
- BASEMEM_ASQ,\r
- BASEMEM_ACQ,\r
- BASEMEM_SQ,\r
- BASEMEM_CQ,\r
- BASEMEM_PRP,\r
- BASEMEM_SECURITY,\r
- MAX_BASEMEM_COUNT\r
-};\r
-\r
-///\r
-/// All of base memories are 4K(0x1000) alignment\r
-///\r
-#define NVME_MEM_BASE(Nvme) ((UINTN)(Nvme->BaseMem))\r
-#define NVME_CONTROL_DATA_BASE(Nvme) (ALIGN (NVME_MEM_BASE(Nvme) + ((NvmeGetBaseMemPages (BASEMEM_CONTROLLER_DATA)) * EFI_PAGE_SIZE), EFI_PAGE_SIZE))\r
-#define NVME_NAMESPACE_DATA_BASE(Nvme) (ALIGN (NVME_MEM_BASE(Nvme) + ((NvmeGetBaseMemPages (BASEMEM_IDENTIFY_DATA)) * EFI_PAGE_SIZE), EFI_PAGE_SIZE))\r
-#define NVME_ASQ_BASE(Nvme) (ALIGN (NVME_MEM_BASE(Nvme) + ((NvmeGetBaseMemPages (BASEMEM_ASQ)) * EFI_PAGE_SIZE), EFI_PAGE_SIZE))\r
-#define NVME_ACQ_BASE(Nvme) (ALIGN (NVME_MEM_BASE(Nvme) + ((NvmeGetBaseMemPages (BASEMEM_ACQ)) * EFI_PAGE_SIZE), EFI_PAGE_SIZE))\r
-#define NVME_SQ_BASE(Nvme, index) (ALIGN (NVME_MEM_BASE(Nvme) + ((NvmeGetBaseMemPages (BASEMEM_SQ) + ((index)*(NVME_MAX_IO_QUEUES-1))) * EFI_PAGE_SIZE), EFI_PAGE_SIZE))\r
-#define NVME_CQ_BASE(Nvme, index) (ALIGN (NVME_MEM_BASE(Nvme) + ((NvmeGetBaseMemPages (BASEMEM_CQ) + ((index)*(NVME_MAX_IO_QUEUES-1))) * EFI_PAGE_SIZE), EFI_PAGE_SIZE))\r
-#define NVME_PRP_BASE(Nvme, index) (ALIGN (NVME_MEM_BASE(Nvme) + ((NvmeGetBaseMemPages (BASEMEM_PRP) + ((index)*NVME_PRP_SIZE)) * EFI_PAGE_SIZE), EFI_PAGE_SIZE))\r
-#define NVME_SEC_BASE(Nvme) (ALIGN (NVME_MEM_BASE(Nvme) + ((NvmeGetBaseMemPages (BASEMEM_SECURITY)) * EFI_PAGE_SIZE), EFI_PAGE_SIZE))\r
-\r
-/**\r
- Transfer MMIO Data to memory.\r
-\r
- @param[in,out] MemBuffer - Destination: Memory address\r
- @param[in] MmioAddr - Source: MMIO address\r
- @param[in] Size - Size for read\r
-\r
- @retval EFI_SUCCESS - MMIO read sucessfully\r
-**/\r
-EFI_STATUS\r
-NvmeMmioRead (\r
- IN OUT VOID *MemBuffer,\r
- IN UINTN MmioAddr,\r
- IN UINTN Size\r
- )\r
-{\r
- UINTN Offset;\r
- UINT8 Data;\r
- UINT8 *Ptr;\r
-\r
- // priority has adjusted\r
- switch (Size) {\r
- case 4:\r
- *((UINT32 *)MemBuffer) = MmioRead32 (MmioAddr);\r
- break;\r
-\r
- case 8:\r
- *((UINT64 *)MemBuffer) = MmioRead64 (MmioAddr);\r
- break;\r
-\r
- case 2:\r
- *((UINT16 *)MemBuffer) = MmioRead16 (MmioAddr);\r
- break;\r
-\r
- case 1:\r
- *((UINT8 *)MemBuffer) = MmioRead8 (MmioAddr);\r
- break;\r
-\r
- default:\r
- Ptr = (UINT8 *)MemBuffer;\r
- for (Offset = 0; Offset < Size; Offset += 1) {\r
- Data = MmioRead8 (MmioAddr + Offset);\r
- Ptr[Offset] = Data;\r
- }\r
- break;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Transfer memory data to MMIO.\r
-\r
- @param[in,out] MmioAddr - Destination: MMIO address\r
- @param[in] MemBuffer - Source: Memory address\r
- @param[in] Size - Size for write\r
-\r
- @retval EFI_SUCCESS - MMIO write sucessfully\r
-**/\r
-EFI_STATUS\r
-NvmeMmioWrite (\r
- IN OUT UINTN MmioAddr,\r
- IN VOID *MemBuffer,\r
- IN UINTN Size\r
- )\r
-{\r
- UINTN Offset;\r
- UINT8 Data;\r
- UINT8 *Ptr;\r
-\r
- // priority has adjusted\r
- switch (Size) {\r
- case 4:\r
- MmioWrite32 (MmioAddr, *((UINT32 *)MemBuffer));\r
- break;\r
-\r
- case 8:\r
- MmioWrite64 (MmioAddr, *((UINT64 *)MemBuffer));\r
- break;\r
-\r
- case 2:\r
- MmioWrite16 (MmioAddr, *((UINT16 *)MemBuffer));\r
- break;\r
-\r
- case 1:\r
- MmioWrite8 (MmioAddr, *((UINT8 *)MemBuffer));\r
- break;\r
-\r
- default:\r
- Ptr = (UINT8 *)MemBuffer;\r
- for (Offset = 0; Offset < Size; Offset += 1) {\r
- Data = Ptr[Offset];\r
- MmioWrite8 (MmioAddr + Offset, Data);\r
- }\r
- break;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Transfer MMIO data to memory.\r
-\r
- @param[in,out] MemBuffer - Destination: Memory address\r
- @param[in] MmioAddr - Source: MMIO address\r
- @param[in] Size - Size for read\r
-\r
- @retval EFI_SUCCESS - MMIO read sucessfully\r
-**/\r
-EFI_STATUS\r
-OpalPciRead (\r
- IN OUT VOID *MemBuffer,\r
- IN UINTN MmioAddr,\r
- IN UINTN Size\r
- )\r
-{\r
- UINTN Offset;\r
- UINT8 Data;\r
- UINT8 *Ptr;\r
-\r
- // priority has adjusted\r
- switch (Size) {\r
- case 4:\r
- *((UINT32 *)MemBuffer) = PciRead32 (MmioAddr);\r
- break;\r
-\r
- case 2:\r
- *((UINT16 *)MemBuffer) = PciRead16 (MmioAddr);\r
- break;\r
-\r
- case 1:\r
- *((UINT8 *)MemBuffer) = PciRead8 (MmioAddr);\r
- break;\r
-\r
- default:\r
- Ptr = (UINT8 *)MemBuffer;\r
- for (Offset = 0; Offset < Size; Offset += 1) {\r
- Data = PciRead8 (MmioAddr + Offset);\r
- Ptr[Offset] = Data;\r
- }\r
- break;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Transfer memory data to MMIO.\r
-\r
- @param[in,out] MmioAddr - Destination: MMIO address\r
- @param[in] MemBuffer - Source: Memory address\r
- @param[in] Size - Size for write\r
-\r
- @retval EFI_SUCCESS - MMIO write sucessfully\r
-**/\r
-EFI_STATUS\r
-OpalPciWrite (\r
- IN OUT UINTN MmioAddr,\r
- IN VOID *MemBuffer,\r
- IN UINTN Size\r
- )\r
-{\r
- UINTN Offset;\r
- UINT8 Data;\r
- UINT8 *Ptr;\r
-\r
- // priority has adjusted\r
- switch (Size) {\r
- case 4:\r
- PciWrite32 (MmioAddr, *((UINT32 *)MemBuffer));\r
- break;\r
-\r
- case 2:\r
- PciWrite16 (MmioAddr, *((UINT16 *)MemBuffer));\r
- break;\r
-\r
- case 1:\r
- PciWrite8 (MmioAddr, *((UINT8 *)MemBuffer));\r
- break;\r
-\r
- default:\r
- Ptr = (UINT8 *)MemBuffer;\r
- for (Offset = 0; Offset < Size; Offset += 1) {\r
- Data = Ptr[Offset];\r
- PciWrite8 (MmioAddr + Offset, Data);\r
- }\r
- break;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Get total pages for specific NVME based memory.\r
-\r
- @param[in] BaseMemIndex - The Index of BaseMem (0-based).\r
-\r
- @retval - The page count for specific BaseMem Index\r
-\r
-**/\r
-UINT32\r
-NvmeGetBaseMemPages (\r
- IN UINTN BaseMemIndex\r
- )\r
-{\r
- UINT32 Pages;\r
- UINTN Index;\r
- UINT32 PageSizeList[8];\r
-\r
- PageSizeList[0] = 1; /* Controller Data */\r
- PageSizeList[1] = 1; /* Identify Data */\r
- PageSizeList[2] = 1; /* ASQ */\r
- PageSizeList[3] = 1; /* ACQ */\r
- PageSizeList[4] = 1; /* SQs */\r
- PageSizeList[5] = 1; /* CQs */\r
- PageSizeList[6] = NVME_PRP_SIZE * NVME_CSQ_DEPTH; /* PRPs */\r
- PageSizeList[7] = 1; /* Security Commands */\r
-\r
- if (BaseMemIndex > MAX_BASEMEM_COUNT) {\r
- ASSERT (FALSE);\r
- return 0;\r
- }\r
-\r
- Pages = 0;\r
- for (Index = 0; Index < BaseMemIndex; Index++) {\r
- Pages += PageSizeList[Index];\r
- }\r
-\r
- return Pages;\r
-}\r
-\r
-/**\r
- Wait for NVME controller status to be ready or not.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] WaitReady - Flag for waitting status ready or not\r
-\r
- @return EFI_SUCCESS - Successfully to wait specific status.\r
- @return others - Fail to wait for specific controller status.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-NvmeWaitController (\r
- IN NVME_CONTEXT *Nvme,\r
- IN BOOLEAN WaitReady\r
- )\r
-{\r
- NVME_CSTS Csts;\r
- EFI_STATUS Status;\r
- UINT32 Index;\r
- UINT8 Timeout;\r
-\r
- //\r
- // Cap.To specifies max delay time in 500ms increments for Csts.Rdy to set after\r
- // Cc.Enable. Loop produces a 1 millisecond delay per itteration, up to 500 * Cap.To.\r
- //\r
- if (Nvme->Cap.To == 0) {\r
- Timeout = 1;\r
- } else {\r
- Timeout = Nvme->Cap.To;\r
- }\r
-\r
- Status = EFI_SUCCESS;\r
- for(Index = (Timeout * 500); Index != 0; --Index) {\r
- MicroSecondDelay (1000);\r
-\r
- //\r
- // Check if the controller is initialized\r
- //\r
- Status = NVME_GET_CSTS (Nvme, &Csts);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NVME_GET_CSTS fail, Status = %r\n", Status));\r
- return Status;\r
- }\r
-\r
- if ((BOOLEAN) Csts.Rdy == WaitReady) {\r
- break;\r
- }\r
- }\r
-\r
- if (Index == 0) {\r
- Status = EFI_TIMEOUT;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Disable the Nvm Express controller.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @return EFI_SUCCESS - Successfully disable the controller.\r
- @return others - Fail to disable the controller.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-NvmeDisableController (\r
- IN NVME_CONTEXT *Nvme\r
- )\r
-{\r
- NVME_CC Cc;\r
- NVME_CSTS Csts;\r
- EFI_STATUS Status;\r
-\r
- Status = NVME_GET_CSTS (Nvme, &Csts);\r
-\r
- ///\r
- /// Read Controller Configuration Register.\r
- ///\r
- Status = NVME_GET_CC (Nvme, &Cc);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NVME_GET_CC fail, Status = %r\n", Status));\r
- goto Done;\r
- }\r
-\r
- if (Cc.En == 1) {\r
- Cc.En = 0;\r
- ///\r
- /// Disable the controller.\r
- ///\r
- Status = NVME_SET_CC (Nvme, &Cc);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NVME_SET_CC fail, Status = %r\n", Status));\r
- goto Done;\r
- }\r
- }\r
-\r
- Status = NvmeWaitController (Nvme, FALSE);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NvmeWaitController fail, Status = %r\n", Status));\r
- goto Done;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-Done:\r
- DEBUG ((DEBUG_INFO, "NvmeDisableController fail, Status: %r\n", Status));\r
- return Status;\r
-}\r
-\r
-/**\r
- Enable the Nvm Express controller.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @return EFI_SUCCESS - Successfully enable the controller.\r
- @return EFI_DEVICE_ERROR - Fail to enable the controller.\r
- @return EFI_TIMEOUT - Fail to enable the controller in given time slot.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-NvmeEnableController (\r
- IN NVME_CONTEXT *Nvme\r
- )\r
-{\r
- NVME_CC Cc;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Enable the controller\r
- //\r
- ZeroMem (&Cc, sizeof (NVME_CC));\r
- Cc.En = 1;\r
- Cc.Iosqes = 6;\r
- Cc.Iocqes = 4;\r
- Status = NVME_SET_CC (Nvme, &Cc);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NVME_SET_CC fail, Status = %r\n", Status));\r
- goto Done;\r
- }\r
-\r
- Status = NvmeWaitController (Nvme, TRUE);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NvmeWaitController fail, Status = %r\n", Status));\r
- goto Done;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-Done:\r
- DEBUG ((DEBUG_INFO, "NvmeEnableController fail, Status: %r\n", Status));\r
- return Status;\r
-}\r
-\r
-/**\r
- Shutdown the Nvm Express controller.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @return EFI_SUCCESS - Successfully shutdown the controller.\r
- @return EFI_DEVICE_ERROR - Fail to shutdown the controller.\r
- @return EFI_TIMEOUT - Fail to shutdown the controller in given time slot.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-NvmeShutdownController (\r
- IN NVME_CONTEXT *Nvme\r
- )\r
-{\r
- NVME_CC Cc;\r
- NVME_CSTS Csts;\r
- EFI_STATUS Status;\r
- UINT32 Index;\r
- UINTN Timeout;\r
-\r
- Status = NVME_GET_CC (Nvme, &Cc);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NVME_GET_CC fail, Status = %r\n", Status));\r
- return Status;\r
- }\r
-\r
- Cc.Shn = 1; // Normal shutdown\r
-\r
- Status = NVME_SET_CC (Nvme, &Cc);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NVME_SET_CC fail, Status = %r\n", Status));\r
- return Status;\r
- }\r
-\r
- Timeout = NVME_GENERIC_TIMEOUT/1000; // ms\r
- for(Index = (UINT32)(Timeout); Index != 0; --Index) {\r
- MicroSecondDelay (1000);\r
-\r
- Status = NVME_GET_CSTS (Nvme, &Csts);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NVME_GET_CSTS fail, Status = %r\n", Status));\r
- return Status;\r
- }\r
-\r
- if (Csts.Shst == 2) { // Shutdown processing complete\r
- break;\r
- }\r
- }\r
-\r
- if (Index == 0) {\r
- Status = EFI_TIMEOUT;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Check the execution status from a given completion queue entry.\r
-\r
- @param[in] Cq - A pointer to the NVME_CQ item.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeCheckCqStatus (\r
- IN NVME_CQ *Cq\r
- )\r
-{\r
- if (Cq->Sct == 0x0 && Cq->Sc == 0x0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- DEBUG ((DEBUG_INFO, "Dump NVMe Completion Entry Status from [0x%x]:\n", (UINTN)Cq));\r
- DEBUG ((DEBUG_INFO, " SQ Identifier : [0x%x], Phase Tag : [%d], Cmd Identifier : [0x%x]\n", Cq->Sqid, Cq->Pt, Cq->Cid));\r
- DEBUG ((DEBUG_INFO, " NVMe Cmd Execution Result - "));\r
-\r
- switch (Cq->Sct) {\r
- case 0x0:\r
- switch (Cq->Sc) {\r
- case 0x0:\r
- DEBUG ((DEBUG_INFO, "Successful Completion\n"));\r
- return EFI_SUCCESS;\r
- case 0x1:\r
- DEBUG ((DEBUG_INFO, "Invalid Command Opcode\n"));\r
- break;\r
- case 0x2:\r
- DEBUG ((DEBUG_INFO, "Invalid Field in Command\n"));\r
- break;\r
- case 0x3:\r
- DEBUG ((DEBUG_INFO, "Command ID Conflict\n"));\r
- break;\r
- case 0x4:\r
- DEBUG ((DEBUG_INFO, "Data Transfer Error\n"));\r
- break;\r
- case 0x5:\r
- DEBUG ((DEBUG_INFO, "Commands Aborted due to Power Loss Notification\n"));\r
- break;\r
- case 0x6:\r
- DEBUG ((DEBUG_INFO, "Internal Device Error\n"));\r
- break;\r
- case 0x7:\r
- DEBUG ((DEBUG_INFO, "Command Abort Requested\n"));\r
- break;\r
- case 0x8:\r
- DEBUG ((DEBUG_INFO, "Command Aborted due to SQ Deletion\n"));\r
- break;\r
- case 0x9:\r
- DEBUG ((DEBUG_INFO, "Command Aborted due to Failed Fused Command\n"));\r
- break;\r
- case 0xA:\r
- DEBUG ((DEBUG_INFO, "Command Aborted due to Missing Fused Command\n"));\r
- break;\r
- case 0xB:\r
- DEBUG ((DEBUG_INFO, "Invalid Namespace or Format\n"));\r
- break;\r
- case 0xC:\r
- DEBUG ((DEBUG_INFO, "Command Sequence Error\n"));\r
- break;\r
- case 0xD:\r
- DEBUG ((DEBUG_INFO, "Invalid SGL Last Segment Descriptor\n"));\r
- break;\r
- case 0xE:\r
- DEBUG ((DEBUG_INFO, "Invalid Number of SGL Descriptors\n"));\r
- break;\r
- case 0xF:\r
- DEBUG ((DEBUG_INFO, "Data SGL Length Invalid\n"));\r
- break;\r
- case 0x10:\r
- DEBUG ((DEBUG_INFO, "Metadata SGL Length Invalid\n"));\r
- break;\r
- case 0x11:\r
- DEBUG ((DEBUG_INFO, "SGL Descriptor Type Invalid\n"));\r
- break;\r
- case 0x80:\r
- DEBUG ((DEBUG_INFO, "LBA Out of Range\n"));\r
- break;\r
- case 0x81:\r
- DEBUG ((DEBUG_INFO, "Capacity Exceeded\n"));\r
- break;\r
- case 0x82:\r
- DEBUG ((DEBUG_INFO, "Namespace Not Ready\n"));\r
- break;\r
- case 0x83:\r
- DEBUG ((DEBUG_INFO, "Reservation Conflict\n"));\r
- break;\r
- }\r
- break;\r
-\r
- case 0x1:\r
- switch (Cq->Sc) {\r
- case 0x0:\r
- DEBUG ((DEBUG_INFO, "Completion Queue Invalid\n"));\r
- break;\r
- case 0x1:\r
- DEBUG ((DEBUG_INFO, "Invalid Queue Identifier\n"));\r
- break;\r
- case 0x2:\r
- DEBUG ((DEBUG_INFO, "Maximum Queue Size Exceeded\n"));\r
- break;\r
- case 0x3:\r
- DEBUG ((DEBUG_INFO, "Abort Command Limit Exceeded\n"));\r
- break;\r
- case 0x5:\r
- DEBUG ((DEBUG_INFO, "Asynchronous Event Request Limit Exceeded\n"));\r
- break;\r
- case 0x6:\r
- DEBUG ((DEBUG_INFO, "Invalid Firmware Slot\n"));\r
- break;\r
- case 0x7:\r
- DEBUG ((DEBUG_INFO, "Invalid Firmware Image\n"));\r
- break;\r
- case 0x8:\r
- DEBUG ((DEBUG_INFO, "Invalid Interrupt Vector\n"));\r
- break;\r
- case 0x9:\r
- DEBUG ((DEBUG_INFO, "Invalid Log Page\n"));\r
- break;\r
- case 0xA:\r
- DEBUG ((DEBUG_INFO, "Invalid Format\n"));\r
- break;\r
- case 0xB:\r
- DEBUG ((DEBUG_INFO, "Firmware Application Requires Conventional Reset\n"));\r
- break;\r
- case 0xC:\r
- DEBUG ((DEBUG_INFO, "Invalid Queue Deletion\n"));\r
- break;\r
- case 0xD:\r
- DEBUG ((DEBUG_INFO, "Feature Identifier Not Saveable\n"));\r
- break;\r
- case 0xE:\r
- DEBUG ((DEBUG_INFO, "Feature Not Changeable\n"));\r
- break;\r
- case 0xF:\r
- DEBUG ((DEBUG_INFO, "Feature Not Namespace Specific\n"));\r
- break;\r
- case 0x10:\r
- DEBUG ((DEBUG_INFO, "Firmware Application Requires NVM Subsystem Reset\n"));\r
- break;\r
- case 0x80:\r
- DEBUG ((DEBUG_INFO, "Conflicting Attributes\n"));\r
- break;\r
- case 0x81:\r
- DEBUG ((DEBUG_INFO, "Invalid Protection Information\n"));\r
- break;\r
- case 0x82:\r
- DEBUG ((DEBUG_INFO, "Attempted Write to Read Only Range\n"));\r
- break;\r
- }\r
- break;\r
-\r
- case 0x2:\r
- switch (Cq->Sc) {\r
- case 0x80:\r
- DEBUG ((DEBUG_INFO, "Write Fault\n"));\r
- break;\r
- case 0x81:\r
- DEBUG ((DEBUG_INFO, "Unrecovered Read Error\n"));\r
- break;\r
- case 0x82:\r
- DEBUG ((DEBUG_INFO, "End-to-end Guard Check Error\n"));\r
- break;\r
- case 0x83:\r
- DEBUG ((DEBUG_INFO, "End-to-end Application Tag Check Error\n"));\r
- break;\r
- case 0x84:\r
- DEBUG ((DEBUG_INFO, "End-to-end Reference Tag Check Error\n"));\r
- break;\r
- case 0x85:\r
- DEBUG ((DEBUG_INFO, "Compare Failure\n"));\r
- break;\r
- case 0x86:\r
- DEBUG ((DEBUG_INFO, "Access Denied\n"));\r
- break;\r
- }\r
- break;\r
-\r
- default:\r
- DEBUG ((DEBUG_INFO, "Unknown error\n"));\r
- break;\r
- }\r
-\r
- return EFI_DEVICE_ERROR;\r
-}\r
-\r
-/**\r
- Create PRP lists for Data transfer which is larger than 2 memory pages.\r
- Note here we calcuate the number of required PRP lists and allocate them at one time.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] SqId - The SQ index for this PRP\r
- @param[in] PhysicalAddr - The physical base address of Data Buffer.\r
- @param[in] Pages - The number of pages to be transfered.\r
- @param[out] PrpListHost - The host base address of PRP lists.\r
- @param[in,out] PrpListNo - The number of PRP List.\r
-\r
- @retval The pointer Value to the first PRP List of the PRP lists.\r
-\r
-**/\r
-STATIC\r
-UINT64\r
-NvmeCreatePrpList (\r
- IN NVME_CONTEXT *Nvme,\r
- IN UINT16 SqId,\r
- IN EFI_PHYSICAL_ADDRESS PhysicalAddr,\r
- IN UINTN Pages,\r
- OUT VOID **PrpListHost,\r
- IN OUT UINTN *PrpListNo\r
- )\r
-{\r
- UINTN PrpEntryNo;\r
- UINT64 PrpListBase;\r
- UINTN PrpListIndex;\r
- UINTN PrpEntryIndex;\r
- UINT64 Remainder;\r
- EFI_PHYSICAL_ADDRESS PrpListPhyAddr;\r
- UINTN Bytes;\r
- UINT8 *PrpEntry;\r
- EFI_PHYSICAL_ADDRESS NewPhyAddr;\r
-\r
- ///\r
- /// The number of Prp Entry in a memory page.\r
- ///\r
- PrpEntryNo = EFI_PAGE_SIZE / sizeof (UINT64);\r
-\r
- ///\r
- /// Calculate total PrpList number.\r
- ///\r
- *PrpListNo = (UINTN) DivU64x64Remainder ((UINT64)Pages, (UINT64)PrpEntryNo, &Remainder);\r
- if (Remainder != 0) {\r
- *PrpListNo += 1;\r
- }\r
-\r
- if (*PrpListNo > NVME_PRP_SIZE) {\r
- DEBUG ((DEBUG_INFO, "NvmeCreatePrpList (PhysicalAddr: %lx, Pages: %x) PrpEntryNo: %x\n",\r
- PhysicalAddr, Pages, PrpEntryNo));\r
- DEBUG ((DEBUG_INFO, "*PrpListNo: %x, Remainder: %lx", *PrpListNo, Remainder));\r
- ASSERT (FALSE);\r
- }\r
- *PrpListHost = (VOID *)(UINTN) NVME_PRP_BASE (Nvme, SqId);\r
-\r
- Bytes = EFI_PAGES_TO_SIZE (*PrpListNo);\r
- PrpListPhyAddr = (UINT64)(UINTN)(*PrpListHost);\r
-\r
- ///\r
- /// Fill all PRP lists except of last one.\r
- ///\r
- ZeroMem (*PrpListHost, Bytes);\r
- for (PrpListIndex = 0; PrpListIndex < *PrpListNo - 1; ++PrpListIndex) {\r
- PrpListBase = *(UINT64*)PrpListHost + PrpListIndex * EFI_PAGE_SIZE;\r
-\r
- for (PrpEntryIndex = 0; PrpEntryIndex < PrpEntryNo; ++PrpEntryIndex) {\r
- PrpEntry = (UINT8 *)(UINTN) (PrpListBase + PrpEntryIndex * sizeof(UINT64));\r
- if (PrpEntryIndex != PrpEntryNo - 1) {\r
- ///\r
- /// Fill all PRP entries except of last one.\r
- ///\r
- CopyMem (PrpEntry, (VOID *)(UINTN) (&PhysicalAddr), sizeof (UINT64));\r
- PhysicalAddr += EFI_PAGE_SIZE;\r
- } else {\r
- ///\r
- /// Fill last PRP entries with next PRP List pointer.\r
- ///\r
- NewPhyAddr = (PrpListPhyAddr + (PrpListIndex + 1) * EFI_PAGE_SIZE);\r
- CopyMem (PrpEntry, (VOID *)(UINTN) (&NewPhyAddr), sizeof (UINT64));\r
- }\r
- }\r
- }\r
-\r
- ///\r
- /// Fill last PRP list.\r
- ///\r
- PrpListBase = *(UINT64*)PrpListHost + PrpListIndex * EFI_PAGE_SIZE;\r
- for (PrpEntryIndex = 0; PrpEntryIndex < ((Remainder != 0) ? Remainder : PrpEntryNo); ++PrpEntryIndex) {\r
- PrpEntry = (UINT8 *)(UINTN) (PrpListBase + PrpEntryIndex * sizeof(UINT64));\r
- CopyMem (PrpEntry, (VOID *)(UINTN) (&PhysicalAddr), sizeof (UINT64));\r
-\r
- PhysicalAddr += EFI_PAGE_SIZE;\r
- }\r
-\r
- return PrpListPhyAddr;\r
-}\r
-\r
-/**\r
- Check whether there are available command slots.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] Qid - Queue index\r
-\r
- @retval EFI_SUCCESS - Available command slot is found\r
- @retval EFI_NOT_READY - No available command slot is found\r
- @retval EFI_DEVICE_ERROR - Error occurred on device side.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeHasFreeCmdSlot (\r
- IN NVME_CONTEXT *Nvme,\r
- IN UINT8 Qid\r
- )\r
-{\r
- return TRUE;\r
-}\r
-\r
-/**\r
- Check whether all command slots are clean.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] Qid - Queue index\r
-\r
- @retval EFI_SUCCESS - All command slots are clean\r
- @retval EFI_NOT_READY - Not all command slots are clean\r
- @retval EFI_DEVICE_ERROR - Error occurred on device side.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeIsAllCmdSlotClean (\r
- IN NVME_CONTEXT *Nvme,\r
- IN UINT8 Qid\r
- )\r
-{\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Waits until all NVME commands completed.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] Qid - Queue index\r
-\r
- @retval EFI_SUCCESS - All NVME commands have completed\r
- @retval EFI_TIMEOUT - Timeout occured\r
- @retval EFI_NOT_READY - Not all NVME commands have completed\r
- @retval others - Error occurred on device side.\r
-**/\r
-EFI_STATUS\r
-NvmeWaitAllComplete (\r
- IN NVME_CONTEXT *Nvme,\r
- IN UINT8 Qid\r
- )\r
-{\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Sends an NVM Express Command Packet to an NVM Express controller or namespace. This function supports\r
- both blocking I/O and nonblocking I/O. The blocking I/O functionality is required, and the nonblocking\r
- I/O functionality is optional.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] NamespaceId - Is a 32 bit Namespace ID to which the Express HCI command packet will be sent.\r
- A Value of 0 denotes the NVM Express controller, a Value of all 0FFh in the namespace\r
- ID specifies that the command packet should be sent to all valid namespaces.\r
- @param[in] NamespaceUuid - Is a 64 bit Namespace UUID to which the Express HCI command packet will be sent.\r
- A Value of 0 denotes the NVM Express controller, a Value of all 0FFh in the namespace\r
- UUID specifies that the command packet should be sent to all valid namespaces.\r
- @param[in,out] Packet - A pointer to the NVM Express HCI Command Packet to send to the NVMe namespace specified\r
- by NamespaceId.\r
-\r
- @retval EFI_SUCCESS - The NVM Express Command Packet was sent by the host. TransferLength bytes were transferred\r
- to, or from DataBuffer.\r
- @retval EFI_NOT_READY - The NVM Express Command Packet could not be sent because the controller is not ready. The caller\r
- may retry again later.\r
- @retval EFI_DEVICE_ERROR - A device error occurred while attempting to send the NVM Express Command Packet.\r
- @retval EFI_INVALID_PARAMETER - Namespace, or the contents of NVM_EXPRESS_PASS_THRU_COMMAND_PACKET are invalid. The NVM\r
- Express Command Packet was not sent, so no additional status information is available.\r
- @retval EFI_UNSUPPORTED - The command described by the NVM Express Command Packet is not supported by the host adapter.\r
- The NVM Express Command Packet was not sent, so no additional status information is available.\r
- @retval EFI_TIMEOUT - A timeout occurred while waiting for the NVM Express Command Packet to execute.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmePassThru (\r
- IN NVME_CONTEXT *Nvme,\r
- IN UINT32 NamespaceId,\r
- IN UINT64 NamespaceUuid,\r
- IN OUT NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet\r
- )\r
-{\r
- EFI_STATUS Status;\r
- NVME_SQ *Sq;\r
- NVME_CQ *Cq;\r
- UINT8 Qid;\r
- UINT32 Bytes;\r
- UINT32 Offset;\r
- EFI_PHYSICAL_ADDRESS PhyAddr;\r
- VOID *PrpListHost;\r
- UINTN PrpListNo;\r
- UINT32 Timer;\r
- UINTN SqSize;\r
- UINTN CqSize;\r
-\r
- ///\r
- /// check the Data fields in Packet parameter.\r
- ///\r
- if ((Nvme == NULL) || (Packet == NULL)) {\r
- DEBUG ((DEBUG_ERROR, "NvmePassThru, invalid parameter: Nvme(%x)/Packet(%x)\n",\r
- (UINTN)Nvme, (UINTN)Packet));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((Packet->NvmeCmd == NULL) || (Packet->NvmeResponse == NULL)) {\r
- DEBUG ((DEBUG_ERROR, "NvmePassThru, invalid parameter: NvmeCmd(%x)/NvmeResponse(%x)\n",\r
- (UINTN)Packet->NvmeCmd, (UINTN)Packet->NvmeResponse));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Packet->QueueId != NVME_ADMIN_QUEUE && Packet->QueueId != NVME_IO_QUEUE) {\r
- DEBUG ((DEBUG_ERROR, "NvmePassThru, invalid parameter: QueueId(%x)\n",\r
- Packet->QueueId));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- PrpListHost = NULL;\r
- PrpListNo = 0;\r
- Status = EFI_SUCCESS;\r
-\r
- Qid = Packet->QueueId;\r
- Sq = Nvme->SqBuffer[Qid] + Nvme->SqTdbl[Qid].Sqt;\r
- Cq = Nvme->CqBuffer[Qid] + Nvme->CqHdbl[Qid].Cqh;\r
- if (Qid == NVME_ADMIN_QUEUE) {\r
- SqSize = NVME_ASQ_SIZE + 1;\r
- CqSize = NVME_ACQ_SIZE + 1;\r
- } else {\r
- SqSize = NVME_CSQ_DEPTH;\r
- CqSize = NVME_CCQ_DEPTH;\r
- }\r
-\r
- if (Packet->NvmeCmd->Nsid != NamespaceId) {\r
- DEBUG ((DEBUG_ERROR, "NvmePassThru: Nsid mismatch (%x, %x)\n",\r
- Packet->NvmeCmd->Nsid, NamespaceId));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- ZeroMem (Sq, sizeof (NVME_SQ));\r
- Sq->Opc = Packet->NvmeCmd->Cdw0.Opcode;\r
- Sq->Fuse = Packet->NvmeCmd->Cdw0.FusedOperation;\r
- Sq->Cid = Packet->NvmeCmd->Cdw0.Cid;\r
- Sq->Nsid = Packet->NvmeCmd->Nsid;\r
-\r
- ///\r
- /// Currently we only support PRP for Data transfer, SGL is NOT supported.\r
- ///\r
- ASSERT (Sq->Psdt == 0);\r
- if (Sq->Psdt != 0) {\r
- DEBUG ((DEBUG_ERROR, "NvmePassThru: doesn't support SGL mechanism\n"));\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Sq->Prp[0] = Packet->TransferBuffer;\r
- Sq->Prp[1] = 0;\r
-\r
- if(Packet->MetadataBuffer != (UINT64)(UINTN)NULL) {\r
- Sq->Mptr = Packet->MetadataBuffer;\r
- }\r
-\r
- ///\r
- /// If the Buffer Size spans more than two memory pages (page Size as defined in CC.Mps),\r
- /// then build a PRP list in the second PRP submission queue entry.\r
- ///\r
- Offset = ((UINT32)Sq->Prp[0]) & (EFI_PAGE_SIZE - 1);\r
- Bytes = Packet->TransferLength;\r
-\r
- if ((Offset + Bytes) > (EFI_PAGE_SIZE * 2)) {\r
- ///\r
- /// Create PrpList for remaining Data Buffer.\r
- ///\r
- PhyAddr = (Sq->Prp[0] + EFI_PAGE_SIZE) & ~(EFI_PAGE_SIZE - 1);\r
- Sq->Prp[1] = NvmeCreatePrpList (Nvme, Nvme->SqTdbl[Qid].Sqt, PhyAddr, EFI_SIZE_TO_PAGES(Offset + Bytes) - 1, &PrpListHost, &PrpListNo);\r
- if (Sq->Prp[1] == 0) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- DEBUG ((DEBUG_ERROR, "NvmeCreatePrpList fail, Status: %r\n", Status));\r
- goto EXIT;\r
- }\r
-\r
- } else if ((Offset + Bytes) > EFI_PAGE_SIZE) {\r
- Sq->Prp[1] = (Sq->Prp[0] + EFI_PAGE_SIZE) & ~(EFI_PAGE_SIZE - 1);\r
- }\r
-\r
- if(Packet->NvmeCmd->Flags & CDW10_VALID) {\r
- Sq->Payload.Raw.Cdw10 = Packet->NvmeCmd->Cdw10;\r
- }\r
- if(Packet->NvmeCmd->Flags & CDW11_VALID) {\r
- Sq->Payload.Raw.Cdw11 = Packet->NvmeCmd->Cdw11;\r
- }\r
- if(Packet->NvmeCmd->Flags & CDW12_VALID) {\r
- Sq->Payload.Raw.Cdw12 = Packet->NvmeCmd->Cdw12;\r
- }\r
- if(Packet->NvmeCmd->Flags & CDW13_VALID) {\r
- Sq->Payload.Raw.Cdw13 = Packet->NvmeCmd->Cdw13;\r
- }\r
- if(Packet->NvmeCmd->Flags & CDW14_VALID) {\r
- Sq->Payload.Raw.Cdw14 = Packet->NvmeCmd->Cdw14;\r
- }\r
- if(Packet->NvmeCmd->Flags & CDW15_VALID) {\r
- Sq->Payload.Raw.Cdw15 = Packet->NvmeCmd->Cdw15;\r
- }\r
-\r
- ///\r
- /// Ring the submission queue doorbell.\r
- ///\r
- Nvme->SqTdbl[Qid].Sqt++;\r
- if(Nvme->SqTdbl[Qid].Sqt == SqSize) {\r
- Nvme->SqTdbl[Qid].Sqt = 0;\r
- }\r
- Status = NVME_SET_SQTDBL (Nvme, Qid, &Nvme->SqTdbl[Qid]);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NVME_SET_SQTDBL fail, Status: %r\n", Status));\r
- goto EXIT;\r
- }\r
-\r
- ///\r
- /// Wait for completion queue to get filled in.\r
- ///\r
- Status = EFI_TIMEOUT;\r
- Timer = 0;\r
- while (Timer < NVME_CMD_TIMEOUT) {\r
- //DEBUG ((DEBUG_VERBOSE, "Timer: %x, Cq:\n", Timer));\r
- //DumpMem (Cq, sizeof (NVME_CQ));\r
- if (Cq->Pt != Nvme->Pt[Qid]) {\r
- Status = EFI_SUCCESS;\r
- break;\r
- }\r
-\r
- MicroSecondDelay (NVME_CMD_WAIT);\r
- Timer += NVME_CMD_WAIT;\r
- }\r
-\r
- Nvme->CqHdbl[Qid].Cqh++;\r
- if (Nvme->CqHdbl[Qid].Cqh == CqSize) {\r
- Nvme->CqHdbl[Qid].Cqh = 0;\r
- Nvme->Pt[Qid] ^= 1;\r
- }\r
-\r
- ///\r
- /// Copy the Respose Queue entry for this command to the callers response Buffer\r
- ///\r
- CopyMem (Packet->NvmeResponse, Cq, sizeof(NVM_EXPRESS_RESPONSE));\r
-\r
- if (!EFI_ERROR(Status)) { // We still need to check CQ status if no timeout error occured\r
- Status = NvmeCheckCqStatus (Cq);\r
- }\r
- NVME_SET_CQHDBL (Nvme, Qid, &Nvme->CqHdbl[Qid]);\r
-\r
-EXIT:\r
- return Status;\r
-}\r
-\r
-/**\r
- Get identify controller Data.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] Buffer - The Buffer used to store the identify controller Data.\r
-\r
- @return EFI_SUCCESS - Successfully get the identify controller Data.\r
- @return others - Fail to get the identify controller Data.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-NvmeIdentifyController (\r
- IN NVME_CONTEXT *Nvme,\r
- IN VOID *Buffer\r
- )\r
-{\r
- NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;\r
- NVM_EXPRESS_COMMAND Command;\r
- NVM_EXPRESS_RESPONSE Response;\r
- EFI_STATUS Status;\r
-\r
- ZeroMem (&CommandPacket, sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));\r
- ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));\r
- ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));\r
-\r
- Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_OPC;\r
- Command.Cdw0.Cid = Nvme->Cid[NVME_ADMIN_QUEUE]++;\r
- //\r
- // According to Nvm Express 1.1 spec Figure 38, When not used, the field shall be cleared to 0h.\r
- // For the Identify command, the Namespace Identifier is only used for the Namespace Data structure.\r
- //\r
- Command.Nsid = 0;\r
-\r
- CommandPacket.NvmeCmd = &Command;\r
- CommandPacket.NvmeResponse = &Response;\r
- CommandPacket.TransferBuffer = (UINT64)(UINTN)Buffer;\r
- CommandPacket.TransferLength = sizeof (NVME_ADMIN_CONTROLLER_DATA);\r
- CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;\r
- CommandPacket.QueueId = NVME_ADMIN_QUEUE;\r
- //\r
- // Set bit 0 (Cns bit) to 1 to identify a controller\r
- //\r
- Command.Cdw10 = 1;\r
- Command.Flags = CDW10_VALID;\r
-\r
- Status = NvmePassThru (\r
- Nvme,\r
- NVME_CONTROLLER_ID,\r
- 0,\r
- &CommandPacket\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Status = NvmeWaitAllComplete (Nvme, CommandPacket.QueueId);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Get specified identify namespace Data.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] NamespaceId - The specified namespace identifier.\r
- @param[in] Buffer - The Buffer used to store the identify namespace Data.\r
-\r
- @return EFI_SUCCESS - Successfully get the identify namespace Data.\r
- @return others - Fail to get the identify namespace Data.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-NvmeIdentifyNamespace (\r
- IN NVME_CONTEXT *Nvme,\r
- IN UINT32 NamespaceId,\r
- IN VOID *Buffer\r
- )\r
-{\r
- NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;\r
- NVM_EXPRESS_COMMAND Command;\r
- NVM_EXPRESS_RESPONSE Response;\r
- EFI_STATUS Status;\r
-\r
- ZeroMem (&CommandPacket, sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));\r
- ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));\r
- ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));\r
-\r
- CommandPacket.NvmeCmd = &Command;\r
- CommandPacket.NvmeResponse = &Response;\r
-\r
- Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_OPC;\r
- Command.Cdw0.Cid = Nvme->Cid[NVME_ADMIN_QUEUE]++;\r
- Command.Nsid = NamespaceId;\r
- CommandPacket.TransferBuffer = (UINT64)(UINTN)Buffer;\r
- CommandPacket.TransferLength = sizeof (NVME_ADMIN_NAMESPACE_DATA);\r
- CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;\r
- CommandPacket.QueueId = NVME_ADMIN_QUEUE;\r
- //\r
- // Set bit 0 (Cns bit) to 1 to identify a namespace\r
- //\r
- CommandPacket.NvmeCmd->Cdw10 = 0;\r
- CommandPacket.NvmeCmd->Flags = CDW10_VALID;\r
-\r
- Status = NvmePassThru (\r
- Nvme,\r
- NamespaceId,\r
- 0,\r
- &CommandPacket\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Status = NvmeWaitAllComplete (Nvme, CommandPacket.QueueId);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Get Block Size for specific namespace of NVME.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @return - Block Size in bytes\r
-\r
-**/\r
-STATIC\r
-UINT32\r
-NvmeGetBlockSize (\r
- IN NVME_CONTEXT *Nvme\r
- )\r
-{\r
- UINT32 BlockSize;\r
- UINT32 Lbads;\r
- UINT32 Flbas;\r
- UINT32 LbaFmtIdx;\r
-\r
- Flbas = Nvme->NamespaceData->Flbas;\r
- LbaFmtIdx = Flbas & 3;\r
- Lbads = Nvme->NamespaceData->LbaFormat[LbaFmtIdx].Lbads;\r
-\r
- BlockSize = (UINT32)1 << Lbads;\r
- return BlockSize;\r
-}\r
-\r
-/**\r
- Get last LBA for specific namespace of NVME.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @return - Last LBA address\r
-\r
-**/\r
-STATIC\r
-EFI_LBA\r
-NvmeGetLastLba (\r
- IN NVME_CONTEXT *Nvme\r
- )\r
-{\r
- EFI_LBA LastBlock;\r
- LastBlock = Nvme->NamespaceData->Nsze - 1;\r
- return LastBlock;\r
-}\r
-\r
-/**\r
- Create io completion queue.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @return EFI_SUCCESS - Successfully create io completion queue.\r
- @return others - Fail to create io completion queue.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-NvmeCreateIoCompletionQueue (\r
- IN NVME_CONTEXT *Nvme\r
- )\r
-{\r
- NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;\r
- NVM_EXPRESS_COMMAND Command;\r
- NVM_EXPRESS_RESPONSE Response;\r
- EFI_STATUS Status;\r
- NVME_ADMIN_CRIOCQ CrIoCq;\r
-\r
- ZeroMem (&CommandPacket, sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));\r
- ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));\r
- ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));\r
- ZeroMem (&CrIoCq, sizeof(NVME_ADMIN_CRIOCQ));\r
-\r
- CommandPacket.NvmeCmd = &Command;\r
- CommandPacket.NvmeResponse = &Response;\r
-\r
- Command.Cdw0.Opcode = NVME_ADMIN_CRIOCQ_OPC;\r
- Command.Cdw0.Cid = Nvme->Cid[NVME_ADMIN_QUEUE]++;\r
- CommandPacket.TransferBuffer = (UINT64)(UINTN)Nvme->CqBuffer[NVME_IO_QUEUE];\r
- CommandPacket.TransferLength = EFI_PAGE_SIZE;\r
- CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;\r
- CommandPacket.QueueId = NVME_ADMIN_QUEUE;\r
-\r
- CrIoCq.Qid = NVME_IO_QUEUE;\r
- CrIoCq.Qsize = NVME_CCQ_SIZE;\r
- CrIoCq.Pc = 1;\r
- CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoCq, sizeof (NVME_ADMIN_CRIOCQ));\r
- CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;\r
-\r
- Status = NvmePassThru (\r
- Nvme,\r
- NVME_CONTROLLER_ID,\r
- 0,\r
- &CommandPacket\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Status = NvmeWaitAllComplete (Nvme, CommandPacket.QueueId);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Create io submission queue.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @return EFI_SUCCESS - Successfully create io submission queue.\r
- @return others - Fail to create io submission queue.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-NvmeCreateIoSubmissionQueue (\r
- IN NVME_CONTEXT *Nvme\r
- )\r
-{\r
- NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;\r
- NVM_EXPRESS_COMMAND Command;\r
- NVM_EXPRESS_RESPONSE Response;\r
- EFI_STATUS Status;\r
- NVME_ADMIN_CRIOSQ CrIoSq;\r
-\r
- ZeroMem (&CommandPacket, sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));\r
- ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));\r
- ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));\r
- ZeroMem (&CrIoSq, sizeof(NVME_ADMIN_CRIOSQ));\r
-\r
- CommandPacket.NvmeCmd = &Command;\r
- CommandPacket.NvmeResponse = &Response;\r
-\r
- Command.Cdw0.Opcode = NVME_ADMIN_CRIOSQ_OPC;\r
- Command.Cdw0.Cid = Nvme->Cid[NVME_ADMIN_QUEUE]++;\r
- CommandPacket.TransferBuffer = (UINT64)(UINTN)Nvme->SqBuffer[NVME_IO_QUEUE];\r
- CommandPacket.TransferLength = EFI_PAGE_SIZE;\r
- CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;\r
- CommandPacket.QueueId = NVME_ADMIN_QUEUE;\r
-\r
- CrIoSq.Qid = NVME_IO_QUEUE;\r
- CrIoSq.Qsize = NVME_CSQ_SIZE;\r
- CrIoSq.Pc = 1;\r
- CrIoSq.Cqid = NVME_IO_QUEUE;\r
- CrIoSq.Qprio = 0;\r
- CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoSq, sizeof (NVME_ADMIN_CRIOSQ));\r
- CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;\r
-\r
- Status = NvmePassThru (\r
- Nvme,\r
- NVME_CONTROLLER_ID,\r
- 0,\r
- &CommandPacket\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Status = NvmeWaitAllComplete (Nvme, CommandPacket.QueueId);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Security send and receive commands.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] SendCommand - The flag to indicate the command type, TRUE for Send command and FALSE for receive command\r
- @param[in] SecurityProtocol - Security Protocol\r
- @param[in] SpSpecific - Security Protocol Specific\r
- @param[in] TransferLength - Transfer Length of Buffer (in bytes) - always a multiple of 512\r
- @param[in,out] TransferBuffer - Address of Data to transfer\r
-\r
- @return EFI_SUCCESS - Successfully create io submission queue.\r
- @return others - Fail to send/receive commands.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeSecuritySendReceive (\r
- IN NVME_CONTEXT *Nvme,\r
- IN BOOLEAN SendCommand,\r
- IN UINT8 SecurityProtocol,\r
- IN UINT16 SpSpecific,\r
- IN UINTN TransferLength,\r
- IN OUT VOID *TransferBuffer\r
- )\r
-{\r
- NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;\r
- NVM_EXPRESS_COMMAND Command;\r
- NVM_EXPRESS_RESPONSE Response;\r
- EFI_STATUS Status;\r
- NVME_ADMIN_SECSEND SecSend;\r
- OACS *Oacs;\r
- UINT8 Opcode;\r
- VOID* *SecBuff;\r
-\r
- Oacs = (OACS *)&Nvme->ControllerData->Oacs;\r
-\r
- //\r
- // Verify security bit for Security Send/Receive commands\r
- //\r
- if (Oacs->Security == 0) {\r
- DEBUG ((DEBUG_ERROR, "Security command doesn't support.\n"));\r
- return EFI_NOT_READY;\r
- }\r
-\r
- SecBuff = (VOID *)(UINTN) NVME_SEC_BASE (Nvme);\r
-\r
- //\r
- // Actions for sending security command\r
- //\r
- if (SendCommand) {\r
- CopyMem (SecBuff, TransferBuffer, TransferLength);\r
- }\r
-\r
- ZeroMem (&CommandPacket, sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));\r
- ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));\r
- ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));\r
- ZeroMem (&SecSend, sizeof(NVME_ADMIN_SECSEND));\r
-\r
- CommandPacket.NvmeCmd = &Command;\r
- CommandPacket.NvmeResponse = &Response;\r
-\r
- Opcode = (UINT8)(SendCommand ? NVME_ADMIN_SECURITY_SEND_OPC : NVME_ADMIN_SECURITY_RECV_OPC);\r
- Command.Cdw0.Opcode = Opcode;\r
- Command.Cdw0.Cid = Nvme->Cid[NVME_ADMIN_QUEUE]++;\r
- CommandPacket.TransferBuffer = (UINT64)(UINTN)SecBuff;\r
- CommandPacket.TransferLength = (UINT32)TransferLength;\r
- CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;\r
- CommandPacket.QueueId = NVME_ADMIN_QUEUE;\r
-\r
- SecSend.Spsp = SpSpecific;\r
- SecSend.Secp = SecurityProtocol;\r
- SecSend.Tl = (UINT32)TransferLength;\r
-\r
- CopyMem (&CommandPacket.NvmeCmd->Cdw10, &SecSend, sizeof (NVME_ADMIN_SECSEND));\r
- CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;\r
-\r
- Status = NvmePassThru (\r
- Nvme,\r
- NVME_CONTROLLER_ID,\r
- 0,\r
- &CommandPacket\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Status = NvmeWaitAllComplete (Nvme, CommandPacket.QueueId);\r
- }\r
-\r
- //\r
- // Actions for receiving security command\r
- //\r
- if (!SendCommand) {\r
- CopyMem (TransferBuffer, SecBuff, TransferLength);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Destroy io completion queue.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @return EFI_SUCCESS - Successfully destroy io completion queue.\r
- @return others - Fail to destroy io completion queue.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-NvmeDestroyIoCompletionQueue (\r
- IN NVME_CONTEXT *Nvme\r
- )\r
-{\r
- NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;\r
- NVM_EXPRESS_COMMAND Command;\r
- NVM_EXPRESS_RESPONSE Response;\r
- EFI_STATUS Status;\r
- NVME_ADMIN_DEIOCQ DelIoCq;\r
-\r
- ZeroMem (&CommandPacket, sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));\r
- ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));\r
- ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));\r
- ZeroMem (&DelIoCq, sizeof(NVME_ADMIN_DEIOCQ));\r
-\r
- CommandPacket.NvmeCmd = &Command;\r
- CommandPacket.NvmeResponse = &Response;\r
-\r
- Command.Cdw0.Opcode = NVME_ADMIN_DELIOCQ_OPC;\r
- Command.Cdw0.Cid = Nvme->Cid[NVME_ADMIN_QUEUE]++;\r
- CommandPacket.TransferBuffer = (UINT64)(UINTN)Nvme->CqBuffer[NVME_IO_QUEUE];\r
- CommandPacket.TransferLength = EFI_PAGE_SIZE;\r
- CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;\r
- CommandPacket.QueueId = NVME_ADMIN_QUEUE;\r
-\r
- DelIoCq.Qid = NVME_IO_QUEUE;\r
- CopyMem (&CommandPacket.NvmeCmd->Cdw10, &DelIoCq, sizeof (NVME_ADMIN_DEIOCQ));\r
- CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;\r
-\r
- Status = NvmePassThru (\r
- Nvme,\r
- NVME_CONTROLLER_ID,\r
- 0,\r
- &CommandPacket\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Status = NvmeWaitAllComplete (Nvme, CommandPacket.QueueId);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Destroy io submission queue.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @return EFI_SUCCESS - Successfully destroy io submission queue.\r
- @return others - Fail to destroy io submission queue.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-NvmeDestroyIoSubmissionQueue (\r
- IN NVME_CONTEXT *Nvme\r
- )\r
-{\r
- NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;\r
- NVM_EXPRESS_COMMAND Command;\r
- NVM_EXPRESS_RESPONSE Response;\r
- EFI_STATUS Status;\r
- NVME_ADMIN_DEIOSQ DelIoSq;\r
-\r
- ZeroMem (&CommandPacket, sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));\r
- ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));\r
- ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));\r
- ZeroMem (&DelIoSq, sizeof(NVME_ADMIN_DEIOSQ));\r
-\r
- CommandPacket.NvmeCmd = &Command;\r
- CommandPacket.NvmeResponse = &Response;\r
-\r
- Command.Cdw0.Opcode = NVME_ADMIN_DELIOSQ_OPC;\r
- Command.Cdw0.Cid = Nvme->Cid[NVME_ADMIN_QUEUE]++;\r
- CommandPacket.TransferBuffer = (UINT64)(UINTN)Nvme->SqBuffer[NVME_IO_QUEUE];\r
- CommandPacket.TransferLength = EFI_PAGE_SIZE;\r
- CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;\r
- CommandPacket.QueueId = NVME_ADMIN_QUEUE;\r
-\r
- DelIoSq.Qid = NVME_IO_QUEUE;\r
- CopyMem (&CommandPacket.NvmeCmd->Cdw10, &DelIoSq, sizeof (NVME_ADMIN_DEIOSQ));\r
- CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;\r
-\r
- Status = NvmePassThru (\r
- Nvme,\r
- NVME_CONTROLLER_ID,\r
- 0,\r
- &CommandPacket\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Status = NvmeWaitAllComplete (Nvme, CommandPacket.QueueId);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Allocate transfer-related Data struct which is used at Nvme.\r
-\r
- @param[in] ImageHandle Image handle for this driver image\r
- @param[in] Nvme The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @retval EFI_OUT_OF_RESOURCE The allocation is failure.\r
- @retval EFI_SUCCESS Successful to allocate memory.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-NvmeAllocateResource (\r
- IN EFI_HANDLE ImageHandle,\r
- IN NVME_CONTEXT *Nvme\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_PHYSICAL_ADDRESS Addr;\r
- UINT32 Size;\r
-\r
- //\r
- // Allocate resources required by NVMe host controller.\r
- //\r
- // NBAR\r
- Size = 0x10000;\r
- Addr = 0xFFFFFFFF;\r
- Status = gDS->AllocateMemorySpace (\r
- EfiGcdAllocateMaxAddressSearchBottomUp,\r
- EfiGcdMemoryTypeMemoryMappedIo,\r
- 15, // 2^15: 32K Alignment\r
- Size,\r
- &Addr,\r
- ImageHandle,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- Nvme->Nbar = (UINT32) Addr;\r
-\r
- // DMA Buffer\r
- Size = NVME_MEM_MAX_SIZE;\r
- Addr = 0xFFFFFFFF;\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiACPIMemoryNVS,\r
- EFI_SIZE_TO_PAGES (Size),\r
- (EFI_PHYSICAL_ADDRESS *)&Addr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- Nvme->BaseMem = (UINT32) Addr;\r
-\r
- // Clean up DMA Buffer before using\r
- ZeroMem ((VOID *)(UINTN)Addr, NVME_MEM_MAX_SIZE);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Free allocated transfer-related Data struct which is used at NVMe.\r
-\r
- @param[in] Nvme The pointer to the NVME_CONTEXT Data structure.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-NvmeFreeResource (\r
- IN NVME_CONTEXT *Nvme\r
- )\r
-{\r
- UINT32 Size;\r
-\r
- // NBAR\r
- if (Nvme->BaseMem != 0) {\r
- Size = 0x10000;\r
- gDS->FreeMemorySpace (Nvme->Nbar, Size);\r
- }\r
-\r
- // DMA Buffer\r
- if (Nvme->Nbar != 0) {\r
- Size = NVME_MEM_MAX_SIZE;\r
- gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN) Nvme->Nbar, EFI_SIZE_TO_PAGES (Size));\r
- }\r
-}\r
-\r
-\r
-/**\r
- Initialize the Nvm Express controller.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @retval EFI_SUCCESS - The NVM Express Controller is initialized successfully.\r
- @retval Others - A device error occurred while initializing the controller.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeControllerInit (\r
- IN NVME_CONTEXT *Nvme\r
- )\r
-{\r
- EFI_STATUS Status;\r
- NVME_AQA Aqa;\r
- NVME_ASQ Asq;\r
- NVME_ACQ Acq;\r
- NVME_VER Ver;\r
-\r
- UINT32 MlBAR;\r
- UINT32 MuBAR;\r
-\r
- ///\r
- /// Update PCIE BAR0/1 for NVME device\r
- ///\r
- MlBAR = Nvme->Nbar;\r
- MuBAR = 0;\r
- PciWrite32 (Nvme->PciBase + 0x10, MlBAR); // MLBAR (BAR0)\r
- PciWrite32 (Nvme->PciBase + 0x14, MuBAR); // MUBAR (BAR1)\r
-\r
- ///\r
- /// Enable PCIE decode\r
- ///\r
- PciWrite8 (Nvme->PciBase + NVME_PCIE_PCICMD, 0x6);\r
-\r
- // Version\r
- NVME_GET_VER (Nvme, &Ver);\r
- if (!(Ver.Mjr == 0x0001) && (Ver.Mnr == 0x0000)) {\r
- DEBUG ((DEBUG_INFO, "\n!!!\n!!! NVME Version mismatch for the implementation !!!\n!!!\n"));\r
- }\r
-\r
- ///\r
- /// Read the Controller Capabilities register and verify that the NVM command set is supported\r
- ///\r
- Status = NVME_GET_CAP (Nvme, &Nvme->Cap);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR, "NVME_GET_CAP fail, Status: %r\n", Status));\r
- goto Done;\r
- }\r
-\r
- if (Nvme->Cap.Css != 0x01) {\r
- DEBUG ((DEBUG_ERROR, "NvmeControllerInit fail: the controller doesn't support NVMe command set\n"));\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- ///\r
- /// Currently the driver only supports 4k page Size.\r
- ///\r
- if ((Nvme->Cap.Mpsmin + 12) > EFI_PAGE_SHIFT) {\r
- DEBUG ((DEBUG_ERROR, "NvmeControllerInit fail: only supports 4k page Size\n"));\r
- ASSERT (FALSE);\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- Nvme->Cid[0] = 0;\r
- Nvme->Cid[1] = 0;\r
-\r
- Nvme->Pt[0] = 0;\r
- Nvme->Pt[1] = 0;\r
-\r
- ZeroMem ((VOID *)(UINTN)(&(Nvme->SqTdbl[0])), sizeof (NVME_SQTDBL) * NVME_MAX_IO_QUEUES);\r
- ZeroMem ((VOID *)(UINTN)(&(Nvme->CqHdbl[0])), sizeof (NVME_CQHDBL) * NVME_MAX_IO_QUEUES);\r
-\r
- ZeroMem ((VOID *)(UINTN)Nvme->BaseMem, NVME_MEM_MAX_SIZE);\r
-\r
- Status = NvmeDisableController (Nvme);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NvmeDisableController fail, Status: %r\n", Status));\r
- goto Done;\r
- }\r
-\r
- ///\r
- /// set number of entries admin submission & completion queues.\r
- ///\r
- Aqa.Asqs = NVME_ASQ_SIZE;\r
- Aqa.Rsvd1 = 0;\r
- Aqa.Acqs = NVME_ACQ_SIZE;\r
- Aqa.Rsvd2 = 0;\r
-\r
- ///\r
- /// Address of admin submission queue.\r
- ///\r
- Asq = (UINT64)(UINTN)(NVME_ASQ_BASE (Nvme) & ~0xFFF);\r
-\r
- ///\r
- /// Address of admin completion queue.\r
- ///\r
- Acq = (UINT64)(UINTN)(NVME_ACQ_BASE (Nvme) & ~0xFFF);\r
-\r
- ///\r
- /// Address of I/O submission & completion queue.\r
- ///\r
- Nvme->SqBuffer[0] = (NVME_SQ *)(UINTN)NVME_ASQ_BASE (Nvme); // NVME_ADMIN_QUEUE\r
- Nvme->CqBuffer[0] = (NVME_CQ *)(UINTN)NVME_ACQ_BASE (Nvme); // NVME_ADMIN_QUEUE\r
- Nvme->SqBuffer[1] = (NVME_SQ *)(UINTN)NVME_SQ_BASE (Nvme, 0); // NVME_IO_QUEUE\r
- Nvme->CqBuffer[1] = (NVME_CQ *)(UINTN)NVME_CQ_BASE (Nvme, 0); // NVME_IO_QUEUE\r
-\r
- DEBUG ((DEBUG_INFO, "BaseMem = [%08X]\n", Nvme->BaseMem));\r
- DEBUG ((DEBUG_INFO, "Admin Submission Queue Size (Aqa.Asqs) = [%08X]\n", Aqa.Asqs));\r
- DEBUG ((DEBUG_INFO, "Admin Completion Queue Size (Aqa.Acqs) = [%08X]\n", Aqa.Acqs));\r
- DEBUG ((DEBUG_INFO, "Admin Submission Queue (SqBuffer[0]) = [%08X]\n", Nvme->SqBuffer[0]));\r
- DEBUG ((DEBUG_INFO, "Admin Completion Queue (CqBuffer[0]) = [%08X]\n", Nvme->CqBuffer[0]));\r
- DEBUG ((DEBUG_INFO, "I/O Submission Queue (SqBuffer[1]) = [%08X]\n", Nvme->SqBuffer[1]));\r
- DEBUG ((DEBUG_INFO, "I/O Completion Queue (CqBuffer[1]) = [%08X]\n", Nvme->CqBuffer[1]));\r
-\r
- ///\r
- /// Program admin queue attributes.\r
- ///\r
- Status = NVME_SET_AQA (Nvme, &Aqa);\r
- if (EFI_ERROR(Status)) {\r
- goto Done;\r
- }\r
-\r
- ///\r
- /// Program admin submission queue address.\r
- ///\r
- Status = NVME_SET_ASQ (Nvme, &Asq);\r
- if (EFI_ERROR(Status)) {\r
- goto Done;\r
- }\r
-\r
- ///\r
- /// Program admin completion queue address.\r
- ///\r
- Status = NVME_SET_ACQ (Nvme, &Acq);\r
- if (EFI_ERROR(Status)) {\r
- goto Done;\r
- }\r
-\r
- Status = NvmeEnableController (Nvme);\r
- if (EFI_ERROR(Status)) {\r
- goto Done;\r
- }\r
-\r
- ///\r
- /// Create one I/O completion queue.\r
- ///\r
- Status = NvmeCreateIoCompletionQueue (Nvme);\r
- if (EFI_ERROR(Status)) {\r
- goto Done;\r
- }\r
-\r
- ///\r
- /// Create one I/O Submission queue.\r
- ///\r
- Status = NvmeCreateIoSubmissionQueue (Nvme);\r
- if (EFI_ERROR(Status)) {\r
- goto Done;\r
- }\r
-\r
- ///\r
- /// Get current Identify Controller Data\r
- ///\r
- Nvme->ControllerData = (NVME_ADMIN_CONTROLLER_DATA *)(UINTN) NVME_CONTROL_DATA_BASE (Nvme);\r
- Status = NvmeIdentifyController (Nvme, Nvme->ControllerData);\r
- if (EFI_ERROR(Status)) {\r
- goto Done;\r
- }\r
-\r
- ///\r
- /// Dump NvmExpress Identify Controller Data\r
- ///\r
- Nvme->ControllerData->Sn[19] = 0;\r
- Nvme->ControllerData->Mn[39] = 0;\r
- //NvmeDumpIdentifyController (Nvme->ControllerData);\r
-\r
- ///\r
- /// Get current Identify Namespace Data\r
- ///\r
- Nvme->NamespaceData = (NVME_ADMIN_NAMESPACE_DATA *)NVME_NAMESPACE_DATA_BASE (Nvme);\r
- Status = NvmeIdentifyNamespace (Nvme, Nvme->Nsid, Nvme->NamespaceData);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NvmeIdentifyNamespace fail, Status = %r\n", Status));\r
- goto Done;\r
- }\r
-\r
- ///\r
- /// Dump NvmExpress Identify Namespace Data\r
- ///\r
- if (Nvme->NamespaceData->Ncap == 0) {\r
- DEBUG ((DEBUG_ERROR, "Invalid Namespace, Ncap: %lx\n", Nvme->NamespaceData->Ncap));\r
- Status = EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\r
-\r
- Nvme->BlockSize = NvmeGetBlockSize (Nvme);\r
- Nvme->LastBlock = NvmeGetLastLba (Nvme);\r
-\r
- Nvme->State = NvmeStatusInit;\r
-\r
- return EFI_SUCCESS;\r
-\r
-Done:\r
- return Status;\r
-}\r
-\r
-/**\r
- Un-initialize the Nvm Express controller.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @retval EFI_SUCCESS - The NVM Express Controller is un-initialized successfully.\r
- @retval Others - A device error occurred while un-initializing the controller.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeControllerExit (\r
- IN NVME_CONTEXT *Nvme\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- Status = EFI_SUCCESS;\r
- if (Nvme->State == NvmeStatusInit || Nvme->State == NvmeStatusMax) {\r
- ///\r
- /// Destroy I/O Submission queue.\r
- ///\r
- Status = NvmeDestroyIoSubmissionQueue (Nvme);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NvmeDestroyIoSubmissionQueue fail, Status = %r\n", Status));\r
- return Status;\r
- }\r
-\r
- ///\r
- /// Destroy I/O completion queue.\r
- ///\r
- Status = NvmeDestroyIoCompletionQueue (Nvme);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NvmeDestroyIoCompletionQueue fail, Status = %r\n", Status));\r
- return Status;\r
- }\r
-\r
- Status = NvmeShutdownController (Nvme);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NvmeShutdownController fail, Status: %r\n", Status));\r
- }\r
- }\r
-\r
- ///\r
- /// Disable PCIE decode\r
- ///\r
- PciWrite8 (Nvme->PciBase + NVME_PCIE_PCICMD, 0x0);\r
- PciWrite32 (Nvme->PciBase + 0x10, 0); // MLBAR (BAR0)\r
- PciWrite32 (Nvme->PciBase + 0x14, 0); // MUBAR (BAR1)\r
-\r
- Nvme->State = NvmeStatusUnknown;\r
- return Status;\r
-}\r
-\r
-/**\r
- Read sector Data from the NVMe device.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in,out] Buffer - The Buffer used to store the Data read from the device.\r
- @param[in] Lba - The start block number.\r
- @param[in] Blocks - Total block number to be read.\r
-\r
- @retval EFI_SUCCESS - Datum are read from the device.\r
- @retval Others - Fail to read all the datum.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeReadSectors (\r
- IN NVME_CONTEXT *Nvme,\r
- IN OUT UINT64 Buffer,\r
- IN UINT64 Lba,\r
- IN UINT32 Blocks\r
- )\r
-{\r
- UINT32 Bytes;\r
- NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;\r
- NVM_EXPRESS_COMMAND Command;\r
- NVM_EXPRESS_RESPONSE Response;\r
- EFI_STATUS Status;\r
- UINT32 BlockSize;\r
-\r
- BlockSize = Nvme->BlockSize;\r
- Bytes = Blocks * BlockSize;\r
-\r
- ZeroMem (&CommandPacket, sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));\r
- ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));\r
- ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));\r
-\r
- CommandPacket.NvmeCmd = &Command;\r
- CommandPacket.NvmeResponse = &Response;\r
-\r
- CommandPacket.NvmeCmd->Cdw0.Opcode = NVME_IO_READ_OPC;\r
- CommandPacket.NvmeCmd->Cdw0.Cid = Nvme->Cid[NVME_IO_QUEUE]++;\r
- CommandPacket.NvmeCmd->Nsid = Nvme->Nsid;\r
- CommandPacket.TransferBuffer = Buffer;\r
-\r
- CommandPacket.TransferLength = Bytes;\r
- CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;\r
- CommandPacket.QueueId = NVME_IO_QUEUE;\r
-\r
- CommandPacket.NvmeCmd->Cdw10 = (UINT32)Lba;\r
- CommandPacket.NvmeCmd->Cdw11 = (UINT32)(RShiftU64 (Lba, 32));\r
- CommandPacket.NvmeCmd->Cdw12 = (Blocks - 1) & 0xFFFF;\r
-\r
- CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID | CDW12_VALID;\r
-\r
- Status = NvmePassThru (\r
- Nvme,\r
- Nvme->Nsid,\r
- 0,\r
- &CommandPacket\r
- );\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Write sector Data to the NVMe device.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] Buffer - The Buffer to be written into the device.\r
- @param[in] Lba - The start block number.\r
- @param[in] Blocks - Total block number to be written.\r
-\r
- @retval EFI_SUCCESS - Datum are written into the Buffer.\r
- @retval Others - Fail to write all the datum.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeWriteSectors (\r
- IN NVME_CONTEXT *Nvme,\r
- IN UINT64 Buffer,\r
- IN UINT64 Lba,\r
- IN UINT32 Blocks\r
- )\r
-{\r
- NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;\r
- NVM_EXPRESS_COMMAND Command;\r
- NVM_EXPRESS_RESPONSE Response;\r
- EFI_STATUS Status;\r
- UINT32 Bytes;\r
- UINT32 BlockSize;\r
-\r
- BlockSize = Nvme->BlockSize;\r
- Bytes = Blocks * BlockSize;\r
-\r
- ZeroMem (&CommandPacket, sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));\r
- ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));\r
- ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));\r
-\r
- CommandPacket.NvmeCmd = &Command;\r
- CommandPacket.NvmeResponse = &Response;\r
-\r
- CommandPacket.NvmeCmd->Cdw0.Opcode = NVME_IO_WRITE_OPC;\r
- CommandPacket.NvmeCmd->Cdw0.Cid = Nvme->Cid[NVME_IO_QUEUE]++;\r
- CommandPacket.NvmeCmd->Nsid = Nvme->Nsid;\r
- CommandPacket.TransferBuffer = Buffer;\r
-\r
- CommandPacket.TransferLength = Bytes;\r
- CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;\r
- CommandPacket.QueueId = NVME_IO_QUEUE;\r
-\r
- CommandPacket.NvmeCmd->Cdw10 = (UINT32)Lba;\r
- CommandPacket.NvmeCmd->Cdw11 = (UINT32)(RShiftU64 (Lba, 32));\r
- CommandPacket.NvmeCmd->Cdw12 = (Blocks - 1) & 0xFFFF;\r
-\r
- CommandPacket.MetadataBuffer = (UINT64)(UINTN)NULL;\r
- CommandPacket.MetadataLength = 0;\r
-\r
- CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID | CDW12_VALID;\r
-\r
- Status = NvmePassThru (\r
- Nvme,\r
- Nvme->Nsid,\r
- 0,\r
- &CommandPacket\r
- );\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Flushes all modified Data to the device.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @retval EFI_SUCCESS - Datum are written into the Buffer.\r
- @retval Others - Fail to write all the datum.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeFlush (\r
- IN NVME_CONTEXT *Nvme\r
- )\r
-{\r
- NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;\r
- NVM_EXPRESS_COMMAND Command;\r
- NVM_EXPRESS_RESPONSE Response;\r
- EFI_STATUS Status;\r
-\r
- ZeroMem (&CommandPacket, sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));\r
- ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));\r
- ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));\r
-\r
- CommandPacket.NvmeCmd = &Command;\r
- CommandPacket.NvmeResponse = &Response;\r
-\r
- CommandPacket.NvmeCmd->Cdw0.Opcode = NVME_IO_FLUSH_OPC;\r
- CommandPacket.NvmeCmd->Cdw0.Cid = Nvme->Cid[NVME_IO_QUEUE]++;\r
- CommandPacket.NvmeCmd->Nsid = Nvme->Nsid;\r
- CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;\r
- CommandPacket.QueueId = NVME_IO_QUEUE;\r
-\r
- Status = NvmePassThru (\r
- Nvme,\r
- Nvme->Nsid,\r
- 0,\r
- &CommandPacket\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Status = NvmeWaitAllComplete (Nvme, CommandPacket.QueueId);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Read some blocks from the device.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[out] Buffer - The Buffer used to store the Data read from the device.\r
- @param[in] Lba - The start block number.\r
- @param[in] Blocks - Total block number to be read.\r
-\r
- @retval EFI_SUCCESS - Datum are read from the device.\r
- @retval Others - Fail to read all the datum.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeRead (\r
- IN NVME_CONTEXT *Nvme,\r
- OUT UINT64 Buffer,\r
- IN UINT64 Lba,\r
- IN UINTN Blocks\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 BlockSize;\r
- UINT32 MaxTransferBlocks;\r
-\r
- ASSERT (Blocks <= NVME_MAX_SECTORS);\r
- Status = EFI_SUCCESS;\r
- BlockSize = Nvme->BlockSize;\r
- if (Nvme->ControllerData->Mdts != 0) {\r
- MaxTransferBlocks = (1 << (Nvme->ControllerData->Mdts)) * (1 << (Nvme->Cap.Mpsmin + 12)) / BlockSize;\r
- } else {\r
- MaxTransferBlocks = 1024;\r
- }\r
-\r
- while (Blocks > 0) {\r
- if (Blocks > MaxTransferBlocks) {\r
- Status = NvmeReadSectors (Nvme, Buffer, Lba, MaxTransferBlocks);\r
-\r
- Blocks -= MaxTransferBlocks;\r
- Buffer += (MaxTransferBlocks * BlockSize);\r
- Lba += MaxTransferBlocks;\r
- } else {\r
- Status = NvmeReadSectors (Nvme, Buffer, Lba, (UINT32) Blocks);\r
- Blocks = 0;\r
- }\r
-\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NvmeRead fail, Status = %r\n", Status));\r
- break;\r
- }\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Write some blocks to the device.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] Buffer - The Buffer to be written into the device.\r
- @param[in] Lba - The start block number.\r
- @param[in] Blocks - Total block number to be written.\r
-\r
- @retval EFI_SUCCESS - Datum are written into the Buffer.\r
- @retval Others - Fail to write all the datum.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeWrite (\r
- IN NVME_CONTEXT *Nvme,\r
- IN UINT64 Buffer,\r
- IN UINT64 Lba,\r
- IN UINTN Blocks\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 BlockSize;\r
- UINT32 MaxTransferBlocks;\r
-\r
- ASSERT (Blocks <= NVME_MAX_SECTORS);\r
- Status = EFI_SUCCESS;\r
- BlockSize = Nvme->BlockSize;\r
-\r
- if (Nvme->ControllerData->Mdts != 0) {\r
- MaxTransferBlocks = (1 << (Nvme->ControllerData->Mdts)) * (1 << (Nvme->Cap.Mpsmin + 12)) / BlockSize;\r
- } else {\r
- MaxTransferBlocks = 1024;\r
- }\r
-\r
- while (Blocks > 0) {\r
- if (Blocks > MaxTransferBlocks) {\r
- Status = NvmeWriteSectors (Nvme, Buffer, Lba, MaxTransferBlocks);\r
-\r
- Blocks -= MaxTransferBlocks;\r
- Buffer += (MaxTransferBlocks * BlockSize);\r
- Lba += MaxTransferBlocks;\r
- } else {\r
- Status = NvmeWriteSectors (Nvme, Buffer, Lba, (UINT32) Blocks);\r
- Blocks = 0;\r
- }\r
-\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((DEBUG_ERROR, "NvmeWrite fail, Status = %r\n", Status));\r
- break;\r
- }\r
- }\r
-\r
- return Status;\r
-}\r
+++ /dev/null
-/** @file\r
- Header file for NVMe function definitions\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#ifndef __OPAL_PASSWORD_NVME_MODE_H__\r
-#define __OPAL_PASSWORD_NVME_MODE_H__\r
-\r
-\r
-#include "OpalNvmeReg.h"\r
-\r
-#define NVME_MAX_SECTORS 0x10000\r
-//\r
-// QueueId\r
-//\r
-#define NVME_ADMIN_QUEUE 0x00\r
-#define NVME_IO_QUEUE 0x01\r
-\r
-typedef struct {\r
- UINT8 Opcode;\r
- UINT8 FusedOperation;\r
- #define NORMAL_CMD 0x00\r
- #define FUSED_FIRST_CMD 0x01\r
- #define FUSED_SECOND_CMD 0x02\r
- UINT16 Cid;\r
-} NVME_CDW0;\r
-\r
-typedef struct {\r
- NVME_CDW0 Cdw0;\r
- UINT8 Flags;\r
- #define CDW10_VALID 0x01\r
- #define CDW11_VALID 0x02\r
- #define CDW12_VALID 0x04\r
- #define CDW13_VALID 0x08\r
- #define CDW14_VALID 0x10\r
- #define CDW15_VALID 0x20\r
- UINT32 Nsid;\r
- UINT32 Cdw10;\r
- UINT32 Cdw11;\r
- UINT32 Cdw12;\r
- UINT32 Cdw13;\r
- UINT32 Cdw14;\r
- UINT32 Cdw15;\r
-} NVM_EXPRESS_COMMAND;\r
-\r
-typedef struct {\r
- UINT32 Cdw0;\r
- UINT32 Cdw1;\r
- UINT32 Cdw2;\r
- UINT32 Cdw3;\r
-} NVM_EXPRESS_RESPONSE;\r
-\r
-typedef struct {\r
- UINT64 CommandTimeout;\r
- UINT64 TransferBuffer;\r
- UINT32 TransferLength;\r
- UINT64 MetadataBuffer;\r
- UINT32 MetadataLength;\r
- UINT8 QueueId;\r
- NVM_EXPRESS_COMMAND *NvmeCmd;\r
- NVM_EXPRESS_RESPONSE *NvmeResponse;\r
-} NVM_EXPRESS_PASS_THRU_COMMAND_PACKET;\r
-\r
-\r
-#pragma pack(1)\r
-\r
-// Internal fields\r
-typedef enum {\r
- NvmeStatusUnknown,\r
- NvmeStatusInit,\r
- NvmeStatusInuse,\r
- NvmeStatusMax,\r
-} NVME_STATUS;\r
-\r
-typedef struct {\r
- UINT32 Nbar;\r
- UINT32 BaseMem;\r
- BOOLEAN PollCancellation;\r
- UINT16 NvmeInitWaitTime;\r
-\r
- NVME_STATUS State;\r
- UINT8 BusID;\r
- UINT8 DeviceID;\r
- UINT8 FuncID;\r
- UINTN PciBase;\r
-\r
- UINT32 Nsid;\r
- UINT64 Nsuuid;\r
- UINT32 BlockSize;\r
- EFI_LBA LastBlock;\r
-\r
- //\r
- // Pointers to 4kB aligned submission & completion queues.\r
- //\r
- NVME_SQ *SqBuffer[NVME_MAX_IO_QUEUES];\r
- NVME_CQ *CqBuffer[NVME_MAX_IO_QUEUES];\r
- UINT16 Cid[NVME_MAX_IO_QUEUES];\r
-\r
- //\r
- // Submission and completion queue indices.\r
- //\r
- NVME_SQTDBL SqTdbl[NVME_MAX_IO_QUEUES];\r
- NVME_CQHDBL CqHdbl[NVME_MAX_IO_QUEUES];\r
- UINT8 Pt[NVME_MAX_IO_QUEUES];\r
-\r
- UINTN SqeCount[NVME_MAX_IO_QUEUES];\r
-\r
- //\r
- // Nvme controller capabilities\r
- //\r
- NVME_CAP Cap;\r
-\r
- //\r
- // pointer to identify controller Data\r
- //\r
- NVME_ADMIN_CONTROLLER_DATA *ControllerData;\r
- NVME_ADMIN_NAMESPACE_DATA *NamespaceData;\r
-} NVME_CONTEXT;\r
-\r
-#pragma pack()\r
-\r
-/**\r
- Transfer MMIO Data to memory.\r
-\r
- @param[in,out] MemBuffer - Destination: Memory address\r
- @param[in] MmioAddr - Source: MMIO address\r
- @param[in] Size - Size for read\r
-\r
- @retval EFI_SUCCESS - MMIO read sucessfully\r
-**/\r
-EFI_STATUS\r
-NvmeMmioRead (\r
- IN OUT VOID *MemBuffer,\r
- IN UINTN MmioAddr,\r
- IN UINTN Size\r
- );\r
-\r
-/**\r
- Transfer memory Data to MMIO.\r
-\r
- @param[in,out] MmioAddr - Destination: MMIO address\r
- @param[in] MemBuffer - Source: Memory address\r
- @param[in] Size - Size for write\r
-\r
- @retval EFI_SUCCESS - MMIO write sucessfully\r
-**/\r
-EFI_STATUS\r
-NvmeMmioWrite (\r
- IN OUT UINTN MmioAddr,\r
- IN VOID *MemBuffer,\r
- IN UINTN Size\r
- );\r
-\r
-/**\r
- Transfer memory data to MMIO.\r
-\r
- @param[in,out] MmioAddr - Destination: MMIO address\r
- @param[in] MemBuffer - Source: Memory address\r
- @param[in] Size - Size for write\r
-\r
- @retval EFI_SUCCESS - MMIO write sucessfully\r
-**/\r
-EFI_STATUS\r
-OpalPciWrite (\r
- IN OUT UINTN MmioAddr,\r
- IN VOID *MemBuffer,\r
- IN UINTN Size\r
- );\r
-\r
-/**\r
- Transfer MMIO data to memory.\r
-\r
- @param[in,out] MemBuffer - Destination: Memory address\r
- @param[in] MmioAddr - Source: MMIO address\r
- @param[in] Size - Size for read\r
-\r
- @retval EFI_SUCCESS - MMIO read sucessfully\r
-**/\r
-EFI_STATUS\r
-OpalPciRead (\r
- IN OUT VOID *MemBuffer,\r
- IN UINTN MmioAddr,\r
- IN UINTN Size\r
- );\r
-\r
-/**\r
- Allocate transfer-related Data struct which is used at Nvme.\r
-\r
- @param[in] ImageHandle Image handle for this driver image\r
- @param[in] Nvme The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @retval EFI_OUT_OF_RESOURCE The allocation is failure.\r
- @retval EFI_SUCCESS Successful to allocate memory.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-NvmeAllocateResource (\r
- IN EFI_HANDLE ImageHandle,\r
- IN NVME_CONTEXT *Nvme\r
- );\r
-\r
-/**\r
- Free allocated transfer-related Data struct which is used at NVMe.\r
-\r
- @param[in] Nvme The pointer to the NVME_CONTEXT Data structure.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-NvmeFreeResource (\r
- IN NVME_CONTEXT *Nvme\r
- );\r
-\r
-/**\r
- Sends an NVM Express Command Packet to an NVM Express controller or namespace. This function supports\r
- both blocking I/O and nonblocking I/O. The blocking I/O functionality is required, and the nonblocking\r
- I/O functionality is optional.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] NamespaceId - Is a 32 bit Namespace ID to which the Express HCI command packet will be sent.\r
- A Value of 0 denotes the NVM Express controller, a Value of all 0FFh in the namespace\r
- ID specifies that the command packet should be sent to all valid namespaces.\r
- @param[in] NamespaceUuid - Is a 64 bit Namespace UUID to which the Express HCI command packet will be sent.\r
- A Value of 0 denotes the NVM Express controller, a Value of all 0FFh in the namespace\r
- UUID specifies that the command packet should be sent to all valid namespaces.\r
- @param[in,out] Packet - A pointer to the NVM Express HCI Command Packet to send to the NVMe namespace specified\r
- by NamespaceId.\r
-\r
- @retval EFI_SUCCESS - The NVM Express Command Packet was sent by the host. TransferLength bytes were transferred\r
- to, or from DataBuffer.\r
- @retval EFI_NOT_READY - The NVM Express Command Packet could not be sent because the controller is not ready. The caller\r
- may retry again later.\r
- @retval EFI_DEVICE_ERROR - A device error occurred while attempting to send the NVM Express Command Packet.\r
- @retval EFI_INVALID_PARAMETER - Namespace, or the contents of NVM_EXPRESS_PASS_THRU_COMMAND_PACKET are invalid. The NVM\r
- Express Command Packet was not sent, so no additional status information is available.\r
- @retval EFI_UNSUPPORTED - The command described by the NVM Express Command Packet is not supported by the host adapter.\r
- The NVM Express Command Packet was not sent, so no additional status information is available.\r
- @retval EFI_TIMEOUT - A timeout occurred while waiting for the NVM Express Command Packet to execute.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmePassThru (\r
- IN NVME_CONTEXT *Nvme,\r
- IN UINT32 NamespaceId,\r
- IN UINT64 NamespaceUuid,\r
- IN OUT NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet\r
- );\r
-\r
-/**\r
- Waits until all NVME commands completed.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] Qid - Queue index\r
-\r
- @retval EFI_SUCCESS - All NVME commands have completed\r
- @retval EFI_TIMEOUT - Timeout occured\r
- @retval EFI_NOT_READY - Not all NVME commands have completed\r
- @retval others - Error occurred on device side.\r
-**/\r
-EFI_STATUS\r
-NvmeWaitAllComplete (\r
- IN NVME_CONTEXT *Nvme,\r
- IN UINT8 Qid\r
- );\r
-\r
-/**\r
- Initialize the Nvm Express controller.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @retval EFI_SUCCESS - The NVM Express Controller is initialized successfully.\r
- @retval Others - A device error occurred while initializing the controller.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeControllerInit (\r
- IN NVME_CONTEXT *Nvme\r
- );\r
-\r
-/**\r
- Un-initialize the Nvm Express controller.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @retval EFI_SUCCESS - The NVM Express Controller is un-initialized successfully.\r
- @retval Others - A device error occurred while un-initializing the controller.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeControllerExit (\r
- IN NVME_CONTEXT *Nvme\r
- );\r
-\r
-/**\r
- Check whether there are available command slots.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] Qid - Queue index\r
-\r
- @retval EFI_SUCCESS - Available command slot is found\r
- @retval EFI_NOT_READY - No available command slot is found\r
- @retval EFI_DEVICE_ERROR - Error occurred on device side.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeHasFreeCmdSlot (\r
- IN NVME_CONTEXT *Nvme,\r
- IN UINT8 Qid\r
- );\r
-\r
-/**\r
- Check whether all command slots are clean.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] Qid - Queue index\r
-\r
- @retval EFI_SUCCESS - All command slots are clean\r
- @retval EFI_NOT_READY - Not all command slots are clean\r
- @retval EFI_DEVICE_ERROR - Error occurred on device side.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeIsAllCmdSlotClean (\r
- IN NVME_CONTEXT *Nvme,\r
- IN UINT8 Qid\r
- );\r
-\r
-/**\r
- Read sector Data from the NVMe device.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in,out] Buffer - The Buffer used to store the Data read from the device.\r
- @param[in] Lba - The start block number.\r
- @param[in] Blocks - Total block number to be read.\r
-\r
- @retval EFI_SUCCESS - Datum are read from the device.\r
- @retval Others - Fail to read all the datum.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeReadSectors (\r
- IN NVME_CONTEXT *Nvme,\r
- IN OUT UINT64 Buffer,\r
- IN UINT64 Lba,\r
- IN UINT32 Blocks\r
- );\r
-\r
-/**\r
- Write sector Data to the NVMe device.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] Buffer - The Buffer to be written into the device.\r
- @param[in] Lba - The start block number.\r
- @param[in] Blocks - Total block number to be written.\r
-\r
- @retval EFI_SUCCESS - Datum are written into the Buffer.\r
- @retval Others - Fail to write all the datum.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeWriteSectors (\r
- IN NVME_CONTEXT *Nvme,\r
- IN UINT64 Buffer,\r
- IN UINT64 Lba,\r
- IN UINT32 Blocks\r
- );\r
-\r
-/**\r
- Flushes all modified Data to the device.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
-\r
- @retval EFI_SUCCESS - Datum are written into the Buffer.\r
- @retval Others - Fail to write all the datum.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeFlush (\r
- IN NVME_CONTEXT *Nvme\r
- );\r
-\r
-/**\r
- Read some blocks from the device.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[out] Buffer - The Buffer used to store the Data read from the device.\r
- @param[in] Lba - The start block number.\r
- @param[in] Blocks - Total block number to be read.\r
-\r
- @retval EFI_SUCCESS - Datum are read from the device.\r
- @retval Others - Fail to read all the datum.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeRead (\r
- IN NVME_CONTEXT *Nvme,\r
- OUT UINT64 Buffer,\r
- IN UINT64 Lba,\r
- IN UINTN Blocks\r
- );\r
-\r
-/**\r
- Write some blocks to the device.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] Buffer - The Buffer to be written into the device.\r
- @param[in] Lba - The start block number.\r
- @param[in] Blocks - Total block number to be written.\r
-\r
- @retval EFI_SUCCESS - Datum are written into the Buffer.\r
- @retval Others - Fail to write all the datum.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeWrite (\r
- IN NVME_CONTEXT *Nvme,\r
- IN UINT64 Buffer,\r
- IN UINT64 Lba,\r
- IN UINTN Blocks\r
- );\r
-\r
-/**\r
- Security send and receive commands.\r
-\r
- @param[in] Nvme - The pointer to the NVME_CONTEXT Data structure.\r
- @param[in] SendCommand - The flag to indicate the command type, TRUE for Send command and FALSE for receive command\r
- @param[in] SecurityProtocol - Security Protocol\r
- @param[in] SpSpecific - Security Protocol Specific\r
- @param[in] TransferLength - Transfer Length of Buffer (in bytes) - always a multiple of 512\r
- @param[in,out] TransferBuffer - Address of Data to transfer\r
-\r
- @return EFI_SUCCESS - Successfully create io submission queue.\r
- @return others - Fail to send/receive commands.\r
-\r
-**/\r
-EFI_STATUS\r
-NvmeSecuritySendReceive (\r
- IN NVME_CONTEXT *Nvme,\r
- IN BOOLEAN SendCommand,\r
- IN UINT8 SecurityProtocol,\r
- IN UINT16 SpSpecific,\r
- IN UINTN TransferLength,\r
- IN OUT VOID *TransferBuffer\r
- );\r
-\r
-#endif\r
+++ /dev/null
-/** @file\r
- Header file for Registers and Structure definitions\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-#ifndef __OPAL_PASSWORD_NVME_REG_H__\r
-#define __OPAL_PASSWORD_NVME_REG_H__\r
-\r
-//\r
-// PCI Header for PCIe root port configuration\r
-//\r
-#define NVME_PCIE_PCICMD 0x04\r
-#define NVME_PCIE_BNUM 0x18\r
-#define NVME_PCIE_SEC_BNUM 0x19\r
-#define NVME_PCIE_IOBL 0x1C\r
-#define NVME_PCIE_MBL 0x20\r
-#define NVME_PCIE_PMBL 0x24\r
-#define NVME_PCIE_PMBU32 0x28\r
-#define NVME_PCIE_PMLU32 0x2C\r
-#define NVME_PCIE_INTR 0x3C\r
-\r
-//\r
-// NVMe related definitions\r
-//\r
-#define PCI_CLASS_MASS_STORAGE_NVM 0x08 // mass storage sub-class non-volatile memory.\r
-#define PCI_IF_NVMHCI 0x02 // mass storage programming interface NVMHCI.\r
-\r
-#define NVME_ASQ_SIZE 1 // Number of admin submission queue entries, which is 0-based\r
-#define NVME_ACQ_SIZE 1 // Number of admin completion queue entries, which is 0-based\r
-\r
-#define NVME_CSQ_SIZE 63 // Number of I/O submission queue entries, which is 0-based\r
-#define NVME_CCQ_SIZE 63 // Number of I/O completion queue entries, which is 0-based\r
-\r
-#define NVME_MAX_IO_QUEUES 2 // Number of I/O queues supported by the driver, 1 for AQ, 1 for CQ\r
-\r
-#define NVME_CSQ_DEPTH (NVME_CSQ_SIZE+1)\r
-#define NVME_CCQ_DEPTH (NVME_CCQ_SIZE+1)\r
-#define NVME_PRP_SIZE (4) // Pages of PRP list\r
-\r
-#define NVME_CONTROLLER_ID 0\r
-\r
-//\r
-// Time out Value for Nvme transaction execution\r
-//\r
-#define NVME_GENERIC_TIMEOUT 5000000 ///< us\r
-#define NVME_CMD_WAIT 100 ///< us\r
-#define NVME_CMD_TIMEOUT 20000000 ///< us\r
-\r
-\r
-\r
-#define NVME_MEM_MAX_SIZE \\r
- (( \\r
- 1 /* Controller Data */ + \\r
- 1 /* Identify Data */ + \\r
- 1 /* ASQ */ + \\r
- 1 /* ACQ */ + \\r
- 1 /* SQs */ + \\r
- 1 /* CQs */ + \\r
- NVME_PRP_SIZE * NVME_CSQ_DEPTH /* PRPs */ \\r
- ) * EFI_PAGE_SIZE)\r
-\r
-\r
-//\r
-// controller register offsets\r
-//\r
-#define NVME_CAP_OFFSET 0x0000 // Controller Capabilities\r
-#define NVME_VER_OFFSET 0x0008 // Version\r
-#define NVME_INTMS_OFFSET 0x000c // Interrupt Mask Set\r
-#define NVME_INTMC_OFFSET 0x0010 // Interrupt Mask Clear\r
-#define NVME_CC_OFFSET 0x0014 // Controller Configuration\r
-#define NVME_CSTS_OFFSET 0x001c // Controller Status\r
-#define NVME_AQA_OFFSET 0x0024 // Admin Queue Attributes\r
-#define NVME_ASQ_OFFSET 0x0028 // Admin Submission Queue Base Address\r
-#define NVME_ACQ_OFFSET 0x0030 // Admin Completion Queue Base Address\r
-#define NVME_SQ0_OFFSET 0x1000 // Submission Queue 0 (admin) Tail Doorbell\r
-#define NVME_CQ0_OFFSET 0x1004 // Completion Queue 0 (admin) Head Doorbell\r
-\r
-//\r
-// These register offsets are defined as 0x1000 + (N * (4 << CAP.DSTRD))\r
-// Get the doorbell stride bit shift Value from the controller capabilities.\r
-//\r
-#define NVME_SQTDBL_OFFSET(QID, DSTRD) 0x1000 + ((2 * (QID)) * (4 << (DSTRD))) // Submission Queue y (NVM) Tail Doorbell\r
-#define NVME_CQHDBL_OFFSET(QID, DSTRD) 0x1000 + (((2 * (QID)) + 1) * (4 << (DSTRD))) // Completion Queue y (NVM) Head Doorbell\r
-\r
-\r
-#pragma pack(1)\r
-\r
-//\r
-// 3.1.1 Offset 00h: CAP - Controller Capabilities\r
-//\r
-typedef struct {\r
- UINT16 Mqes; // Maximum Queue Entries Supported\r
- UINT8 Cqr:1; // Contiguous Queues Required\r
- UINT8 Ams:2; // Arbitration Mechanism Supported\r
- UINT8 Rsvd1:5;\r
- UINT8 To; // Timeout\r
- UINT16 Dstrd:4;\r
- UINT16 Rsvd2:1;\r
- UINT16 Css:4; // Command Sets Supported\r
- UINT16 Rsvd3:7;\r
- UINT8 Mpsmin:4;\r
- UINT8 Mpsmax:4;\r
- UINT8 Rsvd4;\r
-} NVME_CAP;\r
-\r
-//\r
-// 3.1.2 Offset 08h: VS - Version\r
-//\r
-typedef struct {\r
- UINT16 Mnr; // Minor version number\r
- UINT16 Mjr; // Major version number\r
-} NVME_VER;\r
-\r
-//\r
-// 3.1.5 Offset 14h: CC - Controller Configuration\r
-//\r
-typedef struct {\r
- UINT16 En:1; // Enable\r
- UINT16 Rsvd1:3;\r
- UINT16 Css:3; // Command Set Selected\r
- UINT16 Mps:4; // Memory Page Size\r
- UINT16 Ams:3; // Arbitration Mechanism Selected\r
- UINT16 Shn:2; // Shutdown Notification\r
- UINT8 Iosqes:4; // I/O Submission Queue Entry Size\r
- UINT8 Iocqes:4; // I/O Completion Queue Entry Size\r
- UINT8 Rsvd2;\r
-} NVME_CC;\r
-\r
-//\r
-// 3.1.6 Offset 1Ch: CSTS - Controller Status\r
-//\r
-typedef struct {\r
- UINT32 Rdy:1; // Ready\r
- UINT32 Cfs:1; // Controller Fatal Status\r
- UINT32 Shst:2; // Shutdown Status\r
- UINT32 Nssro:1; // NVM Subsystem Reset Occurred\r
- UINT32 Rsvd1:27;\r
-} NVME_CSTS;\r
-\r
-//\r
-// 3.1.8 Offset 24h: AQA - Admin Queue Attributes\r
-//\r
-typedef struct {\r
- UINT16 Asqs:12; // Submission Queue Size\r
- UINT16 Rsvd1:4;\r
- UINT16 Acqs:12; // Completion Queue Size\r
- UINT16 Rsvd2:4;\r
-} NVME_AQA;\r
-\r
-//\r
-// 3.1.9 Offset 28h: ASQ - Admin Submission Queue Base Address\r
-//\r
-#define NVME_ASQ UINT64\r
-\r
-//\r
-// 3.1.10 Offset 30h: ACQ - Admin Completion Queue Base Address\r
-//\r
-#define NVME_ACQ UINT64\r
-\r
-//\r
-// 3.1.11 Offset (1000h + ((2y) * (4 << CAP.DSTRD))): SQyTDBL - Submission Queue y Tail Doorbell\r
-//\r
-typedef struct {\r
- UINT16 Sqt;\r
- UINT16 Rsvd1;\r
-} NVME_SQTDBL;\r
-\r
-//\r
-// 3.1.12 Offset (1000h + ((2y + 1) * (4 << CAP.DSTRD))): CQyHDBL - Completion Queue y Head Doorbell\r
-//\r
-typedef struct {\r
- UINT16 Cqh;\r
- UINT16 Rsvd1;\r
-} NVME_CQHDBL;\r
-\r
-//\r
-// NVM command set structures\r
-//\r
-// Read Command\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10, 11\r
- //\r
- UINT64 Slba; /* Starting Sector Address */\r
- //\r
- // CDW 12\r
- //\r
- UINT16 Nlb; /* Number of Sectors */\r
- UINT16 Rsvd1:10;\r
- UINT16 Prinfo:4; /* Protection Info Check */\r
- UINT16 Fua:1; /* Force Unit Access */\r
- UINT16 Lr:1; /* Limited Retry */\r
- //\r
- // CDW 13\r
- //\r
- UINT32 Af:4; /* Access Frequency */\r
- UINT32 Al:2; /* Access Latency */\r
- UINT32 Sr:1; /* Sequential Request */\r
- UINT32 In:1; /* Incompressible */\r
- UINT32 Rsvd2:24;\r
- //\r
- // CDW 14\r
- //\r
- UINT32 Eilbrt; /* Expected Initial Logical Block Reference Tag */\r
- //\r
- // CDW 15\r
- //\r
- UINT16 Elbat; /* Expected Logical Block Application Tag */\r
- UINT16 Elbatm; /* Expected Logical Block Application Tag Mask */\r
-} NVME_READ;\r
-\r
-//\r
-// Write Command\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10, 11\r
- //\r
- UINT64 Slba; /* Starting Sector Address */\r
- //\r
- // CDW 12\r
- //\r
- UINT16 Nlb; /* Number of Sectors */\r
- UINT16 Rsvd1:10;\r
- UINT16 Prinfo:4; /* Protection Info Check */\r
- UINT16 Fua:1; /* Force Unit Access */\r
- UINT16 Lr:1; /* Limited Retry */\r
- //\r
- // CDW 13\r
- //\r
- UINT32 Af:4; /* Access Frequency */\r
- UINT32 Al:2; /* Access Latency */\r
- UINT32 Sr:1; /* Sequential Request */\r
- UINT32 In:1; /* Incompressible */\r
- UINT32 Rsvd2:24;\r
- //\r
- // CDW 14\r
- //\r
- UINT32 Ilbrt; /* Initial Logical Block Reference Tag */\r
- //\r
- // CDW 15\r
- //\r
- UINT16 Lbat; /* Logical Block Application Tag */\r
- UINT16 Lbatm; /* Logical Block Application Tag Mask */\r
-} NVME_WRITE;\r
-\r
-//\r
-// Flush\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10\r
- //\r
- UINT32 Flush; /* Flush */\r
-} NVME_FLUSH;\r
-\r
-//\r
-// Write Uncorrectable command\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10, 11\r
- //\r
- UINT64 Slba; /* Starting LBA */\r
- //\r
- // CDW 12\r
- //\r
- UINT32 Nlb:16; /* Number of Logical Blocks */\r
- UINT32 Rsvd1:16;\r
-} NVME_WRITE_UNCORRECTABLE;\r
-\r
-//\r
-// Write Zeroes command\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10, 11\r
- //\r
- UINT64 Slba; /* Starting LBA */\r
- //\r
- // CDW 12\r
- //\r
- UINT16 Nlb; /* Number of Logical Blocks */\r
- UINT16 Rsvd1:10;\r
- UINT16 Prinfo:4; /* Protection Info Check */\r
- UINT16 Fua:1; /* Force Unit Access */\r
- UINT16 Lr:1; /* Limited Retry */\r
- //\r
- // CDW 13\r
- //\r
- UINT32 Rsvd2;\r
- //\r
- // CDW 14\r
- //\r
- UINT32 Ilbrt; /* Initial Logical Block Reference Tag */\r
- //\r
- // CDW 15\r
- //\r
- UINT16 Lbat; /* Logical Block Application Tag */\r
- UINT16 Lbatm; /* Logical Block Application Tag Mask */\r
-} NVME_WRITE_ZEROES;\r
-\r
-//\r
-// Compare command\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10, 11\r
- //\r
- UINT64 Slba; /* Starting LBA */\r
- //\r
- // CDW 12\r
- //\r
- UINT16 Nlb; /* Number of Logical Blocks */\r
- UINT16 Rsvd1:10;\r
- UINT16 Prinfo:4; /* Protection Info Check */\r
- UINT16 Fua:1; /* Force Unit Access */\r
- UINT16 Lr:1; /* Limited Retry */\r
- //\r
- // CDW 13\r
- //\r
- UINT32 Rsvd2;\r
- //\r
- // CDW 14\r
- //\r
- UINT32 Eilbrt; /* Expected Initial Logical Block Reference Tag */\r
- //\r
- // CDW 15\r
- //\r
- UINT16 Elbat; /* Expected Logical Block Application Tag */\r
- UINT16 Elbatm; /* Expected Logical Block Application Tag Mask */\r
-} NVME_COMPARE;\r
-\r
-typedef union {\r
- NVME_READ Read;\r
- NVME_WRITE Write;\r
- NVME_FLUSH Flush;\r
- NVME_WRITE_UNCORRECTABLE WriteUncorrectable;\r
- NVME_WRITE_ZEROES WriteZeros;\r
- NVME_COMPARE Compare;\r
-} NVME_CMD;\r
-\r
-typedef struct {\r
- UINT16 Mp; /* Maximum Power */\r
- UINT8 Rsvd1; /* Reserved as of Nvm Express 1.1 Spec */\r
- UINT8 Mps:1; /* Max Power Scale */\r
- UINT8 Nops:1; /* Non-Operational State */\r
- UINT8 Rsvd2:6; /* Reserved as of Nvm Express 1.1 Spec */\r
- UINT32 Enlat; /* Entry Latency */\r
- UINT32 Exlat; /* Exit Latency */\r
- UINT8 Rrt:5; /* Relative Read Throughput */\r
- UINT8 Rsvd3:3; /* Reserved as of Nvm Express 1.1 Spec */\r
- UINT8 Rrl:5; /* Relative Read Leatency */\r
- UINT8 Rsvd4:3; /* Reserved as of Nvm Express 1.1 Spec */\r
- UINT8 Rwt:5; /* Relative Write Throughput */\r
- UINT8 Rsvd5:3; /* Reserved as of Nvm Express 1.1 Spec */\r
- UINT8 Rwl:5; /* Relative Write Leatency */\r
- UINT8 Rsvd6:3; /* Reserved as of Nvm Express 1.1 Spec */\r
- UINT8 Rsvd7[16]; /* Reserved as of Nvm Express 1.1 Spec */\r
-} NVME_PSDESCRIPTOR;\r
-\r
-//\r
-// Identify Controller Data\r
-//\r
-typedef struct {\r
- //\r
- // Controller Capabilities and Features 0-255\r
- //\r
- UINT16 Vid; /* PCI Vendor ID */\r
- UINT16 Ssvid; /* PCI sub-system vendor ID */\r
- UINT8 Sn[20]; /* Produce serial number */\r
-\r
- UINT8 Mn[40]; /* Proeduct model number */\r
- UINT8 Fr[8]; /* Firmware Revision */\r
- UINT8 Rab; /* Recommended Arbitration Burst */\r
- UINT8 Ieee_oiu[3]; /* Organization Unique Identifier */\r
- UINT8 Cmic; /* Multi-interface Capabilities */\r
- UINT8 Mdts; /* Maximum Data Transfer Size */\r
- UINT8 Cntlid[2]; /* Controller ID */\r
- UINT8 Rsvd1[176]; /* Reserved as of Nvm Express 1.1 Spec */\r
- //\r
- // Admin Command Set Attributes\r
- //\r
- UINT16 Oacs; /* Optional Admin Command Support */\r
- UINT8 Acl; /* Abort Command Limit */\r
- UINT8 Aerl; /* Async Event Request Limit */\r
- UINT8 Frmw; /* Firmware updates */\r
- UINT8 Lpa; /* Log Page Attributes */\r
- UINT8 Elpe; /* Error Log Page Entries */\r
- UINT8 Npss; /* Number of Power States Support */\r
- UINT8 Avscc; /* Admin Vendor Specific Command Configuration */\r
- UINT8 Apsta; /* Autonomous Power State Transition Attributes */\r
- UINT8 Rsvd2[246]; /* Reserved as of Nvm Express 1.1 Spec */\r
- //\r
- // NVM Command Set Attributes\r
- //\r
- UINT8 Sqes; /* Submission Queue Entry Size */\r
- UINT8 Cqes; /* Completion Queue Entry Size */\r
- UINT16 Rsvd3; /* Reserved as of Nvm Express 1.1 Spec */\r
- UINT32 Nn; /* Number of Namespaces */\r
- UINT16 Oncs; /* Optional NVM Command Support */\r
- UINT16 Fuses; /* Fused Operation Support */\r
- UINT8 Fna; /* Format NVM Attributes */\r
- UINT8 Vwc; /* Volatile Write Cache */\r
- UINT16 Awun; /* Atomic Write Unit Normal */\r
- UINT16 Awupf; /* Atomic Write Unit Power Fail */\r
- UINT8 Nvscc; /* NVM Vendor Specific Command Configuration */\r
- UINT8 Rsvd4; /* Reserved as of Nvm Express 1.1 Spec */\r
- UINT16 Acwu; /* Atomic Compare & Write Unit */\r
- UINT16 Rsvd5; /* Reserved as of Nvm Express 1.1 Spec */\r
- UINT32 Sgls; /* SGL Support */\r
- UINT8 Rsvd6[164]; /* Reserved as of Nvm Express 1.1 Spec */\r
- //\r
- // I/O Command set Attributes\r
- //\r
- UINT8 Rsvd7[1344]; /* Reserved as of Nvm Express 1.1 Spec */\r
- //\r
- // Power State Descriptors\r
- //\r
- NVME_PSDESCRIPTOR PsDescriptor[32];\r
-\r
- UINT8 VendorData[1024]; /* Vendor specific Data */\r
-} NVME_ADMIN_CONTROLLER_DATA;\r
-\r
-typedef struct {\r
- UINT16 Security : 1; /* supports security send/receive commands */\r
- UINT16 Format : 1; /* supports format nvm command */\r
- UINT16 Firmware : 1; /* supports firmware activate/download commands */\r
- UINT16 Oacs_rsvd : 13;\r
- } OACS; // optional admin command support: NVME_ADMIN_CONTROLLER_DATA.Oacs\r
-\r
-typedef struct {\r
- UINT16 Ms; /* Metadata Size */\r
- UINT8 Lbads; /* LBA Data Size */\r
- UINT8 Rp:2; /* Relative Performance */\r
- #define LBAF_RP_BEST 00b\r
- #define LBAF_RP_BETTER 01b\r
- #define LBAF_RP_GOOD 10b\r
- #define LBAF_RP_DEGRADED 11b\r
- UINT8 Rsvd1:6; /* Reserved as of Nvm Express 1.1 Spec */\r
-} NVME_LBAFORMAT;\r
-\r
-//\r
-// Identify Namespace Data\r
-//\r
-typedef struct {\r
- //\r
- // NVM Command Set Specific\r
- //\r
- UINT64 Nsze; /* Namespace Size (total number of blocks in formatted namespace) */\r
- UINT64 Ncap; /* Namespace Capacity (max number of logical blocks) */\r
- UINT64 Nuse; /* Namespace Utilization */\r
- UINT8 Nsfeat; /* Namespace Features */\r
- UINT8 Nlbaf; /* Number of LBA Formats */\r
- UINT8 Flbas; /* Formatted LBA Size */\r
- UINT8 Mc; /* Metadata Capabilities */\r
- UINT8 Dpc; /* End-to-end Data Protection capabilities */\r
- UINT8 Dps; /* End-to-end Data Protection Type Settings */\r
- UINT8 Nmic; /* Namespace Multi-path I/O and Namespace Sharing Capabilities */\r
- UINT8 Rescap; /* Reservation Capabilities */\r
- UINT8 Rsvd1[88]; /* Reserved as of Nvm Express 1.1 Spec */\r
- UINT64 Eui64; /* IEEE Extended Unique Identifier */\r
- //\r
- // LBA Format\r
- //\r
- NVME_LBAFORMAT LbaFormat[16];\r
-\r
- UINT8 Rsvd2[192]; /* Reserved as of Nvm Express 1.1 Spec */\r
- UINT8 VendorData[3712]; /* Vendor specific Data */\r
-} NVME_ADMIN_NAMESPACE_DATA;\r
-\r
-//\r
-// NvmExpress Admin Identify Cmd\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10\r
- //\r
- UINT32 Cns:2;\r
- UINT32 Rsvd1:30;\r
-} NVME_ADMIN_IDENTIFY;\r
-\r
-//\r
-// NvmExpress Admin Create I/O Completion Queue\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10\r
- //\r
- UINT32 Qid:16; /* Queue Identifier */\r
- UINT32 Qsize:16; /* Queue Size */\r
-\r
- //\r
- // CDW 11\r
- //\r
- UINT32 Pc:1; /* Physically Contiguous */\r
- UINT32 Ien:1; /* Interrupts Enabled */\r
- UINT32 Rsvd1:14; /* reserved as of Nvm Express 1.1 Spec */\r
- UINT32 Iv:16; /* Interrupt Vector */\r
-} NVME_ADMIN_CRIOCQ;\r
-\r
-//\r
-// NvmExpress Admin Create I/O Submission Queue\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10\r
- //\r
- UINT32 Qid:16; /* Queue Identifier */\r
- UINT32 Qsize:16; /* Queue Size */\r
-\r
- //\r
- // CDW 11\r
- //\r
- UINT32 Pc:1; /* Physically Contiguous */\r
- UINT32 Qprio:2; /* Queue Priority */\r
- UINT32 Rsvd1:13; /* Reserved as of Nvm Express 1.1 Spec */\r
- UINT32 Cqid:16; /* Completion Queue ID */\r
-} NVME_ADMIN_CRIOSQ;\r
-\r
-//\r
-// NvmExpress Admin Delete I/O Completion Queue\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10\r
- //\r
- UINT16 Qid;\r
- UINT16 Rsvd1;\r
-} NVME_ADMIN_DEIOCQ;\r
-\r
-//\r
-// NvmExpress Admin Delete I/O Submission Queue\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10\r
- //\r
- UINT16 Qid;\r
- UINT16 Rsvd1;\r
-} NVME_ADMIN_DEIOSQ;\r
-\r
-//\r
-// NvmExpress Admin Security Send\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10\r
- //\r
- UINT32 Resv:8; /* Reserve */\r
- UINT32 Spsp:16; /* SP Specific */\r
- UINT32 Secp:8; /* Security Protocol */\r
-\r
- //\r
- // CDW 11\r
- //\r
- UINT32 Tl; /* Transfer Length */\r
-} NVME_ADMIN_SECSEND;\r
-\r
-//\r
-// NvmExpress Admin Abort Command\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10\r
- //\r
- UINT32 Sqid:16; /* Submission Queue identifier */\r
- UINT32 Cid:16; /* Command Identifier */\r
-} NVME_ADMIN_ABORT;\r
-\r
-//\r
-// NvmExpress Admin Firmware Activate Command\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10\r
- //\r
- UINT32 Fs:3; /* Submission Queue identifier */\r
- UINT32 Aa:2; /* Command Identifier */\r
- UINT32 Rsvd1:27;\r
-} NVME_ADMIN_FIRMWARE_ACTIVATE;\r
-\r
-//\r
-// NvmExpress Admin Firmware Image Download Command\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10\r
- //\r
- UINT32 Numd; /* Number of Dwords */\r
- //\r
- // CDW 11\r
- //\r
- UINT32 Ofst; /* Offset */\r
-} NVME_ADMIN_FIRMWARE_IMAGE_DOWNLOAD;\r
-\r
-//\r
-// NvmExpress Admin Get Features Command\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10\r
- //\r
- UINT32 Fid:8; /* Feature Identifier */\r
- UINT32 Sel:3; /* Select */\r
- UINT32 Rsvd1:21;\r
-} NVME_ADMIN_GET_FEATURES;\r
-\r
-//\r
-// NvmExpress Admin Get Log Page Command\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10\r
- //\r
- UINT32 Lid:8; /* Log Page Identifier */\r
- #define LID_ERROR_INFO\r
- #define LID_SMART_INFO\r
- #define LID_FW_SLOT_INFO\r
- UINT32 Rsvd1:8;\r
- UINT32 Numd:12; /* Number of Dwords */\r
- UINT32 Rsvd2:4; /* Reserved as of Nvm Express 1.1 Spec */\r
-} NVME_ADMIN_GET_LOG_PAGE;\r
-\r
-//\r
-// NvmExpress Admin Set Features Command\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10\r
- //\r
- UINT32 Fid:8; /* Feature Identifier */\r
- UINT32 Rsvd1:23;\r
- UINT32 Sv:1; /* Save */\r
-} NVME_ADMIN_SET_FEATURES;\r
-\r
-//\r
-// NvmExpress Admin Format NVM Command\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10\r
- //\r
- UINT32 Lbaf:4; /* LBA Format */\r
- UINT32 Ms:1; /* Metadata Settings */\r
- UINT32 Pi:3; /* Protection Information */\r
- UINT32 Pil:1; /* Protection Information Location */\r
- UINT32 Ses:3; /* Secure Erase Settings */\r
- UINT32 Rsvd1:20;\r
-} NVME_ADMIN_FORMAT_NVM;\r
-\r
-//\r
-// NvmExpress Admin Security Receive Command\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10\r
- //\r
- UINT32 Rsvd1:8;\r
- UINT32 Spsp:16; /* SP Specific */\r
- UINT32 Secp:8; /* Security Protocol */\r
- //\r
- // CDW 11\r
- //\r
- UINT32 Al; /* Allocation Length */\r
-} NVME_ADMIN_SECURITY_RECEIVE;\r
-\r
-//\r
-// NvmExpress Admin Security Send Command\r
-//\r
-typedef struct {\r
- //\r
- // CDW 10\r
- //\r
- UINT32 Rsvd1:8;\r
- UINT32 Spsp:16; /* SP Specific */\r
- UINT32 Secp:8; /* Security Protocol */\r
- //\r
- // CDW 11\r
- //\r
- UINT32 Tl; /* Transfer Length */\r
-} NVME_ADMIN_SECURITY_SEND;\r
-\r
-typedef union {\r
- NVME_ADMIN_IDENTIFY Identify;\r
- NVME_ADMIN_CRIOCQ CrIoCq;\r
- NVME_ADMIN_CRIOSQ CrIoSq;\r
- NVME_ADMIN_DEIOCQ DeIoCq;\r
- NVME_ADMIN_DEIOSQ DeIoSq;\r
- NVME_ADMIN_ABORT Abort;\r
- NVME_ADMIN_FIRMWARE_ACTIVATE Activate;\r
- NVME_ADMIN_FIRMWARE_IMAGE_DOWNLOAD FirmwareImageDownload;\r
- NVME_ADMIN_GET_FEATURES GetFeatures;\r
- NVME_ADMIN_GET_LOG_PAGE GetLogPage;\r
- NVME_ADMIN_SET_FEATURES SetFeatures;\r
- NVME_ADMIN_FORMAT_NVM FormatNvm;\r
- NVME_ADMIN_SECURITY_RECEIVE SecurityReceive;\r
- NVME_ADMIN_SECURITY_SEND SecuritySend;\r
-} NVME_ADMIN_CMD;\r
-\r
-typedef struct {\r
- UINT32 Cdw10;\r
- UINT32 Cdw11;\r
- UINT32 Cdw12;\r
- UINT32 Cdw13;\r
- UINT32 Cdw14;\r
- UINT32 Cdw15;\r
-} NVME_RAW;\r
-\r
-typedef union {\r
- NVME_ADMIN_CMD Admin; // Union of Admin commands\r
- NVME_CMD Nvm; // Union of Nvm commands\r
- NVME_RAW Raw;\r
-} NVME_PAYLOAD;\r
-\r
-//\r
-// Submission Queue\r
-//\r
-typedef struct {\r
- //\r
- // CDW 0, Common to all comnmands\r
- //\r
- UINT8 Opc; // Opcode\r
- UINT8 Fuse:2; // Fused Operation\r
- UINT8 Rsvd1:5;\r
- UINT8 Psdt:1; // PRP or SGL for Data Transfer\r
- UINT16 Cid; // Command Identifier\r
-\r
- //\r
- // CDW 1\r
- //\r
- UINT32 Nsid; // Namespace Identifier\r
-\r
- //\r
- // CDW 2,3\r
- //\r
- UINT64 Rsvd2;\r
-\r
- //\r
- // CDW 4,5\r
- //\r
- UINT64 Mptr; // Metadata Pointer\r
-\r
- //\r
- // CDW 6-9\r
- //\r
- UINT64 Prp[2]; // First and second PRP entries\r
-\r
- NVME_PAYLOAD Payload;\r
-\r
-} NVME_SQ;\r
-\r
-//\r
-// Completion Queue\r
-//\r
-typedef struct {\r
- //\r
- // CDW 0\r
- //\r
- UINT32 Dword0;\r
- //\r
- // CDW 1\r
- //\r
- UINT32 Rsvd1;\r
- //\r
- // CDW 2\r
- //\r
- UINT16 Sqhd; // Submission Queue Head Pointer\r
- UINT16 Sqid; // Submission Queue Identifier\r
- //\r
- // CDW 3\r
- //\r
- UINT16 Cid; // Command Identifier\r
- UINT16 Pt:1; // Phase Tag\r
- UINT16 Sc:8; // Status Code\r
- UINT16 Sct:3; // Status Code Type\r
- UINT16 Rsvd2:2;\r
- UINT16 Mo:1; // More\r
- UINT16 Dnr:1; // Retry\r
-} NVME_CQ;\r
-\r
-//\r
-// Nvm Express Admin cmd opcodes\r
-//\r
-#define NVME_ADMIN_DELIOSQ_OPC 0\r
-#define NVME_ADMIN_CRIOSQ_OPC 1\r
-#define NVME_ADMIN_DELIOCQ_OPC 4\r
-#define NVME_ADMIN_CRIOCQ_OPC 5\r
-#define NVME_ADMIN_IDENTIFY_OPC 6\r
-#define NVME_ADMIN_SECURITY_SEND_OPC 0x81\r
-#define NVME_ADMIN_SECURITY_RECV_OPC 0x82\r
-\r
-#define NVME_IO_FLUSH_OPC 0\r
-#define NVME_IO_WRITE_OPC 1\r
-#define NVME_IO_READ_OPC 2\r
-\r
-//\r
-// Offset from the beginning of private Data queue Buffer\r
-//\r
-#define NVME_ASQ_BUF_OFFSET EFI_PAGE_SIZE\r
-\r
-#pragma pack()\r
-\r
-#endif\r
-\r
+++ /dev/null
-/** @file\r
- Opal password smm driver which is used to support Opal security feature at s3 path.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "OpalPasswordSmm.h"\r
-\r
-#define SMM_SIZE_ALLOC_BYTES (512)\r
-#define RESPONSE_SIZE (200)\r
-\r
-#define PCI_CLASS_MASS_STORAGE_AHCI (0x06)\r
-\r
-#define OPAL_PCIE_ROOTPORT_SAVESIZE (0x40)\r
-#define STORE_INVALID_ROOTPORT_INDEX ((UINT8) -1)\r
-#define OPAL_DEVICE_TYPE_SATA 0x1\r
-#define OPAL_DEVICE_TYPE_NVME 0x2\r
-#define OPAL_DEVICE_TYPE_UNKNOWN 0xFF\r
-\r
-//\r
-// To unlock the Intel SATA controller at S3 Resume, restored the following registers.\r
-//\r
-const OPAL_HC_PCI_REGISTER_SAVE mSataHcRegisterSaveTemplate[] = {\r
- {0x9, S3BootScriptWidthUint8},\r
- {0x10, S3BootScriptWidthUint32},\r
- {0x14, S3BootScriptWidthUint32},\r
- {0x18, S3BootScriptWidthUint32},\r
- {0x1C, S3BootScriptWidthUint32},\r
- {0x20, S3BootScriptWidthUint32},\r
- {0x24, S3BootScriptWidthUint32},\r
- {0x3c, S3BootScriptWidthUint8},\r
- {0x3d, S3BootScriptWidthUint8},\r
- {0x40, S3BootScriptWidthUint16},\r
- {0x42, S3BootScriptWidthUint16},\r
- {0x92, S3BootScriptWidthUint16},\r
- {0x94, S3BootScriptWidthUint32},\r
- {0x9C, S3BootScriptWidthUint32},\r
- {0x4, S3BootScriptWidthUint16},\r
-};\r
-\r
-\r
-UINT8 mSwSmiValue;\r
-LIST_ENTRY *mOpalDeviceList;\r
-LIST_ENTRY mSmmDeviceList = INITIALIZE_LIST_HEAD_VARIABLE (mSmmDeviceList);\r
-\r
-BOOLEAN mSendBlockSID = FALSE;\r
-\r
-// AHCI\r
-UINT32 mAhciBar = 0;\r
-EFI_AHCI_REGISTERS mAhciRegisters;\r
-VOID *mBuffer = NULL; // DMA can not read/write Data to smram, so we pre-allocates Buffer from AcpiNVS.\r
-//\r
-// NVME\r
-NVME_CONTEXT mNvmeContext;\r
-\r
-/**\r
- Add new bridge node or nvme device info to the device list.\r
-\r
- @param[in] BusNum The bus number.\r
- @param[in] DevNum The device number.\r
- @param[in] FuncNum The function number.\r
- @param[in] Dev The device which need to add device node info.\r
-\r
-**/\r
-VOID\r
-AddPciDeviceNode (\r
- UINT32 BusNum,\r
- UINT32 DevNum,\r
- UINT32 FuncNum,\r
- OPAL_SMM_DEVICE *Dev\r
- )\r
-{\r
- UINT8 *DevList;\r
- PCI_DEVICE *DeviceNode;\r
-\r
- DevList = AllocateZeroPool (sizeof (PCI_DEVICE) + Dev->Length);\r
- ASSERT (DevList != NULL);\r
-\r
- if (Dev->Length != 0) {\r
- CopyMem (DevList, Dev->PciBridgeNode, Dev->Length);\r
- FreePool (Dev->PciBridgeNode);\r
- }\r
-\r
- DeviceNode = (PCI_DEVICE *) (DevList + Dev->Length);\r
-\r
- DeviceNode->BusNum = BusNum;\r
- DeviceNode->DevNum = DevNum;\r
- DeviceNode->FuncNum = FuncNum;\r
-\r
- Dev->Length += sizeof (PCI_DEVICE);\r
- Dev->PciBridgeNode = (PCI_DEVICE *)DevList;\r
-}\r
-\r
-/**\r
- Extract device info from the input device path.\r
-\r
- @param[in] DevicePath Device path info for the device.\r
- @param[in,out] Dev The device which new inputed.\r
-\r
-**/\r
-VOID\r
-ExtractDeviceInfoFromDevicePath (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
- IN OUT OPAL_SMM_DEVICE *Dev\r
- )\r
-{\r
- EFI_DEVICE_PATH_PROTOCOL *TmpDevPath;\r
- EFI_DEVICE_PATH_PROTOCOL *TmpDevPath2;\r
- PCI_DEVICE_PATH *PciDevPath;\r
- SATA_DEVICE_PATH *SataDevPath;\r
- NVME_NAMESPACE_DEVICE_PATH *NvmeDevPath;\r
- UINTN BusNum;\r
-\r
- TmpDevPath = DevicePath;\r
- Dev->DeviceType = OPAL_DEVICE_TYPE_UNKNOWN;\r
-\r
- while (!IsDevicePathEnd(TmpDevPath)) {\r
- if (TmpDevPath->Type == MESSAGING_DEVICE_PATH && TmpDevPath->SubType == MSG_SATA_DP) {\r
- //\r
- // SATA\r
- //\r
- SataDevPath = ( SATA_DEVICE_PATH* )TmpDevPath;\r
- Dev->SataPort = SataDevPath->HBAPortNumber;\r
- Dev->SataPortMultiplierPort = SataDevPath->PortMultiplierPortNumber;\r
- Dev->DeviceType = OPAL_DEVICE_TYPE_SATA;\r
- break;\r
- } else if (TmpDevPath->Type == MESSAGING_DEVICE_PATH && TmpDevPath->SubType == MSG_NVME_NAMESPACE_DP) {\r
- //\r
- // NVMe\r
- //\r
- NvmeDevPath = ( NVME_NAMESPACE_DEVICE_PATH* )TmpDevPath;\r
- Dev->NvmeNamespaceId = NvmeDevPath->NamespaceId;\r
- Dev->DeviceType = OPAL_DEVICE_TYPE_NVME;\r
- break;\r
- }\r
- TmpDevPath = NextDevicePathNode (TmpDevPath);\r
- }\r
-\r
- //\r
- // Get bridge node info for the nvme device.\r
- //\r
- BusNum = 0;\r
- TmpDevPath = DevicePath;\r
- TmpDevPath2 = NextDevicePathNode (DevicePath);\r
- while (!IsDevicePathEnd(TmpDevPath2)) {\r
- if (TmpDevPath->Type == HARDWARE_DEVICE_PATH && TmpDevPath->SubType == HW_PCI_DP) {\r
- PciDevPath = (PCI_DEVICE_PATH *) TmpDevPath;\r
- if ((TmpDevPath2->Type == MESSAGING_DEVICE_PATH && TmpDevPath2->SubType == MSG_NVME_NAMESPACE_DP)||\r
- (TmpDevPath2->Type == MESSAGING_DEVICE_PATH && TmpDevPath2->SubType == MSG_SATA_DP)) {\r
- Dev->BusNum = (UINT32)BusNum;\r
- Dev->DevNum = PciDevPath->Device;\r
- Dev->FuncNum = PciDevPath->Function;\r
- } else {\r
- AddPciDeviceNode((UINT32)BusNum, PciDevPath->Device, PciDevPath->Function, Dev);\r
- if (TmpDevPath2->Type == HARDWARE_DEVICE_PATH && TmpDevPath2->SubType == HW_PCI_DP) {\r
- BusNum = PciRead8 (PCI_LIB_ADDRESS (BusNum, PciDevPath->Device, PciDevPath->Function, NVME_PCIE_SEC_BNUM));\r
- }\r
- }\r
- }\r
-\r
- TmpDevPath = NextDevicePathNode (TmpDevPath);\r
- TmpDevPath2 = NextDevicePathNode (TmpDevPath2);\r
- }\r
-}\r
-\r
-/**\r
-\r
- The function returns whether or not the device is Opal Locked.\r
- TRUE means that the device is partially or fully locked.\r
- This will perform a Level 0 Discovery and parse the locking feature descriptor\r
-\r
- @param[in] OpalDev Opal object to determine if locked\r
- @param[out] BlockSidSupported Whether device support BlockSid feature.\r
-\r
-**/\r
-BOOLEAN\r
-IsOpalDeviceLocked(\r
- OPAL_SMM_DEVICE *OpalDev,\r
- BOOLEAN *BlockSidSupported\r
- )\r
-{\r
- OPAL_SESSION Session;\r
- OPAL_DISK_SUPPORT_ATTRIBUTE SupportedAttributes;\r
- TCG_LOCKING_FEATURE_DESCRIPTOR LockingFeature;\r
- UINT16 OpalBaseComId;\r
- TCG_RESULT Ret;\r
-\r
- Session.Sscp = &OpalDev->Sscp;\r
- Session.MediaId = 0;\r
-\r
- Ret = OpalGetSupportedAttributesInfo (&Session, &SupportedAttributes, &OpalBaseComId);\r
- if (Ret != TcgResultSuccess) {\r
- return FALSE;\r
- }\r
-\r
- OpalDev->OpalBaseComId = OpalBaseComId;\r
- Session.OpalBaseComId = OpalBaseComId;\r
- *BlockSidSupported = SupportedAttributes.BlockSid == 1 ? TRUE : FALSE;\r
-\r
- Ret = OpalGetLockingInfo(&Session, &LockingFeature);\r
- if (Ret != TcgResultSuccess) {\r
- return FALSE;\r
- }\r
-\r
- return OpalDeviceLocked (&SupportedAttributes, &LockingFeature);\r
-}\r
-\r
-/**\r
- Save/Restore RootPort configuration space.\r
-\r
- @param[in] DeviceNode - The device node.\r
- @param[in] SaveAction - TRUE: Save, FALSE: Restore\r
- @param[in,out] PcieConfBufferList - Configuration space data buffer for save/restore\r
-\r
- @retval - PCIE base address of this RootPort\r
-**/\r
-UINTN\r
-SaveRestoreRootportConfSpace (\r
- IN OPAL_SMM_DEVICE *DeviceNode,\r
- IN BOOLEAN SaveAction,\r
- IN OUT UINT8 **PcieConfBufferList\r
- )\r
-{\r
- UINTN RpBase;\r
- UINTN Length;\r
- PCI_DEVICE *DevNode;\r
- UINT8 *StorePcieConfData;\r
- UINTN Index;\r
-\r
- Length = 0;\r
- Index = 0;\r
- RpBase = 0;\r
-\r
- while (Length < DeviceNode->Length) {\r
- DevNode = (PCI_DEVICE *)((UINT8*)DeviceNode->PciBridgeNode + Length);\r
- RpBase = PCI_LIB_ADDRESS (DevNode->BusNum, DevNode->DevNum, DevNode->FuncNum, 0x0);\r
-\r
- if (PcieConfBufferList != NULL) {\r
- if (SaveAction) {\r
- StorePcieConfData = (UINT8 *) AllocateZeroPool (OPAL_PCIE_ROOTPORT_SAVESIZE);\r
- ASSERT (StorePcieConfData != NULL);\r
- OpalPciRead (StorePcieConfData, RpBase, OPAL_PCIE_ROOTPORT_SAVESIZE);\r
- PcieConfBufferList[Index] = StorePcieConfData;\r
- } else {\r
- // Skip PCIe Command & Status registers\r
- StorePcieConfData = PcieConfBufferList[Index];\r
- OpalPciWrite (RpBase, StorePcieConfData, 4);\r
- OpalPciWrite (RpBase + 8, StorePcieConfData + 8, OPAL_PCIE_ROOTPORT_SAVESIZE - 8);\r
-\r
- FreePool (StorePcieConfData);\r
- }\r
- }\r
-\r
- Length += sizeof (PCI_DEVICE);\r
- Index ++;\r
- }\r
-\r
- return RpBase;\r
-}\r
-\r
-/**\r
- Configure RootPort for downstream PCIe NAND devices.\r
-\r
- @param[in] RpBase - PCIe configuration space address of this RootPort\r
- @param[in] BusNumber - Bus number\r
- @param[in] MemoryBase - Memory base address\r
- @param[in] MemoryLength - Memory size\r
-\r
-**/\r
-VOID\r
-ConfigureRootPortForPcieNand (\r
- IN UINTN RpBase,\r
- IN UINTN BusNumber,\r
- IN UINT32 MemoryBase,\r
- IN UINT32 MemoryLength\r
- )\r
-{\r
- UINT32 MemoryLimit;\r
-\r
- DEBUG ((DEBUG_INFO, "ConfigureRootPortForPcieNand, BusNumber: %x, MemoryBase: %x, MemoryLength: %x\n",\r
- BusNumber, MemoryBase, MemoryLength));\r
-\r
- if (MemoryLength == 0) {\r
- MemoryLimit = MemoryBase;\r
- } else {\r
- MemoryLimit = MemoryBase + MemoryLength + 0xFFFFF; // 1M\r
- }\r
-\r
- ///\r
- /// Configue PCIE configuration space for RootPort\r
- ///\r
- PciWrite8 (RpBase + NVME_PCIE_BNUM + 1, (UINT8) BusNumber); // Secondary Bus Number registers\r
- PciWrite8 (RpBase + NVME_PCIE_BNUM + 2, (UINT8) BusNumber); // Subordinate Bus Number registers\r
- PciWrite8 (RpBase + NVME_PCIE_IOBL, 0xFF); // I/O Base registers\r
- PciWrite8 (RpBase + NVME_PCIE_IOBL + 1, 0x00); // I/O Limit registers\r
- PciWrite16 (RpBase + NVME_PCIE_MBL, (UINT16) RShiftU64 ((UINTN)MemoryBase, 16)); // Memory Base register\r
- PciWrite16 (RpBase + NVME_PCIE_MBL + 2, (UINT16) RShiftU64 ((UINTN)MemoryLimit, 16)); // Memory Limit register\r
- PciWrite16 (RpBase + NVME_PCIE_PMBL, 0xFFFF); // Prefetchable Memory Base registers\r
- PciWrite16 (RpBase + NVME_PCIE_PMBL + 2, 0x0000); // Prefetchable Memory Limit registers\r
- PciWrite32 (RpBase + NVME_PCIE_PMBU32, 0xFFFFFFFF); // Prefetchable Memory Upper Base registers\r
- PciWrite32 (RpBase + NVME_PCIE_PMLU32, 0x00000000); // Prefetchable Memory Upper Limit registers\r
-}\r
-\r
-\r
-/**\r
- Dispatch function for a Software SMI handler.\r
-\r
- @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
- @param[in] RegisterContext Points to an optional handler context which was specified when the\r
- handler was registered.\r
- @param[in, out] CommBuffer A pointer to a collection of Data in memory that will\r
- be conveyed from a non-SMM environment into an SMM environment.\r
- @param[in, out] CommBufferSize The Size of the CommBuffer.\r
-\r
- @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers\r
- should still be called.\r
- @retval Others Other execution results.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SmmUnlockOpalPassword (\r
- IN EFI_HANDLE DispatchHandle,\r
- IN CONST VOID *RegisterContext,\r
- IN OUT VOID *CommBuffer,\r
- IN OUT UINTN *CommBufferSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
- OPAL_SMM_DEVICE *OpalDev;\r
- LIST_ENTRY *Entry;\r
- UINT8 BaseClassCode;\r
- UINT8 SubClassCode;\r
- UINT8 ProgInt;\r
- TCG_RESULT Result;\r
- UINT8 SataCmdSt;\r
- UINT8 *StorePcieConfDataList[16];\r
- UINTN RpBase;\r
- UINTN MemoryBase;\r
- UINTN MemoryLength;\r
- OPAL_SESSION Session;\r
- BOOLEAN BlockSidSupport;\r
-\r
- ZeroMem (StorePcieConfDataList, sizeof (StorePcieConfDataList));\r
- Status = EFI_DEVICE_ERROR;\r
-\r
- //\r
- // try to unlock all locked hdd disks.\r
- //\r
- for (Entry = mSmmDeviceList.ForwardLink; Entry != &mSmmDeviceList; Entry = Entry->ForwardLink) {\r
- OpalDev = BASE_CR(Entry, OPAL_SMM_DEVICE, Link);\r
-\r
- RpBase = 0;\r
- SataCmdSt = 0;\r
-\r
- ///\r
- /// Configure RootPort for PCIe AHCI/NVME devices.\r
- ///\r
- if (OpalDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
- ///\r
- /// Save original RootPort configuration space to heap\r
- ///\r
- RpBase = SaveRestoreRootportConfSpace (\r
- OpalDev,\r
- TRUE,\r
- StorePcieConfDataList\r
- );\r
- MemoryBase = mNvmeContext.Nbar;\r
- MemoryLength = 0;\r
- ConfigureRootPortForPcieNand (RpBase, OpalDev->BusNum, (UINT32) MemoryBase, (UINT32) MemoryLength);\r
-\r
- ///\r
- /// Enable PCIE decode for RootPort\r
- ///\r
- SataCmdSt = PciRead8 (RpBase + NVME_PCIE_PCICMD);\r
- PciWrite8 (RpBase + NVME_PCIE_PCICMD, 0x6);\r
- } else {\r
- SataCmdSt = PciRead8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, NVME_PCIE_PCICMD));\r
- PciWrite8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, NVME_PCIE_PCICMD), 0x6);\r
- }\r
-\r
- BaseClassCode = PciRead8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, 0x0B));\r
- SubClassCode = PciRead8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, 0x0A));\r
- ProgInt = PciRead8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, 0x09));\r
- if (BaseClassCode != PCI_CLASS_MASS_STORAGE) {\r
- Status = EFI_INVALID_PARAMETER;\r
- break;\r
- }\r
-\r
- Status = EFI_DEVICE_ERROR;\r
- if (OpalDev->DeviceType == OPAL_DEVICE_TYPE_SATA) {\r
- if ((SubClassCode == PCI_CLASS_MASS_STORAGE_AHCI) || (SubClassCode == PCI_CLASS_MASS_STORAGE_RAID)) {\r
- Status = GetAhciBaseAddress (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR, "GetAhciBaseAddress error, Status: %r\n", Status));\r
- goto done;\r
- }\r
- Status = AhciModeInitialize ((UINT8)OpalDev->SataPort);\r
- ASSERT_EFI_ERROR (Status);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR, "AhciModeInitialize error, Status: %r\n", Status));\r
- goto done;\r
- }\r
- } else {\r
- DEBUG ((DEBUG_ERROR, "SubClassCode not support for SATA device\n"));\r
- }\r
- } else if (OpalDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
- if (SubClassCode == PCI_CLASS_MASS_STORAGE_NVM) {\r
- if (ProgInt != PCI_IF_NVMHCI) {\r
- DEBUG ((DEBUG_ERROR, "PI not support, skipped\n"));\r
- Status = EFI_NOT_FOUND;\r
- goto done;\r
- }\r
-\r
- mNvmeContext.PciBase = PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, 0x0);\r
- mNvmeContext.NvmeInitWaitTime = 0;\r
- mNvmeContext.Nsid = OpalDev->NvmeNamespaceId;\r
- Status = NvmeControllerInit (&mNvmeContext);\r
- } else {\r
- DEBUG ((DEBUG_ERROR, "SubClassCode not support for NVME device\n"));\r
- }\r
- } else {\r
- DEBUG ((DEBUG_ERROR, "Invalid Devicetype\n"));\r
- goto done;\r
- }\r
-\r
- Status = EFI_DEVICE_ERROR;\r
- BlockSidSupport = FALSE;\r
- if (IsOpalDeviceLocked (OpalDev, &BlockSidSupport)) {\r
- ZeroMem(&Session, sizeof(Session));\r
- Session.Sscp = &OpalDev->Sscp;\r
- Session.MediaId = 0;\r
- Session.OpalBaseComId = OpalDev->OpalBaseComId;\r
-\r
- Result = OpalSupportUnlock (&Session, OpalDev->Password, OpalDev->PasswordLength, NULL);\r
- if (Result == TcgResultSuccess) {\r
- Status = EFI_SUCCESS;\r
- }\r
- }\r
-\r
- if (mSendBlockSID && BlockSidSupport) {\r
- Result = OpalBlockSid (&Session, TRUE);\r
- if (Result != TcgResultSuccess) {\r
- break;\r
- }\r
- }\r
-\r
- if (OpalDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
- if (SubClassCode == PCI_CLASS_MASS_STORAGE_NVM) {\r
- Status = NvmeControllerExit (&mNvmeContext);\r
- }\r
- }\r
-\r
-done:\r
- if (OpalDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
- ASSERT (RpBase != 0);\r
- PciWrite8 (RpBase + NVME_PCIE_PCICMD, 0);\r
- RpBase = SaveRestoreRootportConfSpace (\r
- OpalDev,\r
- FALSE, // restore\r
- StorePcieConfDataList\r
- );\r
- PciWrite8 (RpBase + NVME_PCIE_PCICMD, SataCmdSt);\r
- } else {\r
- PciWrite8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, NVME_PCIE_PCICMD), SataCmdSt);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- The function extracts device information from OpalDeviceList and creat SmmDeviceList used for S3.\r
-\r
- @param[in] OpalDeviceList Opal device list created at POST which contains the information of OPAL_DISK_AND_PASSWORD_INFO\r
- @param[in,out] SmmDeviceList Opal Smm device list to be created and used for unlocking devices at S3 resume.\r
-\r
- @retval EFI_SUCCESS Create SmmDeviceList successfully.\r
- @retval Others Other execution results.\r
-**/\r
-EFI_STATUS\r
-CreateSmmDeviceList (\r
- IN LIST_ENTRY *OpalDeviceList,\r
- IN OUT LIST_ENTRY *SmmDeviceList\r
- )\r
-{\r
- LIST_ENTRY *Entry;\r
- OPAL_DISK_AND_PASSWORD_INFO *PciDev;\r
- OPAL_SMM_DEVICE *SmmDev;\r
-\r
- for (Entry = OpalDeviceList->ForwardLink; Entry != OpalDeviceList; Entry = Entry->ForwardLink) {\r
- PciDev = BASE_CR (Entry, OPAL_DISK_AND_PASSWORD_INFO, Link);\r
-\r
- SmmDev = AllocateZeroPool (sizeof (OPAL_SMM_DEVICE));\r
- if (SmmDev == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- SmmDev->Signature = OPAL_SMM_DEVICE_SIGNATURE;\r
-\r
- ExtractDeviceInfoFromDevicePath(&PciDev->OpalDevicePath, SmmDev);\r
-\r
- SmmDev->PasswordLength = PciDev->PasswordLength;\r
- CopyMem(&(SmmDev->Password), PciDev->Password, OPAL_PASSWORD_MAX_LENGTH);\r
-\r
- SmmDev->Sscp.ReceiveData = SecurityReceiveData;\r
- SmmDev->Sscp.SendData = SecuritySendData;\r
-\r
- DEBUG ((DEBUG_INFO, "Opal SMM: Insert device node to SmmDeviceList:\n"));\r
- DEBUG ((DEBUG_INFO, "DeviceType:%x, Bus:%d, Dev:%d, Fun:%d\n", \\r
- SmmDev->DeviceType, SmmDev->BusNum, SmmDev->DevNum, SmmDev->FuncNum));\r
- DEBUG ((DEBUG_INFO, "SataPort:%x, MultiplierPort:%x, NvmeNamespaceId:%x\n", \\r
- SmmDev->SataPort, SmmDev->SataPortMultiplierPort, SmmDev->NvmeNamespaceId));\r
-\r
- InsertHeadList (SmmDeviceList, &SmmDev->Link);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Main entry point for an SMM handler dispatch or communicate-based callback.\r
-\r
- @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
- @param[in] Context Points to an optional handler context which was specified when the\r
- handler was registered.\r
- @param[in,out] CommBuffer A pointer to a collection of Data in memory that will\r
- be conveyed from a non-SMM environment into an SMM environment.\r
- @param[in,out] CommBufferSize The Size of the CommBuffer.\r
-\r
- @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers\r
- should still be called.\r
- @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should\r
- still be called.\r
- @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still\r
- be called.\r
- @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-S3SleepEntryCallBack (\r
- IN EFI_HANDLE DispatchHandle,\r
- IN CONST VOID *Context OPTIONAL,\r
- IN OUT VOID *CommBuffer OPTIONAL,\r
- IN OUT UINTN *CommBufferSize OPTIONAL\r
- )\r
-{\r
- UINTN Bus;\r
- UINTN Device;\r
- UINTN Function;\r
- UINTN Index;\r
- EFI_STATUS Status;\r
- LIST_ENTRY *Entry;\r
- UINTN Offset;\r
- UINT64 Address;\r
- S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
- UINT32 Data;\r
- OPAL_HC_PCI_REGISTER_SAVE *HcRegisterSaveListPtr;\r
- UINTN Count;\r
- OPAL_SMM_DEVICE *SmmDev;\r
-\r
- Data = 0;\r
- Status = EFI_SUCCESS;\r
-\r
- mOpalDeviceList = OpalSupportGetOpalDeviceList();\r
- if (IsListEmpty (mOpalDeviceList)) {\r
- //\r
- // No Opal enabled device. Do nothing.\r
- //\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (IsListEmpty (&mSmmDeviceList)) {\r
- //\r
- // mSmmDeviceList for S3 is empty, creat it by mOpalDeviceList.\r
- //\r
- Status = CreateSmmDeviceList (mOpalDeviceList, &mSmmDeviceList);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- //\r
- // Go through SmmDeviceList to save register data for S3\r
- //\r
- for (Entry = mSmmDeviceList.ForwardLink; Entry != &mSmmDeviceList; Entry = Entry->ForwardLink) {\r
- SmmDev = BASE_CR (Entry, OPAL_SMM_DEVICE, Link);\r
-\r
- if (SmmDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
- continue;\r
- }\r
-\r
- //\r
- // Save register Data for S3. Sata controller only.\r
- //\r
- Bus = SmmDev->BusNum;\r
- Device = SmmDev->DevNum;\r
- Function = SmmDev->FuncNum;\r
-\r
- ASSERT (SmmDev->DeviceType == OPAL_DEVICE_TYPE_SATA);\r
- HcRegisterSaveListPtr = (OPAL_HC_PCI_REGISTER_SAVE *) mSataHcRegisterSaveTemplate;\r
- Count = sizeof (mSataHcRegisterSaveTemplate) / sizeof (OPAL_HC_PCI_REGISTER_SAVE);\r
-\r
- for (Index = 0; Index < Count; Index += 1) {\r
- Offset = HcRegisterSaveListPtr[Index].Address;\r
- Width = HcRegisterSaveListPtr[Index].Width;\r
-\r
- switch (Width) {\r
- case S3BootScriptWidthUint8:\r
- Data = (UINT32)PciRead8 (PCI_LIB_ADDRESS(Bus,Device,Function,Offset));\r
- break;\r
- case S3BootScriptWidthUint16:\r
- Data = (UINT32)PciRead16 (PCI_LIB_ADDRESS(Bus,Device,Function,Offset));\r
- break;\r
- case S3BootScriptWidthUint32:\r
- Data = PciRead32 (PCI_LIB_ADDRESS(Bus,Device,Function,Offset));\r
- break;\r
- default:\r
- ASSERT (FALSE);\r
- break;\r
- }\r
-\r
- Address = S3_BOOT_SCRIPT_LIB_PCI_ADDRESS (Bus, Device, Function, Offset);\r
- Status = S3BootScriptSavePciCfgWrite (Width, Address, 1, &Data);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
- }\r
-\r
- Status = S3BootScriptSaveIoWrite (S3BootScriptWidthUint8, 0xB2, 1, &mSwSmiValue);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Main entry for this driver.\r
-\r
- @param ImageHandle Image handle this driver.\r
- @param SystemTable Pointer to SystemTable.\r
-\r
- @retval EFI_SUCESS This function always complete successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalPasswordSmmInit (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;\r
- EFI_SMM_SX_DISPATCH2_PROTOCOL *SxDispatch;\r
- EFI_HANDLE SwHandle;\r
- EFI_SMM_SW_REGISTER_CONTEXT Context;\r
- EFI_HANDLE S3SleepEntryHandle;\r
- EFI_SMM_SX_REGISTER_CONTEXT EntryRegisterContext;\r
- EFI_SMM_VARIABLE_PROTOCOL *SmmVariable;\r
- OPAL_EXTRA_INFO_VAR OpalExtraInfo;\r
- UINTN DataSize;\r
- EFI_PHYSICAL_ADDRESS Address;\r
-\r
- mBuffer = NULL;\r
- SwHandle = NULL;\r
- S3SleepEntryHandle = NULL;\r
- ZeroMem (&mNvmeContext, sizeof (NVME_CONTEXT));\r
-\r
- Status = gSmst->SmmLocateProtocol (\r
- &gEfiSmmSwDispatch2ProtocolGuid,\r
- NULL,\r
- (VOID **)&SwDispatch\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG((DEBUG_ERROR, " SmmLocateProtocol gEfiSmmSwDispatch2ProtocolGuid fail, Status: %r\n", Status));\r
- return Status;\r
- }\r
-\r
- Status = gSmst->SmmLocateProtocol (\r
- &gEfiSmmSxDispatch2ProtocolGuid,\r
- NULL,\r
- (VOID **)&SxDispatch\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG((DEBUG_ERROR, " SmmLocateProtocol gEfiSmmSxDispatch2ProtocolGuid fail, Status: %r\n", Status));\r
- return Status;\r
- }\r
-\r
- //\r
- // Preallocate a 512 bytes Buffer to perform trusted I/O.\r
- // Assume this is big enough for unlock commands\r
- // It's because DMA can not access smmram stack at the cmd execution.\r
- //\r
- Address = 0xFFFFFFFF;\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiACPIMemoryNVS,\r
- EFI_SIZE_TO_PAGES (SMM_SIZE_ALLOC_BYTES),\r
- &Address\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG((DEBUG_ERROR, " AllocatePages for SATA DAM fail, Status: %r\n", Status));\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- mBuffer = (VOID *)(UINTN)Address;\r
- ZeroMem ((VOID *)(UINTN)mBuffer, SMM_SIZE_ALLOC_BYTES);\r
-\r
- //\r
- // Preallocate resource for AHCI transfer descriptor.\r
- //\r
- Status = AhciAllocateResource ();\r
- if (EFI_ERROR (Status)) {\r
- DEBUG((DEBUG_ERROR, " AhciAllocateResource fail, Status: %r\n", Status));\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto EXIT;\r
- }\r
-\r
- //\r
- // Preallocate resource for NVMe configuration space.\r
- //\r
- Status = NvmeAllocateResource (ImageHandle, &mNvmeContext);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG((DEBUG_ERROR, " NvmeAllocateResource fail, Status: %r\n", Status));\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto EXIT;\r
- }\r
-\r
- //\r
- // Register a S3 entry callback function to store ATA host controller context to boot script.\r
- // These boot scripts would be invoked at S3 path to recovery ATA host controller h/w context\r
- // for executing HDD unlock cmd.\r
- //\r
- EntryRegisterContext.Type = SxS3;\r
- EntryRegisterContext.Phase = SxEntry;\r
- Status = SxDispatch->Register (\r
- SxDispatch,\r
- S3SleepEntryCallBack,\r
- &EntryRegisterContext,\r
- &S3SleepEntryHandle\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- if (EFI_ERROR (Status)) {\r
- goto EXIT;\r
- }\r
-\r
- //\r
- // Register Opal password smm unlock handler\r
- //\r
- Context.SwSmiInputValue = (UINTN) -1;\r
- Status = SwDispatch->Register (\r
- SwDispatch,\r
- SmmUnlockOpalPassword,\r
- &Context,\r
- &SwHandle\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG((DEBUG_ERROR, " SwDispatch->Register fail, Status: %r\n", Status));\r
- goto EXIT;\r
- }\r
-\r
- //\r
- // trigger smi to unlock hdd if it's locked.\r
- //\r
- mSwSmiValue = (UINT8) Context.SwSmiInputValue;\r
-\r
- Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&SmmVariable);\r
- if (!EFI_ERROR (Status)) {\r
- DataSize = sizeof (OPAL_EXTRA_INFO_VAR);\r
- Status = SmmVariable->SmmGetVariable (\r
- OPAL_EXTRA_INFO_VAR_NAME,\r
- &gOpalExtraInfoVariableGuid,\r
- NULL,\r
- &DataSize,\r
- &OpalExtraInfo\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- mSendBlockSID = OpalExtraInfo.EnableBlockSid;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-EXIT:\r
- if (S3SleepEntryHandle != NULL) {\r
- SxDispatch->UnRegister (SxDispatch, S3SleepEntryHandle);\r
- }\r
-\r
- AhciFreeResource ();\r
-\r
- NvmeFreeResource (&mNvmeContext);\r
-\r
- if (mBuffer != NULL) {\r
- gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN) mBuffer, EFI_SIZE_TO_PAGES (SMM_SIZE_ALLOC_BYTES));\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Provide Io action support.\r
-\r
- @param[in] SmmDev the opal device need to perform trust io.\r
- @param[in] IoType OPAL_IO_TYPE indicating whether to perform a Trusted Send or Trusted Receive.\r
- @param[in] SecurityProtocol Security Protocol\r
- @param[in] SpSpecific Security Protocol Specific\r
- @param[in] TransferLength Transfer Length of Buffer (in bytes) - always a multiple of 512\r
- @param[in] Buffer Address of Data to transfer\r
-\r
- @retval TcgResultSuccess Perform the io action success.\r
- @retval TcgResultFailure Perform the io action failed.\r
-\r
-**/\r
-EFI_STATUS\r
-PerformTrustedIo (\r
- OPAL_SMM_DEVICE *SmmDev,\r
- OPAL_IO_TYPE IoType,\r
- UINT8 SecurityProtocol,\r
- UINT16 SpSpecific,\r
- UINTN TransferLength,\r
- VOID *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN BufferSizeBlocks;\r
- EFI_ATA_COMMAND_BLOCK AtaCommandBlock;\r
-\r
- Status = EFI_DEVICE_ERROR;\r
- if (SmmDev->DeviceType == OPAL_DEVICE_TYPE_SATA) {\r
- BufferSizeBlocks = TransferLength / 512;\r
-\r
- ZeroMem( &AtaCommandBlock, sizeof( EFI_ATA_COMMAND_BLOCK ) );\r
- AtaCommandBlock.AtaCommand = ( IoType == OpalSend ) ? ATA_COMMAND_TRUSTED_SEND : ATA_COMMAND_TRUSTED_RECEIVE;\r
- AtaCommandBlock.AtaSectorCount = ( UINT8 )BufferSizeBlocks;\r
- AtaCommandBlock.AtaSectorNumber = ( UINT8 )( BufferSizeBlocks >> 8 );\r
- AtaCommandBlock.AtaFeatures = SecurityProtocol;\r
- AtaCommandBlock.AtaCylinderLow = ( UINT8 )( SpSpecific >> 8 );\r
- AtaCommandBlock.AtaCylinderHigh = ( UINT8 )( SpSpecific );\r
- AtaCommandBlock.AtaDeviceHead = ATA_DEVICE_LBA;\r
-\r
-\r
- ZeroMem( mBuffer, HDD_PAYLOAD );\r
- ASSERT( TransferLength <= HDD_PAYLOAD );\r
-\r
- if (IoType == OpalSend) {\r
- CopyMem( mBuffer, Buffer, TransferLength );\r
- }\r
-\r
- Status = AhciPioTransfer(\r
- &mAhciRegisters,\r
- (UINT8) SmmDev->SataPort,\r
- (UINT8) SmmDev->SataPortMultiplierPort,\r
- NULL,\r
- 0,\r
- ( IoType == OpalSend ) ? FALSE : TRUE, // i/o direction\r
- &AtaCommandBlock,\r
- NULL,\r
- mBuffer,\r
- (UINT32)TransferLength,\r
- ATA_TIMEOUT\r
- );\r
-\r
- if (IoType == OpalRecv) {\r
- CopyMem( Buffer, mBuffer, TransferLength );\r
- }\r
- } else if (SmmDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
- Status = NvmeSecuritySendReceive (\r
- &mNvmeContext,\r
- IoType == OpalSend,\r
- SecurityProtocol,\r
- SwapBytes16(SpSpecific),\r
- TransferLength,\r
- Buffer\r
- );\r
- } else {\r
- DEBUG((DEBUG_ERROR, "DeviceType(%x) not support.\n", SmmDev->DeviceType));\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Send a security protocol command to a device that receives data and/or the result\r
- of one or more commands sent by SendData.\r
-\r
- The ReceiveData function sends a security protocol command to the given MediaId.\r
- The security protocol command sent is defined by SecurityProtocolId and contains\r
- the security protocol specific data SecurityProtocolSpecificData. The function\r
- returns the data from the security protocol command in PayloadBuffer.\r
-\r
- For devices supporting the SCSI command set, the security protocol command is sent\r
- using the SECURITY PROTOCOL IN command defined in SPC-4.\r
-\r
- For devices supporting the ATA command set, the security protocol command is sent\r
- using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize\r
- is non-zero.\r
-\r
- If the PayloadBufferSize is zero, the security protocol command is sent using the\r
- Trusted Non-Data command defined in ATA8-ACS.\r
-\r
- If PayloadBufferSize is too small to store the available data from the security\r
- protocol command, the function shall copy PayloadBufferSize bytes into the\r
- PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL.\r
-\r
- If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero,\r
- the function shall return EFI_INVALID_PARAMETER.\r
-\r
- If the given MediaId does not support security protocol commands, the function shall\r
- return EFI_UNSUPPORTED. If there is no media in the device, the function returns\r
- EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device,\r
- the function returns EFI_MEDIA_CHANGED.\r
-\r
- If the security protocol fails to complete within the Timeout period, the function\r
- shall return EFI_TIMEOUT.\r
-\r
- If the security protocol command completes without an error, the function shall\r
- return EFI_SUCCESS. If the security protocol command completes with an error, the\r
- function shall return EFI_DEVICE_ERROR.\r
-\r
- @param This Indicates a pointer to the calling context.\r
- @param MediaId ID of the medium to receive data from.\r
- @param Timeout The timeout, in 100ns units, to use for the execution\r
- of the security protocol command. A Timeout value of 0\r
- means that this function will wait indefinitely for the\r
- security protocol command to execute. If Timeout is greater\r
- than zero, then this function will return EFI_TIMEOUT\r
- if the time required to execute the receive data command\r
- is greater than Timeout.\r
- @param SecurityProtocolId The value of the "Security Protocol" parameter of\r
- the security protocol command to be sent.\r
- @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter\r
- of the security protocol command to be sent.\r
- @param PayloadBufferSize Size in bytes of the payload data buffer.\r
- @param PayloadBuffer A pointer to a destination buffer to store the security\r
- protocol command specific payload data for the security\r
- protocol command. The caller is responsible for having\r
- either implicit or explicit ownership of the buffer.\r
- @param PayloadTransferSize A pointer to a buffer to store the size in bytes of the\r
- data written to the payload data buffer.\r
-\r
- @retval EFI_SUCCESS The security protocol command completed successfully.\r
- @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was too small to store the available\r
- data from the device. The PayloadBuffer contains the truncated data.\r
- @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands.\r
- @retval EFI_DEVICE_ERROR The security protocol command completed with an error.\r
- @retval EFI_NO_MEDIA There is no media in the device.\r
- @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.\r
- @retval EFI_INVALID_PARAMETER The PayloadBuffer or PayloadTransferSize is NULL and\r
- PayloadBufferSize is non-zero.\r
- @retval EFI_TIMEOUT A timeout occurred while waiting for the security\r
- protocol command to execute.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SecurityReceiveData (\r
- IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,\r
- IN UINT32 MediaId,\r
- IN UINT64 Timeout,\r
- IN UINT8 SecurityProtocolId,\r
- IN UINT16 SecurityProtocolSpecificData,\r
- IN UINTN PayloadBufferSize,\r
- OUT VOID *PayloadBuffer,\r
- OUT UINTN *PayloadTransferSize\r
- )\r
-{\r
- OPAL_SMM_DEVICE *SmmDev;\r
-\r
- SmmDev = OPAL_SMM_DEVICE_FROM_THIS (This);\r
- if (SmmDev == NULL) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return PerformTrustedIo (\r
- SmmDev,\r
- OpalRecv,\r
- SecurityProtocolId,\r
- SecurityProtocolSpecificData,\r
- PayloadBufferSize,\r
- PayloadBuffer\r
- );\r
-}\r
-\r
-/**\r
- Send a security protocol command to a device.\r
-\r
- The SendData function sends a security protocol command containing the payload\r
- PayloadBuffer to the given MediaId. The security protocol command sent is\r
- defined by SecurityProtocolId and contains the security protocol specific data\r
- SecurityProtocolSpecificData. If the underlying protocol command requires a\r
- specific padding for the command payload, the SendData function shall add padding\r
- bytes to the command payload to satisfy the padding requirements.\r
-\r
- For devices supporting the SCSI command set, the security protocol command is sent\r
- using the SECURITY PROTOCOL OUT command defined in SPC-4.\r
-\r
- For devices supporting the ATA command set, the security protocol command is sent\r
- using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize\r
- is non-zero. If the PayloadBufferSize is zero, the security protocol command is\r
- sent using the Trusted Non-Data command defined in ATA8-ACS.\r
-\r
- If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall\r
- return EFI_INVALID_PARAMETER.\r
-\r
- If the given MediaId does not support security protocol commands, the function\r
- shall return EFI_UNSUPPORTED. If there is no media in the device, the function\r
- returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the\r
- device, the function returns EFI_MEDIA_CHANGED.\r
-\r
- If the security protocol fails to complete within the Timeout period, the function\r
- shall return EFI_TIMEOUT.\r
-\r
- If the security protocol command completes without an error, the function shall return\r
- EFI_SUCCESS. If the security protocol command completes with an error, the function\r
- shall return EFI_DEVICE_ERROR.\r
-\r
- @param This Indicates a pointer to the calling context.\r
- @param MediaId ID of the medium to receive data from.\r
- @param Timeout The timeout, in 100ns units, to use for the execution\r
- of the security protocol command. A Timeout value of 0\r
- means that this function will wait indefinitely for the\r
- security protocol command to execute. If Timeout is greater\r
- than zero, then this function will return EFI_TIMEOUT\r
- if the time required to execute the send data command\r
- is greater than Timeout.\r
- @param SecurityProtocolId The value of the "Security Protocol" parameter of\r
- the security protocol command to be sent.\r
- @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter\r
- of the security protocol command to be sent.\r
- @param PayloadBufferSize Size in bytes of the payload data buffer.\r
- @param PayloadBuffer A pointer to a destination buffer to store the security\r
- protocol command specific payload data for the security\r
- protocol command.\r
-\r
- @retval EFI_SUCCESS The security protocol command completed successfully.\r
- @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands.\r
- @retval EFI_DEVICE_ERROR The security protocol command completed with an error.\r
- @retval EFI_NO_MEDIA There is no media in the device.\r
- @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.\r
- @retval EFI_INVALID_PARAMETER The PayloadBuffer is NULL and PayloadBufferSize is non-zero.\r
- @retval EFI_TIMEOUT A timeout occurred while waiting for the security\r
- protocol command to execute.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SecuritySendData (\r
- IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,\r
- IN UINT32 MediaId,\r
- IN UINT64 Timeout,\r
- IN UINT8 SecurityProtocolId,\r
- IN UINT16 SecurityProtocolSpecificData,\r
- IN UINTN PayloadBufferSize,\r
- IN VOID *PayloadBuffer\r
- )\r
-{\r
- OPAL_SMM_DEVICE *SmmDev;\r
-\r
- SmmDev = OPAL_SMM_DEVICE_FROM_THIS (This);\r
- if (SmmDev == NULL) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return PerformTrustedIo (\r
- SmmDev,\r
- OpalSend,\r
- SecurityProtocolId,\r
- SecurityProtocolSpecificData,\r
- PayloadBufferSize,\r
- PayloadBuffer\r
- );\r
-\r
-}\r
-\r
+++ /dev/null
-/** @file\r
- Opal password smm driver which is used to support Opal security feature at s3 path.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#ifndef _OPAL_PASSWORD_SMM_H_\r
-#define _OPAL_PASSWORD_SMM_H_\r
-\r
-#include <PiSmm.h>\r
-#include <IndustryStandard/Atapi.h>\r
-\r
-#include <Protocol/SmmSwDispatch2.h>\r
-#include <Protocol/SmmSxDispatch2.h>\r
-#include <Protocol/AtaPassThru.h>\r
-#include <Protocol/PciIo.h>\r
-#include <Protocol/SmmReadyToLock.h>\r
-#include <Protocol/SmmVariable.h>\r
-#include <Protocol/VariableLock.h>\r
-#include <Protocol/SmmEndOfDxe.h>\r
-#include <Protocol/StorageSecurityCommand.h>\r
-\r
-#include <Library/OpalPasswordSupportLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/IoLib.h>\r
-#include <Library/TimerLib.h>\r
-#include <Library/PciLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/SmmServicesTableLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/S3BootScriptLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/DxeServicesTableLib.h>\r
-#include <Library/SmmIoLib.h>\r
-\r
-#include <IndustryStandard/Pci22.h>\r
-\r
-#include <Guid/OpalPasswordExtraInfoVariable.h>\r
-\r
-#include "OpalAhciMode.h"\r
-#include "OpalIdeMode.h"\r
-#include "OpalNvmeMode.h"\r
-\r
-//\r
-// Time out Value for ATA pass through protocol\r
-//\r
-#define ATA_TIMEOUT EFI_TIMER_PERIOD_SECONDS (3)\r
-\r
-//\r
-// The payload Length of HDD related ATA commands\r
-//\r
-#define HDD_PAYLOAD 512\r
-//\r
-// According to ATA spec, the max Length of hdd password is 32 bytes\r
-//\r
-#define OPAL_PASSWORD_MAX_LENGTH 32\r
-\r
-extern VOID *mBuffer;\r
-\r
-#pragma pack(1)\r
-\r
-typedef struct {\r
- UINT32 Address;\r
- S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
-} OPAL_HC_PCI_REGISTER_SAVE;\r
-\r
-\r
-typedef struct {\r
- UINT32 SegNum;\r
- UINT32 BusNum;\r
- UINT32 DevNum;\r
- UINT32 FuncNum;\r
-} PCI_DEVICE;\r
-\r
-/**\r
-* Opal I/O Type utilized by the Trusted IO callback\r
-*\r
-* The type indicates if the I/O is a send or receive\r
-*/\r
-typedef enum {\r
- //\r
- // I/O is a TCG Trusted Send command\r
- //\r
- OpalSend,\r
-\r
- //\r
- // I/O is a TCG Trusted Receive command\r
- //\r
- OpalRecv\r
-} OPAL_IO_TYPE;\r
-\r
-\r
-#define OPAL_SMM_DEVICE_SIGNATURE SIGNATURE_32 ('o', 's', 'd', 's')\r
-\r
-typedef struct {\r
- UINTN Signature;\r
- LIST_ENTRY Link;\r
-\r
- EFI_STORAGE_SECURITY_COMMAND_PROTOCOL Sscp;\r
-\r
- UINT32 SegNum;\r
- UINT32 BusNum;\r
- UINT32 DevNum;\r
- UINT32 FuncNum;\r
-\r
- UINT8 DeviceType;\r
-\r
- UINT32 SataPort;\r
- UINT32 SataPortMultiplierPort;\r
-\r
- UINT32 NvmeNamespaceId;\r
-\r
- UINT8 Password[32];\r
- UINT8 PasswordLength;\r
-\r
- UINT32 Length;\r
- PCI_DEVICE *PciBridgeNode;\r
-\r
- UINT16 OpalBaseComId;\r
-} OPAL_SMM_DEVICE;\r
-\r
-#define OPAL_SMM_DEVICE_FROM_THIS(a) CR (a, OPAL_SMM_DEVICE, Sscp, OPAL_SMM_DEVICE_SIGNATURE)\r
-\r
-#pragma pack()\r
-\r
-/**\r
- Send a security protocol command to a device that receives data and/or the result\r
- of one or more commands sent by SendData.\r
-\r
- The ReceiveData function sends a security protocol command to the given MediaId.\r
- The security protocol command sent is defined by SecurityProtocolId and contains\r
- the security protocol specific data SecurityProtocolSpecificData. The function\r
- returns the data from the security protocol command in PayloadBuffer.\r
-\r
- For devices supporting the SCSI command set, the security protocol command is sent\r
- using the SECURITY PROTOCOL IN command defined in SPC-4.\r
-\r
- For devices supporting the ATA command set, the security protocol command is sent\r
- using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize\r
- is non-zero.\r
-\r
- If the PayloadBufferSize is zero, the security protocol command is sent using the\r
- Trusted Non-Data command defined in ATA8-ACS.\r
-\r
- If PayloadBufferSize is too small to store the available data from the security\r
- protocol command, the function shall copy PayloadBufferSize bytes into the\r
- PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL.\r
-\r
- If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero,\r
- the function shall return EFI_INVALID_PARAMETER.\r
-\r
- If the given MediaId does not support security protocol commands, the function shall\r
- return EFI_UNSUPPORTED. If there is no media in the device, the function returns\r
- EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device,\r
- the function returns EFI_MEDIA_CHANGED.\r
-\r
- If the security protocol fails to complete within the Timeout period, the function\r
- shall return EFI_TIMEOUT.\r
-\r
- If the security protocol command completes without an error, the function shall\r
- return EFI_SUCCESS. If the security protocol command completes with an error, the\r
- function shall return EFI_DEVICE_ERROR.\r
-\r
- @param This Indicates a pointer to the calling context.\r
- @param MediaId ID of the medium to receive data from.\r
- @param Timeout The timeout, in 100ns units, to use for the execution\r
- of the security protocol command. A Timeout value of 0\r
- means that this function will wait indefinitely for the\r
- security protocol command to execute. If Timeout is greater\r
- than zero, then this function will return EFI_TIMEOUT\r
- if the time required to execute the receive data command\r
- is greater than Timeout.\r
- @param SecurityProtocolId The value of the "Security Protocol" parameter of\r
- the security protocol command to be sent.\r
- @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter\r
- of the security protocol command to be sent.\r
- @param PayloadBufferSize Size in bytes of the payload data buffer.\r
- @param PayloadBuffer A pointer to a destination buffer to store the security\r
- protocol command specific payload data for the security\r
- protocol command. The caller is responsible for having\r
- either implicit or explicit ownership of the buffer.\r
- @param PayloadTransferSize A pointer to a buffer to store the size in bytes of the\r
- data written to the payload data buffer.\r
-\r
- @retval EFI_SUCCESS The security protocol command completed successfully.\r
- @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was too small to store the available\r
- data from the device. The PayloadBuffer contains the truncated data.\r
- @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands.\r
- @retval EFI_DEVICE_ERROR The security protocol command completed with an error.\r
- @retval EFI_NO_MEDIA There is no media in the device.\r
- @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.\r
- @retval EFI_INVALID_PARAMETER The PayloadBuffer or PayloadTransferSize is NULL and\r
- PayloadBufferSize is non-zero.\r
- @retval EFI_TIMEOUT A timeout occurred while waiting for the security\r
- protocol command to execute.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SecurityReceiveData (\r
- IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,\r
- IN UINT32 MediaId,\r
- IN UINT64 Timeout,\r
- IN UINT8 SecurityProtocolId,\r
- IN UINT16 SecurityProtocolSpecificData,\r
- IN UINTN PayloadBufferSize,\r
- OUT VOID *PayloadBuffer,\r
- OUT UINTN *PayloadTransferSize\r
- );\r
-\r
-/**\r
- Send a security protocol command to a device.\r
-\r
- The SendData function sends a security protocol command containing the payload\r
- PayloadBuffer to the given MediaId. The security protocol command sent is\r
- defined by SecurityProtocolId and contains the security protocol specific data\r
- SecurityProtocolSpecificData. If the underlying protocol command requires a\r
- specific padding for the command payload, the SendData function shall add padding\r
- bytes to the command payload to satisfy the padding requirements.\r
-\r
- For devices supporting the SCSI command set, the security protocol command is sent\r
- using the SECURITY PROTOCOL OUT command defined in SPC-4.\r
-\r
- For devices supporting the ATA command set, the security protocol command is sent\r
- using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize\r
- is non-zero. If the PayloadBufferSize is zero, the security protocol command is\r
- sent using the Trusted Non-Data command defined in ATA8-ACS.\r
-\r
- If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall\r
- return EFI_INVALID_PARAMETER.\r
-\r
- If the given MediaId does not support security protocol commands, the function\r
- shall return EFI_UNSUPPORTED. If there is no media in the device, the function\r
- returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the\r
- device, the function returns EFI_MEDIA_CHANGED.\r
-\r
- If the security protocol fails to complete within the Timeout period, the function\r
- shall return EFI_TIMEOUT.\r
-\r
- If the security protocol command completes without an error, the function shall return\r
- EFI_SUCCESS. If the security protocol command completes with an error, the function\r
- shall return EFI_DEVICE_ERROR.\r
-\r
- @param This Indicates a pointer to the calling context.\r
- @param MediaId ID of the medium to receive data from.\r
- @param Timeout The timeout, in 100ns units, to use for the execution\r
- of the security protocol command. A Timeout value of 0\r
- means that this function will wait indefinitely for the\r
- security protocol command to execute. If Timeout is greater\r
- than zero, then this function will return EFI_TIMEOUT\r
- if the time required to execute the receive data command\r
- is greater than Timeout.\r
- @param SecurityProtocolId The value of the "Security Protocol" parameter of\r
- the security protocol command to be sent.\r
- @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter\r
- of the security protocol command to be sent.\r
- @param PayloadBufferSize Size in bytes of the payload data buffer.\r
- @param PayloadBuffer A pointer to a destination buffer to store the security\r
- protocol command specific payload data for the security\r
- protocol command.\r
-\r
- @retval EFI_SUCCESS The security protocol command completed successfully.\r
- @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands.\r
- @retval EFI_DEVICE_ERROR The security protocol command completed with an error.\r
- @retval EFI_NO_MEDIA There is no media in the device.\r
- @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.\r
- @retval EFI_INVALID_PARAMETER The PayloadBuffer is NULL and PayloadBufferSize is non-zero.\r
- @retval EFI_TIMEOUT A timeout occurred while waiting for the security\r
- protocol command to execute.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SecuritySendData (\r
- IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,\r
- IN UINT32 MediaId,\r
- IN UINT64 Timeout,\r
- IN UINT8 SecurityProtocolId,\r
- IN UINT16 SecurityProtocolSpecificData,\r
- IN UINTN PayloadBufferSize,\r
- IN VOID *PayloadBuffer\r
- );\r
-\r
-#endif // _OPAL_PASSWORD_SMM_H_\r
-\r
+++ /dev/null
-## @file\r
-# This is a Opal Password Smm driver.\r
-#\r
-# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-##\r
-[Defines]\r
- INF_VERSION = 0x00010005\r
- BASE_NAME = OpalPasswordSmm\r
- FILE_GUID = 7D24A234-A8C2-4718-BF60-A2EF070F414E\r
- MODULE_TYPE = DXE_SMM_DRIVER\r
- VERSION_STRING = 1.0\r
- PI_SPECIFICATION_VERSION = 0x0001000A\r
- ENTRY_POINT = OpalPasswordSmmInit\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
-#\r
-\r
-[Sources]\r
- OpalPasswordSmm.c\r
- OpalPasswordSmm.h\r
- OpalAhciMode.c\r
- OpalAhciMode.h\r
- OpalIdeMode.c\r
- OpalIdeMode.h\r
- OpalNvmeMode.c\r
- OpalNvmeMode.h\r
- OpalNvmeReg.h\r
-\r
-[Packages]\r
- MdePkg/MdePkg.dec\r
- SecurityPkg/SecurityPkg.dec\r
- MdeModulePkg/MdeModulePkg.dec\r
-\r
-[LibraryClasses]\r
- UefiBootServicesTableLib\r
- UefiDriverEntryPoint\r
- UefiRuntimeServicesTableLib\r
- DebugLib\r
- IoLib\r
- PciLib\r
- BaseLib\r
- BaseMemoryLib\r
- SmmServicesTableLib\r
- MemoryAllocationLib\r
- UefiLib\r
- TimerLib\r
- S3BootScriptLib\r
- DxeServicesTableLib\r
- DevicePathLib\r
- OpalPasswordSupportLib\r
- SmmIoLib\r
-\r
-[Guids]\r
- gOpalExtraInfoVariableGuid ## CONSUMES ## GUID\r
-\r
-[Protocols]\r
- gEfiSmmSwDispatch2ProtocolGuid ## CONSUMES\r
- gEfiAtaPassThruProtocolGuid ## CONSUMES\r
- gEfiPciIoProtocolGuid ## CONSUMES\r
- gEfiSmmSxDispatch2ProtocolGuid ## CONSUMES\r
- gEfiSmmVariableProtocolGuid ## CONSUMES\r
- gEfiStorageSecurityCommandProtocolGuid ## CONSUMES\r
-\r
-[Depex]\r
- gEfiSmmSwDispatch2ProtocolGuid AND\r
- gEfiSmmSxDispatch2ProtocolGuid AND\r
- gEfiSmmVariableProtocolGuid\r