| /** @file | |
| Copyright (c) 2017-2021, Arm Limited. All rights reserved.<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| System Control and Management Interface V1.0 | |
| http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ | |
| DEN0056A_System_Control_and_Management_Interface.pdf | |
| **/ | |
| #include <Library/BaseLib.h> | |
| #include <Library/DebugLib.h> | |
| #include <Library/UefiBootServicesTableLib.h> | |
| #include <Protocol/ArmScmiBaseProtocol.h> | |
| #include "ArmScmiBaseProtocolPrivate.h" | |
| #include "ScmiPrivate.h" | |
| /** Return version of the Base protocol supported by SCP firmware. | |
| @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. | |
| @param[out] Version Version of the supported SCMI Base protocol. | |
| @retval EFI_SUCCESS The version of the protocol is returned. | |
| @retval EFI_DEVICE_ERROR SCP returns an SCMI error. | |
| @retval !(EFI_SUCCESS) Other errors. | |
| **/ | |
| STATIC | |
| EFI_STATUS | |
| BaseGetVersion ( | |
| IN SCMI_BASE_PROTOCOL *This, | |
| OUT UINT32 *Version | |
| ) | |
| { | |
| return ScmiGetProtocolVersion (ScmiProtocolIdBase, Version); | |
| } | |
| /** Return total number of SCMI protocols supported by the SCP firmware. | |
| @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. | |
| @param[out] TotalProtocols Total number of SCMI protocols supported. | |
| @retval EFI_SUCCESS Total number of protocols supported are returned. | |
| @retval EFI_DEVICE_ERROR SCP returns a SCMI error. | |
| @retval !(EFI_SUCCESS) Other errors. | |
| **/ | |
| STATIC | |
| EFI_STATUS | |
| BaseGetTotalProtocols ( | |
| IN SCMI_BASE_PROTOCOL *This, | |
| OUT UINT32 *TotalProtocols | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINT32 *ReturnValues; | |
| Status = ScmiGetProtocolAttributes (ScmiProtocolIdBase, &ReturnValues); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| *TotalProtocols = SCMI_TOTAL_PROTOCOLS (ReturnValues[0]); | |
| return EFI_SUCCESS; | |
| } | |
| /** Common function which returns vendor details. | |
| @param[in] MessageId ScmiMessageIdBaseDiscoverVendor | |
| OR | |
| ScmiMessageIdBaseDiscoverSubVendor | |
| @param[out] VendorIdentifier ASCII name of the vendor/subvendor. | |
| @retval EFI_SUCCESS VendorIdentifier is returned. | |
| @retval EFI_DEVICE_ERROR SCP returns an SCMI error. | |
| @retval !(EFI_SUCCESS) Other errors. | |
| **/ | |
| STATIC | |
| EFI_STATUS | |
| BaseDiscoverVendorDetails ( | |
| IN SCMI_MESSAGE_ID_BASE MessageId, | |
| OUT UINT8 VendorIdentifier[SCMI_MAX_STR_LEN] | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINT32 *ReturnValues; | |
| SCMI_COMMAND Cmd; | |
| UINT32 PayloadLength; | |
| Cmd.ProtocolId = ScmiProtocolIdBase; | |
| Cmd.MessageId = MessageId; | |
| PayloadLength = 0; | |
| Status = ScmiCommandExecute ( | |
| &Cmd, | |
| &PayloadLength, | |
| &ReturnValues | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| AsciiStrCpyS ( | |
| (CHAR8 *)VendorIdentifier, | |
| SCMI_MAX_STR_LEN, | |
| (CONST CHAR8 *)ReturnValues | |
| ); | |
| return EFI_SUCCESS; | |
| } | |
| /** Return vendor name. | |
| @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. | |
| @param[out] VendorIdentifier Null terminated ASCII string of up to | |
| 16 bytes with a vendor name. | |
| @retval EFI_SUCCESS VendorIdentifier is returned. | |
| @retval EFI_DEVICE_ERROR SCP returns a SCMI error. | |
| @retval !(EFI_SUCCESS) Other errors. | |
| **/ | |
| STATIC | |
| EFI_STATUS | |
| BaseDiscoverVendor ( | |
| IN SCMI_BASE_PROTOCOL *This, | |
| OUT UINT8 VendorIdentifier[SCMI_MAX_STR_LEN] | |
| ) | |
| { | |
| return BaseDiscoverVendorDetails ( | |
| ScmiMessageIdBaseDiscoverVendor, | |
| VendorIdentifier | |
| ); | |
| } | |
| /** Return sub vendor name. | |
| @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. | |
| @param[out] VendorIdentifier Null terminated ASCII string of up to | |
| 16 bytes with a sub vendor name. | |
| @retval EFI_SUCCESS VendorIdentifier is returned. | |
| @retval EFI_DEVICE_ERROR SCP returns a SCMI error. | |
| @retval !(EFI_SUCCESS) Other errors. | |
| **/ | |
| EFI_STATUS | |
| BaseDiscoverSubVendor ( | |
| IN SCMI_BASE_PROTOCOL *This, | |
| OUT UINT8 VendorIdentifier[SCMI_MAX_STR_LEN] | |
| ) | |
| { | |
| return BaseDiscoverVendorDetails ( | |
| ScmiMessageIdBaseDiscoverSubVendor, | |
| VendorIdentifier | |
| ); | |
| } | |
| /** Return implementation version. | |
| @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. | |
| @param[out] ImplementationVersion Vendor specific implementation version. | |
| @retval EFI_SUCCESS Implementation version is returned. | |
| @retval EFI_DEVICE_ERROR SCP returns a SCMI error. | |
| @retval !(EFI_SUCCESS) Other errors. | |
| **/ | |
| STATIC | |
| EFI_STATUS | |
| BaseDiscoverImplVersion ( | |
| IN SCMI_BASE_PROTOCOL *This, | |
| OUT UINT32 *ImplementationVersion | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINT32 *ReturnValues; | |
| SCMI_COMMAND Cmd; | |
| UINT32 PayloadLength; | |
| Cmd.ProtocolId = ScmiProtocolIdBase; | |
| Cmd.MessageId = ScmiMessageIdBaseDiscoverImplementationVersion; | |
| PayloadLength = 0; | |
| Status = ScmiCommandExecute ( | |
| &Cmd, | |
| &PayloadLength, | |
| &ReturnValues | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| *ImplementationVersion = ReturnValues[0]; | |
| return EFI_SUCCESS; | |
| } | |
| /** Return list of protocols. | |
| @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. | |
| @param[out] ProtocolListSize Size of the ProtocolList. | |
| @param[out] ProtocolList Protocol list. | |
| @retval EFI_SUCCESS List of protocols is returned. | |
| @retval EFI_BUFFER_TOO_SMALL ProtocolListSize is too small for the result. | |
| It has been updated to the size needed. | |
| @retval EFI_DEVICE_ERROR SCP returns a SCMI error. | |
| @retval !(EFI_SUCCESS) Other errors. | |
| **/ | |
| STATIC | |
| EFI_STATUS | |
| BaseDiscoverListProtocols ( | |
| IN SCMI_BASE_PROTOCOL *This, | |
| IN OUT UINT32 *ProtocolListSize, | |
| OUT UINT8 *ProtocolList | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINT32 TotalProtocols; | |
| UINT32 *MessageParams; | |
| BASE_DISCOVER_LIST *DiscoverList; | |
| UINT32 Skip; | |
| UINT32 Index; | |
| SCMI_COMMAND Cmd; | |
| UINT32 PayloadLength; | |
| UINT32 RequiredSize; | |
| Status = BaseGetTotalProtocols (This, &TotalProtocols); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| Status = ScmiCommandGetPayload (&MessageParams); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| RequiredSize = sizeof (UINT8) * TotalProtocols; | |
| if (*ProtocolListSize < RequiredSize) { | |
| *ProtocolListSize = RequiredSize; | |
| return EFI_BUFFER_TOO_SMALL; | |
| } | |
| Cmd.ProtocolId = ScmiProtocolIdBase; | |
| Cmd.MessageId = ScmiMessageIdBaseDiscoverListProtocols; | |
| Skip = 0; | |
| while (Skip < TotalProtocols) { | |
| *MessageParams = Skip; | |
| // Note PayloadLength is a IN/OUT parameter. | |
| PayloadLength = sizeof (Skip); | |
| Status = ScmiCommandExecute ( | |
| &Cmd, | |
| &PayloadLength, | |
| (UINT32 **)&DiscoverList | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| for (Index = 0; Index < DiscoverList->NumProtocols; Index++) { | |
| ProtocolList[Skip++] = DiscoverList->Protocols[Index]; | |
| } | |
| } | |
| *ProtocolListSize = RequiredSize; | |
| return EFI_SUCCESS; | |
| } | |
| // Instance of the SCMI Base protocol. | |
| STATIC CONST SCMI_BASE_PROTOCOL BaseProtocol = { | |
| BaseGetVersion, | |
| BaseGetTotalProtocols, | |
| BaseDiscoverVendor, | |
| BaseDiscoverSubVendor, | |
| BaseDiscoverImplVersion, | |
| BaseDiscoverListProtocols | |
| }; | |
| /** Initialize Base protocol and install protocol on a given handle. | |
| @param[in] Handle Handle to install Base protocol. | |
| @retval EFI_SUCCESS Base protocol interface installed | |
| successfully. | |
| **/ | |
| EFI_STATUS | |
| ScmiBaseProtocolInit ( | |
| IN OUT EFI_HANDLE *Handle | |
| ) | |
| { | |
| return gBS->InstallMultipleProtocolInterfaces ( | |
| Handle, | |
| &gArmScmiBaseProtocolGuid, | |
| &BaseProtocol, | |
| NULL | |
| ); | |
| } |