summaryrefslogtreecommitdiffstats
path: root/ArmPkg/Drivers/ArmScmiDxe/ScmiBaseProtocol.c
diff options
context:
space:
mode:
Diffstat (limited to 'ArmPkg/Drivers/ArmScmiDxe/ScmiBaseProtocol.c')
-rw-r--r--ArmPkg/Drivers/ArmScmiDxe/ScmiBaseProtocol.c318
1 files changed, 318 insertions, 0 deletions
diff --git a/ArmPkg/Drivers/ArmScmiDxe/ScmiBaseProtocol.c b/ArmPkg/Drivers/ArmScmiDxe/ScmiBaseProtocol.c
new file mode 100644
index 0000000000..0829438c82
--- /dev/null
+++ b/ArmPkg/Drivers/ArmScmiDxe/ScmiBaseProtocol.c
@@ -0,0 +1,318 @@
+/** @file
+
+ Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ 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 (SCMI_PROTOCOL_ID_BASE, 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 (SCMI_PROTOCOL_ID_BASE, &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 SCMI_MESSAGE_ID_BASE_DISCOVER_VENDOR
+ OR
+ SCMI_MESSAGE_ID_BASE_DISCOVER_SUB_VENDOR
+
+ @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 = SCMI_PROTOCOL_ID_BASE;
+ 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 (
+ SCMI_MESSAGE_ID_BASE_DISCOVER_VENDOR,
+ 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 (
+ SCMI_MESSAGE_ID_BASE_DISCOVER_SUB_VENDOR,
+ 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 = SCMI_PROTOCOL_ID_BASE;
+ Cmd.MessageId = SCMI_MESSAGE_ID_BASE_DISCOVER_IMPLEMENTATION_VERSION;
+
+ 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 = SCMI_PROTOCOL_ID_BASE;
+ Cmd.MessageId = SCMI_MESSAGE_ID_BASE_DISCOVER_LIST_PROTOCOLS;
+
+ 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
+ );
+}