/** Set performance level of a domain. @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance. @param[in] DomainId Identifier for the performance domain. @param[in] Level Performance level of the domain. @retval EFI_SUCCESS Performance level set successfully. @retval EFI_DEVICE_ERROR SCP returns an SCMI error. @retval !(EFI_SUCCESS) Other errors. **/ EFI_STATUS PerformanceLevelSet ( IN SCMI_PERFORMANCE_PROTOCOL *This, IN UINT32 DomainId, IN UINT32 Level ) { EFI_STATUS Status; UINT32 PayloadLength; SCMI_COMMAND Cmd; UINT32 *MessageParams; Status = ScmiCommandGetPayload (&MessageParams); if (EFI_ERROR (Status)) { return Status; } *MessageParams++ = DomainId; *MessageParams = Level; Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE; Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_LEVEL_SET; PayloadLength = sizeof (DomainId) + sizeof (Level); Status = ScmiCommandExecute ( &Cmd, &PayloadLength, NULL ); return Status; }
/** 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 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 performance domain attributes. @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance. @param[in] DomainId Identifier for the performance domain. @param[out] Attributes Performance domain attributes. @retval EFI_SUCCESS Domain attributes are returned. @retval EFI_DEVICE_ERROR SCP returns an SCMI error. @retval !(EFI_SUCCESS) Other errors. **/ STATIC EFI_STATUS PerformanceDomainAttributes ( IN SCMI_PERFORMANCE_PROTOCOL *This, IN UINT32 DomainId, OUT SCMI_PERFORMANCE_DOMAIN_ATTRIBUTES *DomainAttributes ) { EFI_STATUS Status; UINT32 *MessageParams; UINT32 *ReturnValues; UINT32 PayloadLength; SCMI_COMMAND Cmd; Status = ScmiCommandGetPayload (&MessageParams); if (EFI_ERROR (Status)) { return Status; } *MessageParams = DomainId; Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE; Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_DOMAIN_ATTRIBUTES; PayloadLength = sizeof (DomainId); Status = ScmiCommandExecute ( &Cmd, &PayloadLength, &ReturnValues ); if (EFI_ERROR (Status)) { return Status; } CopyMem ( DomainAttributes, ReturnValues, sizeof (SCMI_PERFORMANCE_DOMAIN_ATTRIBUTES) ); return EFI_SUCCESS; }
/** Get performance limits of a domain. @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance. @param[in] DomainId Identifier for the performance domain. @param[out] Limit Performance Limits of the domain. @retval EFI_SUCCESS Performance limits are returned. @retval EFI_DEVICE_ERROR SCP returns an SCMI error. @retval !(EFI_SUCCESS) Other errors. **/ EFI_STATUS PerformanceLimitsGet ( SCMI_PERFORMANCE_PROTOCOL *This, UINT32 DomainId, SCMI_PERFORMANCE_LIMITS *Limits ) { EFI_STATUS Status; UINT32 PayloadLength; SCMI_COMMAND Cmd; UINT32 *MessageParams; SCMI_PERFORMANCE_LIMITS *ReturnValues; Status = ScmiCommandGetPayload (&MessageParams); if (EFI_ERROR (Status)) { return Status; } *MessageParams = DomainId; Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE; Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_LIMITS_GET; PayloadLength = sizeof (DomainId); Status = ScmiCommandExecute ( &Cmd, &PayloadLength, (UINT32**)&ReturnValues ); if (EFI_ERROR (Status)) { return Status; } Limits->RangeMax = ReturnValues->RangeMax; Limits->RangeMin = ReturnValues->RangeMin; return EFI_SUCCESS; }
/** Get performance level of a domain. @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance. @param[in] DomainId Identifier for the performance domain. @param[out] Level Performance level of the domain. @retval EFI_SUCCESS Performance level got successfully. @retval EFI_DEVICE_ERROR SCP returns an SCMI error. @retval !(EFI_SUCCESS) Other errors. **/ EFI_STATUS PerformanceLevelGet ( IN SCMI_PERFORMANCE_PROTOCOL *This, IN UINT32 DomainId, OUT UINT32 *Level ) { EFI_STATUS Status; UINT32 PayloadLength; SCMI_COMMAND Cmd; UINT32 *ReturnValues; UINT32 *MessageParams; Status = ScmiCommandGetPayload (&MessageParams); if (EFI_ERROR (Status)) { return Status; } *MessageParams = DomainId; Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE; Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_LEVEL_GET; PayloadLength = sizeof (DomainId); Status = ScmiCommandExecute ( &Cmd, &PayloadLength, &ReturnValues ); if (EFI_ERROR (Status)) { return Status; } *Level = *ReturnValues; return EFI_SUCCESS; }
/** Return list of performance domain levels of a given domain. @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance. @param[in] DomainId Identifier for the performance domain. @param[out] NumLevels Total number of levels a domain can support. @param[in,out] LevelArraySize Size of the performance level array. @param[out] LevelArray Array of the performance levels. @retval EFI_SUCCESS Domain levels are returned. @retval EFI_DEVICE_ERROR SCP returns an SCMI error. @retval EFI_BUFFER_TOO_SMALL LevelArraySize is too small for the result. It has been updated to the size needed. @retval !(EFI_SUCCESS) Other errors. **/ STATIC EFI_STATUS PerformanceDescribeLevels ( IN SCMI_PERFORMANCE_PROTOCOL *This, IN UINT32 DomainId, OUT UINT32 *NumLevels, IN OUT UINT32 *LevelArraySize, OUT SCMI_PERFORMANCE_LEVEL *LevelArray ) { EFI_STATUS Status; UINT32 PayloadLength; SCMI_COMMAND Cmd; UINT32* MessageParams; UINT32 LevelIndex; UINT32 RequiredSize; UINT32 LevelNo; UINT32 ReturnNumLevels; UINT32 ReturnRemainNumLevels; PERF_DESCRIBE_LEVELS *Levels; Status = ScmiCommandGetPayload (&MessageParams); if (EFI_ERROR (Status)) { return Status; } LevelIndex = 0; RequiredSize = 0; *MessageParams++ = DomainId; Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE; Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_DESCRIBE_LEVELS; do { *MessageParams = LevelIndex; // Note, PayloadLength is an IN/OUT parameter. PayloadLength = sizeof (DomainId) + sizeof (LevelIndex); Status = ScmiCommandExecute ( &Cmd, &PayloadLength, (UINT32**)&Levels ); if (EFI_ERROR (Status)) { return Status; } ReturnNumLevels = NUM_PERF_LEVELS (Levels->NumLevels); ReturnRemainNumLevels = NUM_REMAIN_PERF_LEVELS (Levels->NumLevels); if (RequiredSize == 0) { *NumLevels = ReturnNumLevels + ReturnRemainNumLevels; RequiredSize = (*NumLevels) * sizeof (SCMI_PERFORMANCE_LEVEL); if (RequiredSize > (*LevelArraySize)) { // Update LevelArraySize with required size. *LevelArraySize = RequiredSize; return EFI_BUFFER_TOO_SMALL; } } for (LevelNo = 0; LevelNo < ReturnNumLevels; LevelNo++) { CopyMem ( &LevelArray[LevelIndex++], &Levels->PerfLevel[LevelNo], sizeof (SCMI_PERFORMANCE_LEVEL) ); } } while (ReturnRemainNumLevels != 0); *LevelArraySize = RequiredSize; 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; }