/** 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;
}
Exemple #2
0
/** 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;
}
Exemple #3
0
/** 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;
}
Exemple #8
0
/** 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;
}