From f72a939c03afa519187b7ce10bd1fb09a358e893 Mon Sep 17 00:00:00 2001 From: Jim Quigley Date: Wed, 17 Jun 2020 16:12:00 +0100 Subject: [PATCH 1/9] SCMI: Resource Permissions Module This patch adds the SCMI Resource Permissions module to the firmware. Change-Id: I4dc738024eebc77f23b64095670ecbbb8e7f6e34 Signed-off-by: Jim Quigley --- .../include/mod_resource_perms.h | 452 +++++++++++ module/resource_perms/src/Makefile | 11 + .../resource_perms/src/mod_resource_perms.c | 709 ++++++++++++++++++ module/scmi/include/mod_scmi_std.h | 6 + tools/build_system/firmware.mk | 6 + tools/build_system/rules.mk | 4 + 6 files changed, 1188 insertions(+) create mode 100644 module/resource_perms/include/mod_resource_perms.h create mode 100644 module/resource_perms/src/Makefile create mode 100644 module/resource_perms/src/mod_resource_perms.c diff --git a/module/resource_perms/include/mod_resource_perms.h b/module/resource_perms/include/mod_resource_perms.h new file mode 100644 index 000000000..b76271572 --- /dev/null +++ b/module/resource_perms/include/mod_resource_perms.h @@ -0,0 +1,452 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * System Control and Management Interface (SCMI) + * Resource Management Support. + */ + +#ifndef MOD_SCMI_RESOURCE_PERMISSIONS_H +#define MOD_SCMI_RESOURCE_PERMISSIONS_H + +#include + +#include +#include + +#include + +/* + * We will use type uint16_t to track the resources. + */ +typedef uint16_t mod_res_perms_t; + +#define MOD_RES_PERMS_TYPE_BITS (sizeof(mod_res_perms_t) * CHAR_BIT) +#define MOD_RES_PERMS_TYPE_SHIFT (4) +#define MOD_RES_PERMS_TYPE_MASK ((1 << MOD_RES_PERMS_TYPE_SHIFT) - 1) + +/*! Find the array element for the resource */ +#define MOD_RES_PERMS_RESOURCE_ELEMENT(resource_id) \ + (resource_id >> MOD_RES_PERMS_TYPE_SHIFT) + +/*! Find the bit in the array element for the resource */ +#define MOD_RES_PERMS_RESOURCE_BIT(resource_id) \ + (resource_id & MOD_RES_PERMS_TYPE_MASK) + +/*! + * \brief Bits to set to deny Protocol permissions. Note that the default + * throughout is to allow access to a Protocol:Message:Resource. + */ +enum mod_res_perms_permissions { + MOD_RES_PERMS_ACCESS_ALLOWED = 0, + MOD_RES_PERMS_ACCESS_DENIED = 1, +}; + +#define MOD_RES_PERMS_PROTOCOL_OFFSET MOD_SCMI_PROTOCOL_ID_BASE + +enum mod_res_perms_protocol_deny { + MOD_RES_PERMS_SCMI_ALL_PROTOCOLS_ALLOWED = 0, + MOD_RES_PERMS_SCMI_BASE_PROTOCOL_DENIED = MOD_RES_PERMS_ACCESS_DENIED + << (MOD_SCMI_PROTOCOL_ID_BASE - MOD_RES_PERMS_PROTOCOL_OFFSET), + MOD_RES_PERMS_SCMI_CLOCK_PROTOCOL_DENIED = MOD_RES_PERMS_ACCESS_DENIED + << (MOD_SCMI_PROTOCOL_ID_CLOCK - MOD_RES_PERMS_PROTOCOL_OFFSET), + MOD_RES_PERMS_SCMI_SYS_POWER_PROTOCOL_DENIED = MOD_RES_PERMS_ACCESS_DENIED + << (MOD_SCMI_PROTOCOL_ID_SYS_POWER - MOD_RES_PERMS_PROTOCOL_OFFSET), + MOD_RES_PERMS_SCMI_POWER_DOMAIN_DENIED = MOD_RES_PERMS_ACCESS_DENIED + << (MOD_SCMI_PROTOCOL_ID_POWER_DOMAIN - MOD_RES_PERMS_PROTOCOL_OFFSET), + MOD_RES_PERMS_SCMI_PERF_PROTOCOL_DENIED = MOD_RES_PERMS_ACCESS_DENIED + << (MOD_SCMI_PROTOCOL_ID_PERF - MOD_RES_PERMS_PROTOCOL_OFFSET), + MOD_RES_PERMS_SCMI_SENSOR_PROTOCOL_DENIED = MOD_RES_PERMS_ACCESS_DENIED + << (MOD_SCMI_PROTOCOL_ID_SENSOR - MOD_RES_PERMS_PROTOCOL_OFFSET), + MOD_RES_PERMS_SCMI_RESET_DOMAIN_PROTOCOL_DENIED = + MOD_RES_PERMS_ACCESS_DENIED + << (MOD_SCMI_PROTOCOL_ID_RESET_DOMAIN - MOD_RES_PERMS_PROTOCOL_OFFSET), +}; + +/*! + * \brief Bitmask of the protocols disabled for the agent. + */ +struct mod_res_agent_protocol_permissions { + /*! + * \details This bitmask specifies which protocols are DISABLED for this + * agent. If a bit is set that agent does NOT have permission to + * use the protocol. + */ + mod_res_perms_t protocols; +}; + +/*! + * \brief Bits to set to deny Message permissions. Note that the default + * throughout is to allow access to a Message:Resource. + */ +#define MOD_RES_PERMS_MESSAGE_OFFSET MOD_SCMI_PROTOCOL_ID_BASE + +enum mod_res_perms_message_idx { + MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX = + MOD_SCMI_PROTOCOL_ID_BASE - MOD_RES_PERMS_MESSAGE_OFFSET, + MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX = + MOD_SCMI_PROTOCOL_ID_CLOCK - MOD_RES_PERMS_MESSAGE_OFFSET, + MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX = + MOD_SCMI_PROTOCOL_ID_SYS_POWER - MOD_RES_PERMS_MESSAGE_OFFSET, + MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX = + MOD_SCMI_PROTOCOL_ID_POWER_DOMAIN - MOD_RES_PERMS_MESSAGE_OFFSET, + MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX = + MOD_SCMI_PROTOCOL_ID_PERF - MOD_RES_PERMS_MESSAGE_OFFSET, + MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX = + MOD_SCMI_PROTOCOL_ID_SENSOR - MOD_RES_PERMS_MESSAGE_OFFSET, + MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX = + MOD_SCMI_PROTOCOL_ID_RESET_DOMAIN - MOD_RES_PERMS_MESSAGE_OFFSET, +}; + +/*! + * \brief Bits to set when denying message permissions. The + * VERSION/ATTRIBUTES/MSG_ATTRIBUTES messages are available to all + * agents. The message bits for each protocol are defined as + * offsets from the corresponding base index. + */ +enum mod_res_perms_message_bitmask_base { + MOD_RES_PERMS_SCMI_BASE_BITMASK_IDX = MOD_SCMI_BASE_NOTIFY_ERRORS, + MOD_RES_PERMS_SCMI_CLOCK_BITMASK_IDX = MOD_SCMI_CLOCK_ATTRIBUTES, + MOD_RES_PERMS_SCMI_SYS_POWER_BITMASK_IDX = MOD_SCMI_SYS_POWER_STATE_SET, + MOD_RES_PERMS_SCMI_POWER_DOMAIN_BITMASK_IDX = + MOD_SCMI_PD_POWER_DOMAIN_ATTRIBUTES, + MOD_RES_PERMS_SCMI_PERF_BITMASK_IDX = MOD_SCMI_PERF_DOMAIN_ATTRIBUTES, + MOD_RES_PERMS_SCMI_SENSOR_BITMASK_IDX = MOD_SCMI_SENSOR_DESCRIPTION_GET, + MOD_RES_PERMS_SCMI_RESET_DOMAIN_BITMASK_IDX = + MOD_SCMI_RESET_DOMAIN_ATTRIBUTES, +}; + +/*! + * \brief Bitmask of the messages for each protocol disabled for + * the agent. Currently we have 8 SCMI protocols. + */ +struct mod_res_agent_msg_permissions { + /*! \details Bitmask of the disabled messages for each protocol. */ + mod_res_perms_t messages[8]; +}; + +/*! + * \brief Bitmask of the resources for each protocol:command disabled for + * the agent. + * + * \details Each protocol will manage a unique number of commands, so + * we specify different size tables. + * + * If the permissions table is not set then the agent is deemed + * to be allowed access that protocol:command:resource. They will + * be checked in order protocol->command->resource. + * + * In order for a protocol to be disabled for an agent, the + * bit must be SET in the agent_protocol_permissions table. + * + * In order for a command to be disabled for an agent, the + * bit must be SET in the agent_cmd_permissions table. + * + * In order for a resource to be disabled for an agent, the + * bit must be SET in the agent_permission table. + * + * \note The VERSION/ATTRIBUTES/MSG_ATTRIBUTES commands + * are available to all agents. + * + * \note The BASE and SYSTEM_POWER protocols are managed by + * agent:protocol:command, there are no resource + * permissions associated with these protocols. + * + */ + +/*! + * \brief SCMI Agent Permissions + * + * \details An agent may have any combination of the permissions + * tables set. + */ +struct mod_res_agent_permission { + /*! \brief Protocol permissions. */ + struct mod_res_agent_protocol_permissions *agent_protocol_permissions; + + /*! \brief Protocol:Message permissions. */ + struct mod_res_agent_msg_permissions *agent_msg_permissions; + + /*! \brief Power Domain:Resource permissions. */ + mod_res_perms_t *scmi_pd_perms; + + /*! Performance:Resource permissions. */ + mod_res_perms_t *scmi_perf_perms; + + /*! \brief Clock:Resource permissions. */ + mod_res_perms_t *scmi_clock_perms; + + /*! \brief Sensor:Resource permissions. */ + mod_res_perms_t *scmi_sensor_perms; + +#ifdef BUILD_HAS_SCMI_RESET + /*! \brief Reset Domain:Resource permissions. */ + mod_res_perms_t *scmi_reset_domain_perms; +#endif +}; + +/*! + * \brief Type of the interfaces exposed by the resource permissions module. + */ +enum mod_res_perms_api_idx { + MOD_RES_PERM_RESOURCE_PERMS, + MOD_RES_PERM_API_IDX_COUNT, +}; + +/*! + * \brief Interfaces exposed by the resource permissions module. + */ +struct mod_res_permissions_api { + /*! + * \brief Check whether the agent has permission to access a protocol. + * + * \param agent_id identifier of the agent. + * \param protocol_id identifier of the protocol. + * + * \retval MOD_RES_PERMS_ACCESS_ALLOWED The agent has permissions to + * use the protocol. + * \retval MOD_RES_PERMS_ACCESS_DENIED The agent does not have + * permissions to use the protocol. + */ + enum mod_res_perms_permissions (*agent_has_protocol_permission)( + uint32_t agent_id, + uint32_t protocol_id); + + /*! + * \brief Check whether the agent has permission to access a message. + * + * \param agent_id identifier of the agent. + * \param protocol_id identifier of the protocol. + * \param message_id identifier of the message. + * + * \retval MOD_RES_PERMS_ACCESS_ALLOWED The agent has permissions to + * use the protocol. + * \retval MOD_RES_PERMS_ACCESS_DENIED The agent does not have + * permissions to use the message. + */ + enum mod_res_perms_permissions (*agent_has_message_permission)( + uint32_t agent_id, + uint32_t protocol_id, + uint32_t message_id); + + /*! + * \brief Check whether the agent has permission to access a resource. + * + * \param agent_id identifier of the agent. + * \param protocol_id identifier of the protocol. + * \param message_id identifier of the message. + * \param resource_id identifier of the resource. + * + * \retval MOD_RES_PERMS_ACCESS_ALLOWED The agent has permissions to + * use the protocol. + * \retval MOD_RES_PERMS_ACCESS_DENIED The agent does not have + * permissions to use the resource. + */ + enum mod_res_perms_permissions (*agent_has_resource_permission)( + uint32_t agent_id, + uint32_t protocol_id, + uint32_t message_id, + uint32_t resource_id); +}; + +/*! + * \brief Resource Permissions module configuration data. + * + * \note If the agent_permissions table is not set in the config then no + * resource permissions are implemented. + */ +struct mod_res_resource_perms_config { + /*! \brief Number of agents on the platform. */ + uint32_t agent_count; + + /*! \brief Number of SCMI protocols supported by the platform. */ + uint32_t protocol_count; + + /*! \brief Number of clocks supported by the platform. */ + uint32_t clock_count; + + /*! \brief Number of sensors supported by the platform. */ + uint32_t sensor_count; + + /*! \brief Number of power domains supported by the platform. */ + uint32_t pd_count; + + /*! \brief Number of performance domains supported by the platform. */ + uint32_t perf_count; + +#ifdef BUILD_HAS_SCMI_RESET + /*! \brief Number of performance domains supported by the platform. */ + uint32_t reset_domain_count; +#endif + + /*! \brief Address of the permissions table */ + uintptr_t agent_permissions; +}; + +/*! + * \defgroup GroupResPerms Mapping + * + * \brief Resource Permissions Identifier Mapping. + * + * \details The Resource Permissions Identifier Checkin and Mapping functions + * are weak definitions to allow a platform to implement a function + * for mapping agent IDs, SCMI protocol IDs and SCMI Message IDs + * appropriate to that platform. The permissons checking functions + * may also be implemented. The Resource Permissions Identifier + * Mapping/Checking functions may be overridden in the + * `product//src` directory. + * This may be useful for platforms with non-contiguous or + * platform-specific agent:protocol:command identifiers. + * + * \{ + */ + +/*! + * \brief Resource Permissions Map Agent ID to index. + * + * \details This function maps an Agent ID to an index in the + * resource permissions table. + * + * The Resource Permissions Mapping handlers have default + * weak implementations that allow a platform to implement + * a policy appropriate for that platform. + * + * \param[out] agent_idx Index for agent. + * \param[in] agent_id Identifier of the agent. + * + * \retval ::FWK_SUCCESS The operation succeeded. + * + * \return Status code representing the result of the operation. + */ +int mod_res_agent_id_to_index(uint32_t agent_id, uint32_t *agent_idx); + +/*! + * \brief Resource Permissions Map Protocol ID to index. + * + * \details This function maps an SCMI Protocol ID to an index in the + * resource permissions table. + * + * The Resource Permissions Mapping handlers have default + * weak implementations that allow a platform to implement + * a policy appropriate for that platform. + * + * \param[out] protocol_idx Index for protocol. + * \param[in] protocol_id Identifier of the Protocol. + * + * \retval ::FWK_SUCCESS The operation succeeded. + * + * \return Status code representing the result of the operation. + */ +int mod_res_plat_protocol_id_to_index( + uint32_t protocol_id, + uint32_t *protocol_idx); + +/*! + * \brief Resource Permissions Map Message ID to index. + * + * \details This function maps an SCMI Message ID to an index in the + * resource permissions table. + * + * The Resource Permissions Mapping handlers have default + * weak implementations that allow a platform to implement + * a policy appropriate for that platform. + * + * \param[out] message_idx Index for message. + * \param[in] protocol_id Identifier of the Protocol. + * \param[in] message_id Identifier of the Message. + * + * \retval ::FWK_SUCCESS The operation succeeded. + * + * \return Status code representing the result of the operation. + */ +int mod_res_plat_message_id_to_index( + uint32_t protocol_id, + uint32_t message_id, + int32_t *message_idx); + +/*! + * \brief Resource Permissions Map Resource ID to index. + * + * \details This function maps an SCMI Resource ID to an index in the + * resource permissions table. + * + * The Resource Permissions Mapping handlers have default + * weak implementations that allow a platform to implement + * a policy appropriate for that platform. + * + * \param[out] resource_idx Index for resource. + * \param[in] agent_id Identifier of the Agent. + * \param[in] protocol_id Identifier of the Protocol. + * \param[in] message_id Identifier of the Message. + * \param[in] resource_id Identifier of the Resource. + * + * \retval ::FWK_SUCCESS The operation succeeded. + * + * \return Status code representing the result of the operation. + */ +int mod_res_plat_resource_id_to_index( + uint32_t agent_id, + uint32_t protocol_id, + uint32_t message_id, + uint32_t resource_id, + int32_t *resource_idx); + +/*! + * \brief Check whether the agent has permission to access a protocol. + * + * \param agent_id identifier of the agent. + * \param protocol_id identifier of the protocol. + * + * \retval MOD_RES_PERMS_ACCESS_ALLOWED The agent has permissions to + * use the protocol. + * \retval MOD_RES_PERMS_ACCESS_DENIED The agent does not have + * permissions to use the protocol. + */ +enum mod_res_perms_permissions mod_res_plat_agent_protocol_permission( + uint32_t agent_id, + uint32_t protocol_id); + +/*! + * \brief Check whether the agent has permission to access a message. + * + * \param agent_id identifier of the agent. + * \param protocol_id identifier of the protocol. + * \param message_id identifier of the message. + * + * \retval MOD_RES_PERMS_ACCESS_ALLOWED The agent has permissions to + * use the protocol. + * \retval MOD_RES_PERMS_ACCESS_DENIED The agent does not have + * permissions to use the message. + */ +enum mod_res_perms_permissions mod_res_plat_agent_message_permission( + uint32_t agent_id, + uint32_t protocol_id, + uint32_t message_id); + +/*! + * \brief Check whether the agent has permission to access a resource. + * + * \param agent_id identifier of the agent. + * \param protocol_id identifier of the protocol. + * \param message_id identifier of the message. + * \param resource_id identifier of the resource. + * + * \retval MOD_RES_PERMS_ACCESS_ALLOWED The agent has permissions to + * use the protocol. + * \retval MOD_RES_PERMS_ACCESS_DENIED The agent does not have + * permissions to use the resource. + */ +enum mod_res_perms_permissions mod_res_plat_agent_resource_permissions( + uint32_t agent_id, + uint32_t protocol_id, + uint32_t message_id, + uint32_t resource_id); + +/*! + * \} + */ + +#endif /* MOD_SCMI_RESOURCE_PERMISSIONS_H */ diff --git a/module/resource_perms/src/Makefile b/module/resource_perms/src/Makefile new file mode 100644 index 000000000..3de189afc --- /dev/null +++ b/module/resource_perms/src/Makefile @@ -0,0 +1,11 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_LIB_NAME := resource_perms +BS_LIB_SOURCES := mod_resource_perms.c + +include $(BS_DIR)/lib.mk diff --git a/module/resource_perms/src/mod_resource_perms.c b/module/resource_perms/src/mod_resource_perms.c new file mode 100644 index 000000000..410f4d860 --- /dev/null +++ b/module/resource_perms/src/mod_resource_perms.c @@ -0,0 +1,709 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * System Control and Management Interface (SCMI) support + * resource management support. + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include + +struct res_perms_ctx { + /*! Number of agents for the platform. */ + uint32_t agent_count; + + /*! Number of protocols for the platform. */ + uint32_t protocol_count; + + /*! Number of clock resources for the platform. */ + uint32_t clock_count; + + /*! Number of sensor resources for the platform. */ + uint32_t sensor_count; + + /*! Number of power domain resources for the platform. */ + uint32_t pd_count; + + /*! Number of performance domain resources for the platform. */ + uint32_t perf_count; + +#ifdef BUILD_HAS_SCMI_RESET + /*! Number of reset domain resources for the platform. */ + uint32_t reset_domain_count; +#endif + + /*! + * The default is for an agent to have permission to access any + * resource. In order to deny permissions to an agent the table + * must be created and the relevant bit SET. If the table is not + * created then all agents have access to all resources. + * + * The agent_permissions table can be created in the SCMI config + * file. + * + * If the agent_permissions table was not set up in the config, + * the agent will not be able to allocate permissions at run-time. + * + * Note that if the agent wants to set permissions at run-time + * the agent_permissions[] tables must be allocated in writable + * memory. + */ + struct mod_res_agent_permission *agent_permissions; +}; + +static struct res_perms_ctx res_perms_ctx; + +/* + * Map the agent-id to the corresponding index in the table. + * + * Returns FWK_SUCCESS if the agent_id is valid for the platform. + * Returns FWK_E_PARAM if the agent_is id not valid for the platform. + * + * This is a weak definition to allow the platform override the function + * to deal with platform-specific agent mappings, eg, for non-sequential + * agent IDs or for sharing a single set of permissions between multiple + * agents, etc. + */ +__attribute((weak)) int mod_res_agent_id_to_index( + uint32_t agent_id, + uint32_t *agent_idx) +{ + uint32_t idx = agent_id - 1; + + if (idx < res_perms_ctx.agent_count) { + *agent_idx = idx; + return FWK_SUCCESS; + } + + return FWK_E_PARAM; +} + +/* + * Map the protocol-id to the corresponding index in the table. + * + * Returns true if the protocol_id is valid for the platform. + * Returns false if the protocol_is id not valid for the platform. + * + * This is a weak definition to allow the platform override the function + * to deal with platform-specific protocol mappings, eg, for non-contiguous + * protocol IDs. + */ +__attribute((weak)) int mod_res_plat_protocol_id_to_index( + uint32_t protocol_id, + uint32_t *protocol_idx) +{ + return FWK_E_PARAM; +} + +static int mod_res_protocol_id_to_index( + uint32_t protocol_id, + uint32_t *protocol_idx) +{ + if ((protocol_id >= MOD_SCMI_PLATFORM_PROTOCOL_ID_MIN) && + (protocol_id <= MOD_SCMI_PLATFORM_PROTOCOL_ID_MAX)) + return mod_res_plat_protocol_id_to_index(protocol_id, protocol_idx); + + switch (protocol_id) { + case MOD_SCMI_PROTOCOL_ID_BASE: + case MOD_SCMI_PROTOCOL_ID_POWER_DOMAIN: + case MOD_SCMI_PROTOCOL_ID_SYS_POWER: + case MOD_SCMI_PROTOCOL_ID_PERF: + case MOD_SCMI_PROTOCOL_ID_CLOCK: + case MOD_SCMI_PROTOCOL_ID_SENSOR: + case MOD_SCMI_PROTOCOL_ID_RESET_DOMAIN: + *protocol_idx = protocol_id - MOD_SCMI_PROTOCOL_ID_BASE; + return FWK_SUCCESS; + default: + return FWK_E_PARAM; + } +} + +/* + * Map the message-id to the corresponding index in the resources + * table. + * + * Returns FWK_SUCCESS if the message_id is valid for the protocol. + * Returns FWK_E_PARAM if the message_id not valid for the protocol. + * + * Contents of idx are only valid if >= 0. + * + * This is a weak definition to allow the platform override the function + * to deal with platform-specific message ID mappings, eg, for non-contiguous + * message IDs. + */ +__attribute((weak)) int mod_res_plat_message_id_to_index( + uint32_t protocol_id, + uint32_t message_id, + int32_t *message_idx) +{ + return FWK_E_PARAM; +} + +static int mod_res_message_id_to_index( + uint32_t protocol_id, + uint32_t message_id, + int32_t *message_idx) +{ + /* + * All protocols have + * + * 0: VERSION + * 1: ATTRIBUTES + * 2: MSG_ATTRIBUTES + * + * messages which are available to all agents. + * + * If the message is not managed in the permissions + * we return false and idx == -1. + */ + *message_idx = -1; + + if ((protocol_id >= MOD_SCMI_PLATFORM_PROTOCOL_ID_MIN) && + (protocol_id <= MOD_SCMI_PLATFORM_PROTOCOL_ID_MAX)) + return mod_res_message_id_to_index( + protocol_id, message_id, message_idx); + + if (message_id < 3) + return FWK_SUCCESS; + + switch (protocol_id) { + case MOD_SCMI_PROTOCOL_ID_BASE: + if (message_id >= MOD_SCMI_BASE_COMMAND_COUNT) + return FWK_E_PARAM; + if (message_id == MOD_SCMI_BASE_NOTIFY_ERRORS) + *message_idx = 0; + return FWK_SUCCESS; + + case MOD_SCMI_PROTOCOL_ID_POWER_DOMAIN: + if (message_id >= MOD_SCMI_PD_POWER_COMMAND_COUNT) + return FWK_E_PARAM; + if ((message_id >= MOD_SCMI_PD_POWER_DOMAIN_ATTRIBUTES) && + (message_id <= MOD_SCMI_PD_POWER_STATE_NOTIFY)) + *message_idx = message_id - MOD_SCMI_PD_POWER_DOMAIN_ATTRIBUTES; + return FWK_SUCCESS; + + case MOD_SCMI_PROTOCOL_ID_SYS_POWER: + if (message_id >= MOD_SCMI_SYS_POWER_COMMAND_COUNT) + return FWK_E_PARAM; + if ((message_id >= MOD_SCMI_SYS_POWER_STATE_SET) && + (message_id <= MOD_SCMI_SYS_POWER_STATE_NOTIFY)) + *message_idx = message_id - MOD_SCMI_SYS_POWER_STATE_SET; + return FWK_SUCCESS; + + case MOD_SCMI_PROTOCOL_ID_PERF: + if (message_id >= MOD_SCMI_PERF_COMMAND_COUNT) + return FWK_E_PARAM; + if ((message_id >= MOD_SCMI_PERF_DOMAIN_ATTRIBUTES) && + (message_id <= MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL)) + *message_idx = message_id - MOD_SCMI_PERF_DOMAIN_ATTRIBUTES; + return FWK_SUCCESS; + + case MOD_SCMI_PROTOCOL_ID_CLOCK: + if (message_id >= MOD_SCMI_CLOCK_COMMAND_COUNT) + return FWK_E_PARAM; + if ((message_id >= MOD_SCMI_CLOCK_ATTRIBUTES) && + (message_id <= MOD_SCMI_CLOCK_CONFIG_SET)) + *message_idx = message_id - MOD_SCMI_CLOCK_ATTRIBUTES; + return FWK_SUCCESS; + + case MOD_SCMI_PROTOCOL_ID_SENSOR: + if (message_id >= MOD_SCMI_SENSOR_COMMAND_COUNT) + return FWK_E_PARAM; + if ((message_id >= MOD_SCMI_SENSOR_DESCRIPTION_GET) && + (message_id <= MOD_SCMI_SENSOR_READING_GET)) + *message_idx = message_id - MOD_SCMI_SENSOR_DESCRIPTION_GET; + return FWK_SUCCESS; + + case MOD_SCMI_PROTOCOL_ID_RESET_DOMAIN: + if (message_id >= MOD_SCMI_RESET_COMMAND_COUNT) + return FWK_E_PARAM; + if ((message_id >= MOD_SCMI_RESET_DOMAIN_ATTRIBUTES) && + (message_id <= MOD_SCMI_RESET_NOTIFY)) + *message_idx = message_id - MOD_SCMI_RESET_DOMAIN_ATTRIBUTES; + return FWK_SUCCESS; + + default: + return FWK_E_PARAM; + } +} + +/* + * Map the resource-id to the corresponding element index in the resources + * table. + * + * Returns FWK_SUCCESS if the resource_id is valid for the protocol. + * Returns FWK_E_PARAM if the resource_id not valid for the protocol. + * + * Contents of resource_idx are only valid if >= 0. + * + * This is a weak definition to allow the platform override the function + * to deal with platform-specific ID mappings, eg, for non-contiguous + * IDs. + */ +__attribute((weak)) int mod_res_plat_resource_id_to_index( + uint32_t agent_id, + uint32_t protocol_id, + uint32_t message_id, + uint32_t resource_id, + int32_t *resource_idx) +{ + return FWK_E_PARAM; +} + +static int mod_res_resource_id_to_index( + uint32_t agent_id, + uint32_t protocol_id, + uint32_t message_id, + uint32_t resource_id, + int32_t *resource_idx) +{ + uint32_t agent_idx; + int message_count; + int message_offset; + int resource_size; + int status; + + /* + * All protocols have + * + * 0: VERSION + * 1: ATTRIBUTES + * 2: MSG_ATTRIBUTES + * + * messages which are available to all agents. + * + * If the message is not managed in the permissions + * we return false and idx == -1. + */ + *resource_idx = -1; + + if ((protocol_id >= MOD_SCMI_PLATFORM_PROTOCOL_ID_MIN) && + (protocol_id <= MOD_SCMI_PLATFORM_PROTOCOL_ID_MAX)) + return mod_res_plat_resource_id_to_index( + agent_id, protocol_id, message_id, resource_id, resource_idx); + + if (message_id < 3) + return FWK_SUCCESS; + + /* + * Each table is organised as + * + * agent[number_of_agents].commands[number_of_commands_for_protocol] + */ + + switch (protocol_id) { + case MOD_SCMI_PROTOCOL_ID_BASE: + /* No per-resource managemment for SCMI Base Protocol */ + return FWK_E_PARAM; + + case MOD_SCMI_PROTOCOL_ID_SYS_POWER: + /* No per-resource managemment for SCMI System Power Protocol */ + return FWK_E_PARAM; + + case MOD_SCMI_PROTOCOL_ID_POWER_DOMAIN: + if ((message_id >= MOD_SCMI_PD_POWER_DOMAIN_ATTRIBUTES) && + (message_id <= MOD_SCMI_PD_POWER_STATE_NOTIFY)) { + message_count = MOD_SCMI_PD_POWER_STATE_NOTIFY - + MOD_SCMI_PD_POWER_DOMAIN_ATTRIBUTES + 1; + message_offset = message_id - MOD_SCMI_PD_POWER_DOMAIN_ATTRIBUTES; + resource_size = res_perms_ctx.pd_count; + break; + } + return FWK_E_PARAM; + + case MOD_SCMI_PROTOCOL_ID_PERF: + if ((message_id >= MOD_SCMI_PERF_DOMAIN_ATTRIBUTES) && + (message_id <= MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL)) { + message_count = MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES + 1; + message_offset = message_id - MOD_SCMI_PERF_DOMAIN_ATTRIBUTES; + resource_size = res_perms_ctx.perf_count; + break; + } + return FWK_E_PARAM; + + case MOD_SCMI_PROTOCOL_ID_CLOCK: + if ((message_id >= MOD_SCMI_CLOCK_ATTRIBUTES) && + (message_id <= MOD_SCMI_CLOCK_CONFIG_SET)) { + message_count = + MOD_SCMI_CLOCK_CONFIG_SET - MOD_SCMI_CLOCK_ATTRIBUTES + 1; + message_offset = message_id - MOD_SCMI_CLOCK_ATTRIBUTES; + resource_size = res_perms_ctx.clock_count; + break; + } + return FWK_E_PARAM; + + case MOD_SCMI_PROTOCOL_ID_SENSOR: + if ((message_id >= MOD_SCMI_SENSOR_DESCRIPTION_GET) && + (message_id <= MOD_SCMI_SENSOR_READING_GET)) { + message_count = MOD_SCMI_SENSOR_READING_GET - + MOD_SCMI_SENSOR_DESCRIPTION_GET + 1; + message_offset = message_id - MOD_SCMI_SENSOR_DESCRIPTION_GET; + resource_size = res_perms_ctx.sensor_count; + break; + } + return FWK_E_PARAM; + +#ifdef BUILD_HAS_SCMI_RESET + case MOD_SCMI_PROTOCOL_ID_RESET_DOMAIN: + if ((message_id >= MOD_SCMI_RESET_DOMAIN_ATTRIBUTES) && + (message_id <= MOD_SCMI_RESET_NOTIFY)) { + message_count = + MOD_SCMI_RESET_NOTIFY - MOD_SCMI_RESET_DOMAIN_ATTRIBUTES + 1; + message_offset = message_id - MOD_SCMI_RESET_DOMAIN_ATTRIBUTES; + resource_size = res_perms_ctx.reset_domain_count; + break; + } + return FWK_E_PARAM; +#endif + + default: + return FWK_E_PARAM; + } + + status = mod_res_agent_id_to_index(agent_id, &agent_idx); + if ((status != FWK_SUCCESS) || (agent_idx >= res_perms_ctx.agent_count)) + return FWK_E_PARAM; + + resource_size = MOD_RES_PERMS_RESOURCE_ELEMENT(resource_size) + 1; + + /* + * message_count: the number of messages for the agent. + * resource_size: the number of resource elements per message type. + * message_offset: the offset of this message from message 0. + * + * [1]: &agent[agent_idx].message[0] + * [2]: &agent[agent_idx].message[message_id] + * [3]: &agent[agent_idx].message[message_id].resource[resource_id] + */ + *resource_idx = (agent_idx * message_count * resource_size) + /* [1] */ + (message_offset * resource_size) + /* [2] */ + MOD_RES_PERMS_RESOURCE_ELEMENT(resource_id); /* [3] */ + + return FWK_SUCCESS; +} + +/* + * Check whether an agent has access to a protocol. + * + * Note that we will always check the higher permissions levels + * when called, so + * + * protocol -> message -> resource + */ + +/* + * Check whether an agent has access to a protocol. + * + * Note that we will always check the higher permissions levels + * when called, so + * + * protocol -> message -> resource + */ +__attribute((weak)) enum mod_res_perms_permissions + mod_res_plat_agent_protocol_permissions( + uint32_t agent_id, + uint32_t protocol_id) +{ + return MOD_RES_PERMS_ACCESS_DENIED; +} + +static enum mod_res_perms_permissions agent_protocol_permissions( + uint32_t agent_id, + uint32_t protocol_id) +{ + uint32_t agent_idx; + uint32_t protocol_idx; + mod_res_perms_t perms; + int status; + + /* No Agent:Protocol permissions management */ + if ((agent_id == 0) || (res_perms_ctx.agent_permissions == NULL) || + (res_perms_ctx.agent_permissions->agent_protocol_permissions == NULL)) + return MOD_RES_PERMS_ACCESS_ALLOWED; + + if ((protocol_id >= MOD_SCMI_PLATFORM_PROTOCOL_ID_MIN) && + (protocol_id <= MOD_SCMI_PLATFORM_PROTOCOL_ID_MAX)) + return mod_res_plat_agent_protocol_permissions(agent_id, protocol_id); + + status = mod_res_agent_id_to_index(agent_id, &agent_idx); + if ((status != FWK_SUCCESS) || (agent_idx >= res_perms_ctx.agent_count)) + return MOD_RES_PERMS_ACCESS_DENIED; + + status = mod_res_protocol_id_to_index(protocol_id, &protocol_idx); + if ((status != FWK_SUCCESS) || + (protocol_idx >= res_perms_ctx.protocol_count)) + return MOD_RES_PERMS_ACCESS_DENIED; + + perms = + res_perms_ctx.agent_permissions->agent_protocol_permissions[agent_idx] + .protocols; + + /* Agent:Protocol access denied */ + if (perms & (1 << protocol_idx)) + return MOD_RES_PERMS_ACCESS_DENIED; + + return MOD_RES_PERMS_ACCESS_ALLOWED; +} + +/* + * Check whether an agent can access a protocol:message. + */ +__attribute((weak)) enum mod_res_perms_permissions + mod_res_plat_agent_message_permissions( + uint32_t agent_id, + uint32_t protocol_id, + uint32_t message_id) +{ + return MOD_RES_PERMS_ACCESS_DENIED; +} + +static enum mod_res_perms_permissions agent_message_permissions( + uint32_t agent_id, + uint32_t protocol_id, + uint32_t message_id) +{ + enum mod_res_perms_permissions protocol_perms; + uint32_t agent_idx; + uint32_t protocol_idx; + int32_t message_idx; + mod_res_perms_t perms; + int status; + + /* No permissions management */ + if ((agent_id == 0) || (res_perms_ctx.agent_permissions == NULL)) + return MOD_RES_PERMS_ACCESS_ALLOWED; + + if ((protocol_id >= MOD_SCMI_PLATFORM_PROTOCOL_ID_MIN) && + (protocol_id <= MOD_SCMI_PLATFORM_PROTOCOL_ID_MAX)) + return mod_res_plat_agent_message_permissions( + agent_id, protocol_id, message_id); + + /* Agent:Protocol access denied */ + protocol_perms = agent_protocol_permissions(agent_id, protocol_id); + if (protocol_perms == MOD_RES_PERMS_ACCESS_DENIED) + return MOD_RES_PERMS_ACCESS_DENIED; + + /* No Agent:Protocol:command permissions management */ + if (res_perms_ctx.agent_permissions->agent_msg_permissions == NULL) + return MOD_RES_PERMS_ACCESS_ALLOWED; + + status = mod_res_message_id_to_index(protocol_id, message_id, &message_idx); + if (status != FWK_SUCCESS) + return MOD_RES_PERMS_ACCESS_DENIED; + + if (message_idx < 0) + return MOD_RES_PERMS_ACCESS_ALLOWED; + + status = mod_res_agent_id_to_index(agent_id, &agent_idx); + if (status != FWK_SUCCESS) + return MOD_RES_PERMS_ACCESS_DENIED; + + status = mod_res_protocol_id_to_index(protocol_id, &protocol_idx); + if (status != FWK_SUCCESS) + return MOD_RES_PERMS_ACCESS_DENIED; + + perms = res_perms_ctx.agent_permissions->agent_msg_permissions[agent_idx] + .messages[protocol_idx]; + + /* Agent:Protocol:message access denied */ + if (perms & (1 << message_idx)) + return MOD_RES_PERMS_ACCESS_DENIED; + + return MOD_RES_PERMS_ACCESS_ALLOWED; +} + +/* + * Check the permissions for agent:protocol:message:resource. + * + * Note that BASE and SYSTEM_POWER protocols do not support + * resource-level permissions checking, these protocols are + * managed at the agent:protocol:message level. + */ +__attribute((weak)) enum mod_res_perms_permissions + mod_res_plat_agent_resource_permissions( + uint32_t agent_id, + uint32_t protocol_id, + uint32_t message_id, + uint32_t resource_id) +{ + return MOD_RES_PERMS_ACCESS_DENIED; +} + +static enum mod_res_perms_permissions agent_resource_permissions( + uint32_t agent_id, + uint32_t protocol_id, + uint32_t message_id, + uint32_t resource_id) +{ + enum mod_res_perms_permissions message_perms; + uint32_t agent_idx; + int32_t message_idx; + int32_t resource_idx; + mod_res_perms_t perms; + int status; + + /* No permissions management */ + if ((agent_id == 0) || (res_perms_ctx.agent_permissions == NULL)) + return MOD_RES_PERMS_ACCESS_ALLOWED; + + if ((protocol_id >= MOD_SCMI_PLATFORM_PROTOCOL_ID_MIN) && + (protocol_id <= MOD_SCMI_PLATFORM_PROTOCOL_ID_MAX)) + return mod_res_plat_agent_resource_permissions( + agent_id, protocol_id, message_id, resource_id); + + /* Agent:Protocol:command access denied */ + message_perms = + agent_message_permissions(agent_id, protocol_id, message_id); + if (message_perms == MOD_RES_PERMS_ACCESS_DENIED) + return MOD_RES_PERMS_ACCESS_DENIED; + + status = mod_res_message_id_to_index(protocol_id, message_id, &message_idx); + if (status != FWK_SUCCESS) + return MOD_RES_PERMS_ACCESS_DENIED; + if (message_idx < 0) + return MOD_RES_PERMS_ACCESS_ALLOWED; + + status = mod_res_agent_id_to_index(agent_id, &agent_idx); + if (status != FWK_SUCCESS) + return MOD_RES_PERMS_ACCESS_DENIED; + + status = mod_res_resource_id_to_index( + agent_id, protocol_id, message_id, resource_id, &resource_idx); + if (status != FWK_SUCCESS) + return MOD_RES_PERMS_ACCESS_DENIED; + if (resource_idx < 0) + return MOD_RES_PERMS_ACCESS_ALLOWED; + + switch (protocol_id) { + case MOD_SCMI_PROTOCOL_ID_BASE: + return MOD_RES_PERMS_ACCESS_DENIED; + + case MOD_SCMI_PROTOCOL_ID_POWER_DOMAIN: + if (res_perms_ctx.agent_permissions->scmi_pd_perms == NULL) + return MOD_RES_PERMS_ACCESS_ALLOWED; + if (resource_id >= res_perms_ctx.pd_count) + return MOD_RES_PERMS_ACCESS_DENIED; + perms = res_perms_ctx.agent_permissions->scmi_pd_perms[resource_idx]; + break; + + case MOD_SCMI_PROTOCOL_ID_SYS_POWER: + return MOD_RES_PERMS_ACCESS_DENIED; + + case MOD_SCMI_PROTOCOL_ID_PERF: + if (res_perms_ctx.agent_permissions->scmi_perf_perms == NULL) + return MOD_RES_PERMS_ACCESS_ALLOWED; + if (resource_id >= res_perms_ctx.perf_count) + return MOD_RES_PERMS_ACCESS_DENIED; + perms = res_perms_ctx.agent_permissions->scmi_perf_perms[resource_idx]; + break; + + case MOD_SCMI_PROTOCOL_ID_CLOCK: + if (res_perms_ctx.agent_permissions->scmi_clock_perms == NULL) + return MOD_RES_PERMS_ACCESS_ALLOWED; + if (resource_id >= res_perms_ctx.clock_count) + return MOD_RES_PERMS_ACCESS_DENIED; + perms = res_perms_ctx.agent_permissions->scmi_clock_perms[resource_idx]; + break; + + case MOD_SCMI_PROTOCOL_ID_SENSOR: + if (res_perms_ctx.agent_permissions->scmi_sensor_perms == NULL) + return MOD_RES_PERMS_ACCESS_ALLOWED; + if (resource_id >= res_perms_ctx.sensor_count) + return MOD_RES_PERMS_ACCESS_DENIED; + perms = + res_perms_ctx.agent_permissions->scmi_sensor_perms[resource_idx]; + break; + +#ifdef BUILD_HAS_SCMI_RESET + case MOD_SCMI_PROTOCOL_ID_RESET_DOMAIN: + if (res_perms_ctx.agent_permissions->scmi_reset_domain_perms == NULL) + return MOD_RES_PERMS_ACCESS_ALLOWED; + if (resource_id >= res_perms_ctx.reset_domain_count) + return MOD_RES_PERMS_ACCESS_DENIED; + perms = res_perms_ctx.agent_permissions + ->scmi_reset_domain_perms[resource_idx]; + break; +#endif + + default: + return MOD_RES_PERMS_ACCESS_DENIED; + } + + /* Agent:Protocol:message:resource access denied */ + if ((perms & (1 << (MOD_RES_PERMS_RESOURCE_BIT(resource_id))))) + return MOD_RES_PERMS_ACCESS_DENIED; + + return MOD_RES_PERMS_ACCESS_ALLOWED; +} + +static const struct mod_res_permissions_api res_perms_api = { + .agent_has_protocol_permission = agent_protocol_permissions, + .agent_has_message_permission = agent_message_permissions, + .agent_has_resource_permission = agent_resource_permissions, +}; + +/* + * Module Framework support + */ +static int mod_res_perms_process_bind_request( + fwk_id_t source_id, + fwk_id_t target_id, + fwk_id_t api_id, + const void **api) +{ + /* Only allow binding to the module */ + if (!fwk_id_is_equal(target_id, fwk_module_id_resource_perms)) + return FWK_E_PARAM; + + /* We don't do any permissions management */ + *api = &res_perms_api; + + return FWK_SUCCESS; +} + +static int mod_res_perms_resources_init( + fwk_id_t module_id, + unsigned int element_count, + const void *data) +{ + struct mod_res_resource_perms_config *config; + + config = (struct mod_res_resource_perms_config *)data; + if (config->agent_permissions != 0x0) { + res_perms_ctx.agent_permissions = + (struct mod_res_agent_permission *)config->agent_permissions; + res_perms_ctx.agent_count = config->agent_count; + res_perms_ctx.protocol_count = config->protocol_count; + res_perms_ctx.clock_count = config->clock_count; + res_perms_ctx.sensor_count = config->sensor_count; + res_perms_ctx.pd_count = config->pd_count; + res_perms_ctx.perf_count = config->perf_count; +#ifdef BUILD_HAS_SCMI_RESET + res_perms_ctx.reset_domain_count = config->reset_domain_count; +#endif + } + + return FWK_SUCCESS; +} + +/* Module description */ +const struct fwk_module module_resource_perms = { + .name = "RESOURCE_PERMS", + .type = FWK_MODULE_TYPE_SERVICE, + .init = mod_res_perms_resources_init, + .process_bind_request = mod_res_perms_process_bind_request, + .api_count = MOD_RES_PERM_API_IDX_COUNT, +}; diff --git a/module/scmi/include/mod_scmi_std.h b/module/scmi/include/mod_scmi_std.h index a44709d7d..3398e5fbc 100644 --- a/module/scmi/include/mod_scmi_std.h +++ b/module/scmi/include/mod_scmi_std.h @@ -37,6 +37,11 @@ /*! Maximum value of an SCMI protocol identifier */ #define MOD_SCMI_PROTOCOL_ID_MAX 0xFF +/*! Minimum Protocol ID reserved for vendor or platform-specific extensions */ +#define MOD_SCMI_PLATFORM_PROTOCOL_ID_MIN 0x80 +/*! Maximum Protocol ID reserved for vendor or platform-specific extensions */ +#define MOD_SCMI_PLATFORM_PROTOCOL_ID_MAX MOD_SCMI_PROTOCOL_ID_MAX + /*! * \brief SCMI error codes. */ @@ -183,6 +188,7 @@ enum scmi_reset_domain_command_id { MOD_SCMI_RESET_DOMAIN_ATTRIBUTES = 0x03, MOD_SCMI_RESET_REQUEST = 0x04, MOD_SCMI_RESET_NOTIFY = 0x05, + MOD_SCMI_RESET_COMMAND_COUNT, }; /*! diff --git a/tools/build_system/firmware.mk b/tools/build_system/firmware.mk index 048edc170..d9ab04c27 100644 --- a/tools/build_system/firmware.mk +++ b/tools/build_system/firmware.mk @@ -209,6 +209,12 @@ else BUILD_HAS_FAST_CHANNELS := no endif +ifeq ($(BS_FIRMWARE_HAS_RESOURCE_PERMISSIONS),yes) + BUILD_HAS_RESOURCE_PERMISSIONS := yes +else + BUILD_HAS_RESOURCE_PERMISSIONS := no +endif + ifeq ($(BS_FIRMWARE_HAS_SCMI_NOTIFICATIONS),yes) BUILD_HAS_SCMI_NOTIFICATIONS := yes else diff --git a/tools/build_system/rules.mk b/tools/build_system/rules.mk index bdbed7399..b19b34ea1 100644 --- a/tools/build_system/rules.mk +++ b/tools/build_system/rules.mk @@ -41,6 +41,10 @@ ifeq ($(BUILD_HAS_STATISTICS),yes) DEFINES += BUILD_HAS_STATISTICS endif +ifeq ($(BUILD_HAS_RESOURCE_PERMISSIONS),yes) + DEFINES += BUILD_HAS_RESOURCE_PERMISSIONS +endif + export AS := $(CC) export LD := $(CC) -- GitLab From cfd168697f4e8e95d879931052cde9e7364d4d9d Mon Sep 17 00:00:00 2001 From: Jim Quigley Date: Wed, 17 Jun 2020 16:12:49 +0100 Subject: [PATCH 2/9] juno: Resource Permissions module build Enable Resource Permissions for Juno. Change-Id: Ib6744a20506ea262a530a9f1ef3f32cf46275c28 Signed-off-by: Jim Quigley --- .../juno/scp_ramfw/config_resource_perms.c | 105 ++++++++++++++++++ product/juno/scp_ramfw/firmware.mk | 9 ++ 2 files changed, 114 insertions(+) create mode 100644 product/juno/scp_ramfw/config_resource_perms.c diff --git a/product/juno/scp_ramfw/config_resource_perms.c b/product/juno/scp_ramfw/config_resource_perms.c new file mode 100644 index 000000000..6a4d7fcf1 --- /dev/null +++ b/product/juno/scp_ramfw/config_resource_perms.c @@ -0,0 +1,105 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config_dvfs.h" +#include "config_power_domain.h" +#include "config_sensor.h" +#include "juno_clock.h" +#include "juno_scmi.h" + +#include +#include + +#include +#include +#include +#include +#include + +/*! + * If the agent wants to modify permissions at run-time these tables + * must be allocated in wrtiable memory. + */ + +/*! + * Agent 0 gets access to all resources. + */ +#define AGENT_IDX(agent_id) (agent_id - 1) + +/*! + * Note that permissions are denied when a bit is set, the + * permissions tables are being added for Juno as an example only. + */ +static struct mod_res_agent_protocol_permissions + agent_protocol_permissions[] = { + [AGENT_IDX(JUNO_SCMI_AGENT_IDX_OSPM)] = { + .protocols = MOD_RES_PERMS_SCMI_ALL_PROTOCOLS_ALLOWED, + }, + [AGENT_IDX(JUNO_SCMI_AGENT_IDX_PSCI)] = { + .protocols = MOD_RES_PERMS_SCMI_ALL_PROTOCOLS_ALLOWED, + }, +}; + +/* + * Messages have an index offset from 0x3 as all agents can access + * the VERSION/ATTRIBUTES/MSG_ATTRIBUTES messages for all + * protocols, hence message 0x3 maps to bit[0], message 0x4 maps + * to bit[1], etc. + */ +static struct mod_res_agent_msg_permissions agent_msg_permissions[] = { + [AGENT_IDX(JUNO_SCMI_AGENT_IDX_OSPM)] = { + /* Example, Base, disable unused msg 12 */ + .messages[MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX] = + (1 << 12), /* Example, Base, disable unused msg 12 */ + /* Power Domain */ + .messages[MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0, + /* System Power Domain */ + .messages[MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0, + /* Performance */ + .messages[MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = 0x0, + /* Clocks */ + .messages[MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = 0x0, + /* Sensors */ + .messages[MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0, + /* Reset Domains */ + .messages[MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0, + }, + [AGENT_IDX(JUNO_SCMI_AGENT_IDX_PSCI)] = { + .messages[MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0, + }, +}; + +/* + * Protocols have an index offset from SCMI_BASE protocol, 0x10 + * Note that the BASE and SYSTEM_POWER protocols are managed + * on a protocol:command basis, there is no resource permissions + * associated with the protocols. + */ + +static struct mod_res_agent_permission agent_permissions = { + .agent_protocol_permissions = agent_protocol_permissions, + .agent_msg_permissions = agent_msg_permissions, +}; + +struct fwk_module_config config_resource_perms = { + .data = + &(struct mod_res_resource_perms_config){ + .agent_permissions = (uintptr_t)&agent_permissions, + .agent_count = JUNO_SCMI_AGENT_IDX_COUNT, + .protocol_count = 7, + .clock_count = JUNO_CLOCK_IDX_COUNT, + .sensor_count = MOD_JUNO_R0_SENSOR_IDX_COUNT, + .pd_count = POWER_DOMAIN_IDX_COUNT, + .perf_count = DVFS_ELEMENT_IDX_COUNT, + }, +}; diff --git a/product/juno/scp_ramfw/firmware.mk b/product/juno/scp_ramfw/firmware.mk index bb2ac1f91..21ff4f16e 100644 --- a/product/juno/scp_ramfw/firmware.mk +++ b/product/juno/scp_ramfw/firmware.mk @@ -13,6 +13,7 @@ BS_FIRMWARE_HAS_MULTITHREADING := no BS_FIRMWARE_HAS_NOTIFICATION := yes BS_FIRMWARE_HAS_SCMI_NOTIFICATIONS := no BS_FIRMWARE_HAS_FAST_CHANNELS := no +BS_FIRMWARE_HAS_RESOURCE_PERMISSIONS := yes BS_FIRMWARE_HAS_DEBUG_UNIT := yes BS_FIRMWARE_HAS_SCMI_RESET := no BS_FIRMWARE_HAS_STATISTICS := no @@ -64,6 +65,10 @@ ifeq ($(BS_FIRMWARE_HAS_SCMI_RESET),yes) BS_FIRMWARE_MODULES += reset_domain scmi_reset_domain juno_reset_domain endif +ifeq ($(BS_FIRMWARE_HAS_RESOURCE_PERMISSIONS),yes) + BS_FIRMWARE_MODULES += resource_perms +endif + BS_FIRMWARE_SOURCES := \ juno_utils.c \ config_sds.c \ @@ -118,4 +123,8 @@ ifeq ($(BS_FIRMWARE_HAS_STATISTICS),yes) BS_FIRMWARE_SOURCES += config_stats.c endif +ifeq ($(BS_FIRMWARE_HAS_RESOURCE_PERMISSIONS),yes) + BS_FIRMWARE_SOURCES += config_resource_perms.c +endif + include $(BS_DIR)/firmware.mk -- GitLab From 4b9299c4ff888b84d3ac45e44bc587eccb56d2e4 Mon Sep 17 00:00:00 2001 From: Jim Quigley Date: Tue, 16 Jun 2020 16:08:01 +0100 Subject: [PATCH 3/9] SCMI: Base Protocol Permissions This patch adds the SCMI Base Protocol Resource Permissions management. Change-Id: If05eb65633ae803a4a561c9d1a17b0a81f78d89c Signed-off-by: Jim Quigley --- module/scmi/src/mod_scmi.c | 59 +++++++++++++++++++ .../juno/scp_ramfw/config_resource_perms.c | 7 ++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/module/scmi/src/mod_scmi.c b/module/scmi/src/mod_scmi.c index 10f2319f5..6f382ee19 100644 --- a/module/scmi/src/mod_scmi.c +++ b/module/scmi/src/mod_scmi.c @@ -12,6 +12,9 @@ #include #include +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS +# include +#endif #include #include @@ -60,6 +63,11 @@ struct scmi_ctx { /* Table of service contexts */ struct scmi_service_ctx *service_ctx_table; + +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + /* SCMI Resource Permissions API */ + const struct mod_res_permissions_api *res_perms_api; +#endif }; /* @@ -630,6 +638,40 @@ exit: return FWK_SUCCESS; } +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS +/* + * SCMI Resource Permissions handler + */ +static int scmi_base_permissions_handler( + fwk_id_t service_id, + const uint32_t *payload, + size_t payload_size, + unsigned int message_id) +{ + enum mod_res_perms_permissions perms; + unsigned int agent_id; + int status; + + status = get_agent_id(service_id, &agent_id); + if (status != FWK_SUCCESS) + return FWK_E_ACCESS; + + if (message_id < 3) + return FWK_SUCCESS; + + /* + * Check that the agent has permissions to access the message. + */ + perms = scmi_ctx.res_perms_api->agent_has_message_permission( + agent_id, MOD_SCMI_PROTOCOL_ID_BASE, message_id); + + if (perms == MOD_RES_PERMS_ACCESS_ALLOWED) + return FWK_SUCCESS; + else + return FWK_E_ACCESS; +} +#endif + static int scmi_base_message_handler(fwk_id_t protocol_id, fwk_id_t service_id, const uint32_t *payload, size_t payload_size, unsigned int message_id) { @@ -650,6 +692,14 @@ static int scmi_base_message_handler(fwk_id_t protocol_id, fwk_id_t service_id, goto error; } +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + if (scmi_base_permissions_handler( + service_id, payload, payload_size, message_id) != FWK_SUCCESS) { + return_value = SCMI_DENIED; + goto error; + } +#endif + return base_handler_table[message_id](service_id, payload); error: @@ -790,6 +840,15 @@ static int scmi_bind(fwk_id_t id, unsigned int round) protocol->message_handler = protocol_api->message_handler; } +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + status = fwk_module_bind( + FWK_ID_MODULE(FWK_MODULE_IDX_RESOURCE_PERMS), + FWK_ID_API(FWK_MODULE_IDX_RESOURCE_PERMS, MOD_RES_PERM_RESOURCE_PERMS), + &scmi_ctx.res_perms_api); + if (status != FWK_SUCCESS) + return status; +#endif + return FWK_SUCCESS; } diff --git a/product/juno/scp_ramfw/config_resource_perms.c b/product/juno/scp_ramfw/config_resource_perms.c index 6a4d7fcf1..172d62946 100644 --- a/product/juno/scp_ramfw/config_resource_perms.c +++ b/product/juno/scp_ramfw/config_resource_perms.c @@ -39,8 +39,10 @@ static struct mod_res_agent_protocol_permissions [AGENT_IDX(JUNO_SCMI_AGENT_IDX_OSPM)] = { .protocols = MOD_RES_PERMS_SCMI_ALL_PROTOCOLS_ALLOWED, }, + + /* PSCI agent has no access to clock protocol */ [AGENT_IDX(JUNO_SCMI_AGENT_IDX_PSCI)] = { - .protocols = MOD_RES_PERMS_SCMI_ALL_PROTOCOLS_ALLOWED, + .protocols = MOD_RES_PERMS_SCMI_CLOCK_PROTOCOL_DENIED, }, }; @@ -73,7 +75,8 @@ static struct mod_res_agent_msg_permissions agent_msg_permissions[] = { .messages[MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0, .messages[MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0, .messages[MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = 0x0, - .messages[MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = 0x0, + /* Clocks, no access */ + .messages[MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = 0xff, .messages[MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0, .messages[MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0, }, -- GitLab From a17cfbfd76cee92bcec69b6c203b01ee891ceba0 Mon Sep 17 00:00:00 2001 From: Jim Quigley Date: Tue, 16 Jun 2020 16:08:59 +0100 Subject: [PATCH 4/9] SCMI: Clock Protocol Permissions This patch adds the SCMI Clock Protocol Resource Permissions management. Change-Id: Ie636c4317e65f17b53f5ba3f5ba7eba2c405a203 Signed-off-by: Jim Quigley --- .../include/mod_resource_perms.h | 21 +++ module/scmi_clock/include/mod_scmi_clock.h | 3 - module/scmi_clock/src/mod_scmi_clock.c | 150 +++++++++--------- .../juno/scp_ramfw/config_resource_perms.c | 44 +++++ product/juno/scp_ramfw/config_scmi_clock.c | 21 --- .../sgm775/scp_ramfw/config_resource_perms.c | 79 +++++++++ product/sgm775/scp_ramfw/config_scmi_clock.c | 16 -- product/sgm775/scp_ramfw/firmware.mk | 9 ++ .../sgm776/scp_ramfw/config_resource_perms.c | 79 +++++++++ product/sgm776/scp_ramfw/config_scmi_clock.c | 16 -- product/sgm776/scp_ramfw/firmware.mk | 8 + product/tc0/scp_ramfw/config_resource_perms.c | 79 +++++++++ product/tc0/scp_ramfw/config_scmi_clock.c | 14 -- product/tc0/scp_ramfw/firmware.mk | 9 ++ 14 files changed, 405 insertions(+), 143 deletions(-) create mode 100644 product/sgm775/scp_ramfw/config_resource_perms.c create mode 100644 product/sgm776/scp_ramfw/config_resource_perms.c create mode 100644 product/tc0/scp_ramfw/config_resource_perms.c diff --git a/module/resource_perms/include/mod_resource_perms.h b/module/resource_perms/include/mod_resource_perms.h index b76271572..bf5ba1c2b 100644 --- a/module/resource_perms/include/mod_resource_perms.h +++ b/module/resource_perms/include/mod_resource_perms.h @@ -157,6 +157,27 @@ struct mod_res_agent_msg_permissions { * */ +/*! + * \brief SCMI Clock Protocol Message index offset + */ +#define MOD_RES_PERMS_CLOCK_PERMS_OFFSET MOD_SCMI_CLOCK_ATTRIBUTES + +/*! + * \brief SCMI Clock Protocol Message Indices + */ +enum mod_res_clock_permissions_idx { + MOD_RES_PERMS_SCMI_CLOCK_ATTRIBUTES_IDX = + MOD_SCMI_CLOCK_ATTRIBUTES - MOD_RES_PERMS_CLOCK_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_CLOCK_DESCRIBE_RATE_IDX = + MOD_SCMI_CLOCK_DESCRIBE_RATES - MOD_RES_PERMS_CLOCK_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_CLOCK_RATE_SET_IDX = + MOD_SCMI_CLOCK_RATE_SET - MOD_RES_PERMS_CLOCK_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_CLOCK_RATE_GET_IDX = + MOD_SCMI_CLOCK_RATE_GET - MOD_RES_PERMS_CLOCK_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_CLOCK_CONFIG_SET_IDX = + MOD_SCMI_CLOCK_CONFIG_SET - MOD_RES_PERMS_CLOCK_PERMS_OFFSET, +}; + /*! * \brief SCMI Agent Permissions * diff --git a/module/scmi_clock/include/mod_scmi_clock.h b/module/scmi_clock/include/mod_scmi_clock.h index 7b482c0c5..8249db0c1 100644 --- a/module/scmi_clock/include/mod_scmi_clock.h +++ b/module/scmi_clock/include/mod_scmi_clock.h @@ -69,9 +69,6 @@ struct mod_scmi_clock_device { * that is defined by the \c clock module. */ fwk_id_t element_id; - - /*! Mask of permission flags defined by \ref mod_scmi_clock_permissions */ - uint8_t permissions; }; /*! diff --git a/module/scmi_clock/src/mod_scmi_clock.c b/module/scmi_clock/src/mod_scmi_clock.c index 7adfb56e9..a8c477add 100644 --- a/module/scmi_clock/src/mod_scmi_clock.c +++ b/module/scmi_clock/src/mod_scmi_clock.c @@ -28,6 +28,10 @@ #include #include +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS +# include +#endif + struct clock_operations { /* * Service identifier currently requesting operation from this clock. @@ -60,6 +64,11 @@ struct scmi_clock_ctx { /* Pointer to a table of clock operations */ struct clock_operations *clock_ops; + +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + /* SCMI Resource Permissions API */ + const struct mod_res_permissions_api *res_perms_api; +#endif }; static const fwk_id_t mod_scmi_clock_event_id_get_state = @@ -181,7 +190,6 @@ static int get_clock_device_entry( *clock_device = &agent_entry->device_table[clock_idx]; - fwk_assert((*clock_device)->permissions != MOD_SCMI_CLOCK_PERM_INVALID); fwk_assert(fwk_module_is_valid_element_id((*clock_device)->element_id)); if (agent != NULL) @@ -256,23 +264,6 @@ static int set_agent_clock_state( return FWK_SUCCESS; } -/* - * Query the permissions for a service making a request to determine if - * the operation is permitted on the given clock device. - */ -static int check_service_permission( - const struct mod_scmi_clock_device *device, - enum mod_scmi_clock_permissions requested_permission, - bool *granted) -{ - if (granted == NULL) - return FWK_E_PARAM; - - *granted = device->permissions & requested_permission; - - return FWK_SUCCESS; -} - /* * Helper for clock operations */ @@ -515,6 +506,55 @@ __attribute((weak)) int mod_scmi_clock_config_set_policy( return FWK_SUCCESS; } +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + +/* + * SCMI Resource Permissions handler + */ +static unsigned int get_clock_id(const uint32_t *payload) +{ + /* + * Every SCMI Clock message is formatted with the clock ID + * as the first message element. We will use the clock_attributes + * message as a basic format to retrieve the clock ID to avoid + * unnecessary code. + */ + const struct scmi_clock_attributes_a2p *parameters = + (const struct scmi_clock_attributes_a2p *)payload; + + return parameters->clock_id; +} + +static int scmi_clock_permissions_handler( + fwk_id_t service_id, + const uint32_t *payload, + size_t payload_size, + unsigned int message_id) +{ + enum mod_res_perms_permissions perms; + unsigned int agent_id, clock_id; + int status; + + status = scmi_clock_ctx.scmi_api->get_agent_id(service_id, &agent_id); + if (status != FWK_SUCCESS) + return FWK_E_ACCESS; + + if (message_id < 3) + return FWK_SUCCESS; + + clock_id = get_clock_id(payload); + + perms = scmi_clock_ctx.res_perms_api->agent_has_resource_permission( + agent_id, MOD_SCMI_PROTOCOL_ID_CLOCK, message_id, clock_id); + + if (perms == MOD_RES_PERMS_ACCESS_ALLOWED) + return FWK_SUCCESS; + else + return FWK_E_ACCESS; +} + +#endif + /* * Helper to create events for processing pending requests */ @@ -674,7 +714,6 @@ static int scmi_clock_attributes_handler(fwk_id_t service_id, int status; const struct mod_scmi_clock_agent *agent; const struct mod_scmi_clock_device *clock_device; - bool service_permission_granted; size_t response_size; const struct scmi_clock_attributes_a2p *parameters; struct scmi_clock_attributes_p2a return_values = { @@ -692,16 +731,6 @@ static int scmi_clock_attributes_handler(fwk_id_t service_id, goto exit; } - status = check_service_permission(clock_device, - MOD_SCMI_CLOCK_PERM_ATTRIBUTES, &service_permission_granted); - if (status != FWK_SUCCESS) - goto exit; - - if (!service_permission_granted) { - return_values.status = SCMI_DENIED; - goto exit; - } - status = create_event_request(clock_device->element_id, service_id, SCMI_CLOCK_REQUEST_GET_STATE, @@ -733,7 +762,6 @@ static int scmi_clock_rate_get_handler(fwk_id_t service_id, int status; const struct mod_scmi_clock_agent *agent; const struct mod_scmi_clock_device *clock_device; - bool service_permission_granted; size_t response_size; const struct scmi_clock_rate_get_a2p *parameters; struct scmi_clock_rate_get_p2a return_values = { @@ -751,16 +779,6 @@ static int scmi_clock_rate_get_handler(fwk_id_t service_id, goto exit; } - status = check_service_permission(clock_device, - MOD_SCMI_CLOCK_PERM_GET_RATE, &service_permission_granted); - if (status != FWK_SUCCESS) - goto exit; - - if (!service_permission_granted) { - return_values.status = SCMI_NOT_SUPPORTED; - goto exit; - } - status = create_event_request(clock_device->element_id, service_id, SCMI_CLOCK_REQUEST_GET_RATE, @@ -792,7 +810,6 @@ static int scmi_clock_rate_set_handler(fwk_id_t service_id, int status; const struct mod_scmi_clock_agent *agent; const struct mod_scmi_clock_device *clock_device; - bool service_permission_granted; bool round_auto; bool round_up; bool asynchronous; @@ -820,16 +837,6 @@ static int scmi_clock_rate_set_handler(fwk_id_t service_id, goto exit; } - status = check_service_permission(clock_device, - MOD_SCMI_CLOCK_PERM_SET_RATE, &service_permission_granted); - if (status != FWK_SUCCESS) - goto exit; - - if (!service_permission_granted) { - return_values.status = SCMI_NOT_SUPPORTED; - goto exit; - } - if (asynchronous) { /* Support for async clock set commands not yet implemented */ return_values.status = SCMI_NOT_SUPPORTED; @@ -897,7 +904,6 @@ static int scmi_clock_config_set_handler(fwk_id_t service_id, { int status; bool enable; - bool service_permission_granted; size_t response_size; const struct scmi_clock_config_set_a2p *parameters; const struct mod_scmi_clock_agent *agent; @@ -920,16 +926,6 @@ static int scmi_clock_config_set_handler(fwk_id_t service_id, goto exit; } - status = check_service_permission(clock_device, - MOD_SCMI_CLOCK_PERM_SET_CONFIG, &service_permission_granted); - if (status != FWK_SUCCESS) - goto exit; - - if (!service_permission_granted) { - return_values.status = SCMI_NOT_SUPPORTED; - goto exit; - } - struct event_set_state_request_data data = { .state = enable ? MOD_CLOCK_STATE_RUNNING : MOD_CLOCK_STATE_STOPPED }; @@ -983,7 +979,6 @@ static int scmi_clock_describe_rates_handler(fwk_id_t service_id, int status; const struct mod_scmi_clock_agent *agent; const struct mod_scmi_clock_device *clock_device; - bool service_permission_granted; unsigned int i; size_t max_payload_size; uint32_t payload_size; @@ -1012,16 +1007,6 @@ static int scmi_clock_describe_rates_handler(fwk_id_t service_id, goto exit; } - status = check_service_permission(clock_device, - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES, &service_permission_granted); - if (status != FWK_SUCCESS) - goto exit; - - if (!service_permission_granted) { - return_values.status = SCMI_NOT_SUPPORTED; - goto exit; - } - /* * Get the maximum payload size to determine how many clock rate entries can * be returned in one response. @@ -1154,6 +1139,7 @@ static int scmi_clock_message_handler(fwk_id_t protocol_id, fwk_id_t service_id, const uint32_t *payload, size_t payload_size, unsigned int message_id) { int32_t return_value; + int status; static_assert(FWK_ARRAY_SIZE(handler_table) == FWK_ARRAY_SIZE(payload_size_table), @@ -1170,6 +1156,15 @@ static int scmi_clock_message_handler(fwk_id_t protocol_id, fwk_id_t service_id, goto error; } +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + status = scmi_clock_permissions_handler( + service_id, payload, payload_size, message_id); + if (status != FWK_SUCCESS) { + return_value = SCMI_DENIED; + goto error; + } +#endif + return handler_table[message_id](service_id, payload); error: @@ -1232,6 +1227,15 @@ static int scmi_clock_bind(fwk_id_t id, unsigned int round) if (status != FWK_SUCCESS) return status; +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + status = fwk_module_bind( + FWK_ID_MODULE(FWK_MODULE_IDX_RESOURCE_PERMS), + FWK_ID_API(FWK_MODULE_IDX_RESOURCE_PERMS, MOD_RES_PERM_RESOURCE_PERMS), + &scmi_clock_ctx.res_perms_api); + if (status != FWK_SUCCESS) + return status; +#endif + return fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_CLOCK), FWK_ID_API(FWK_MODULE_IDX_CLOCK, 0), &scmi_clock_ctx.clock_api); } diff --git a/product/juno/scp_ramfw/config_resource_perms.c b/product/juno/scp_ramfw/config_resource_perms.c index 172d62946..0bdb3eb21 100644 --- a/product/juno/scp_ramfw/config_resource_perms.c +++ b/product/juno/scp_ramfw/config_resource_perms.c @@ -89,9 +89,53 @@ static struct mod_res_agent_msg_permissions agent_msg_permissions[] = { * associated with the protocols. */ +/* + * We are tracking 5 SCMI Clock Protocol commands + * + * 0, SCMI_CLOCK_ATTRIBUTES + * 1, SCMI_CLOCK_RATE_GET + * 2, SCMI_CLOCK_RATE_SET + * 3, SCMI_CLOCK_CONFIG_SET + * 4, SCMI_CLOCK_DESCRIBE_RATES + */ +#define JUNO_CLOCK_RESOURCE_CMDS 5 +#define JUNO_CLOCK_RESOURCE_ELEMENTS \ + ((JUNO_CLOCK_IDX_COUNT >> MOD_RES_PERMS_TYPE_SHIFT) + 1) +static mod_res_perms_t scmi_clock_perms[] + [JUNO_CLOCK_RESOURCE_CMDS][JUNO_CLOCK_RESOURCE_ELEMENTS] = { + /* SCMI_PROTOCOL_ID_CLOCK */ + /* 0, SCMI_CLOCK_ATTRIBUTES */ + /* 1, SCMI_CLOCK_RATE_GET */ + /* 2, SCMI_CLOCK_RATE_SET */ + /* 3, SCMI_CLOCK_CONFIG_SET */ + /* 4, SCMI_CLOCK_DESCRIBE_RATES */ + [AGENT_IDX(JUNO_SCMI_AGENT_IDX_OSPM)] = { + [MOD_RES_PERMS_SCMI_CLOCK_ATTRIBUTES_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_CLOCK_DESCRIBE_RATE_IDX][0] = 0x0, + /* + * Clocks 0, 1, 2, 4 do not allow set commands, + * Clocks 3 and 5 allow rate_set/config_set + */ + [MOD_RES_PERMS_SCMI_CLOCK_RATE_SET_IDX][0] = + ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)), + [MOD_RES_PERMS_SCMI_CLOCK_RATE_GET_IDX][0] = + ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)), + [MOD_RES_PERMS_SCMI_CLOCK_CONFIG_SET_IDX][0] = 0x0, + }, + [AGENT_IDX(JUNO_SCMI_AGENT_IDX_PSCI)] = { + /* No access to clocks for PSCI agent, so bits [4:0] set */ + [MOD_RES_PERMS_SCMI_CLOCK_ATTRIBUTES_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_DESCRIBE_RATE_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_RATE_SET_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_RATE_GET_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_CONFIG_SET_IDX][0] = 0x1f, + }, +}; + static struct mod_res_agent_permission agent_permissions = { .agent_protocol_permissions = agent_protocol_permissions, .agent_msg_permissions = agent_msg_permissions, + .scmi_clock_perms = &scmi_clock_perms[0][0][0], }; struct fwk_module_config config_resource_perms = { diff --git a/product/juno/scp_ramfw/config_scmi_clock.c b/product/juno/scp_ramfw/config_scmi_clock.c index 95a3759bc..4141247a3 100644 --- a/product/juno/scp_ramfw/config_scmi_clock.c +++ b/product/juno/scp_ramfw/config_scmi_clock.c @@ -20,52 +20,31 @@ static const struct mod_scmi_clock_device agent_device_table_ospm[] = { /* Big */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, JUNO_CLOCK_IDX_BIGCLK), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | - MOD_SCMI_CLOCK_PERM_GET_RATE, }, { /* Little */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, JUNO_CLOCK_IDX_LITTLECLK), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | - MOD_SCMI_CLOCK_PERM_GET_RATE, }, { /* GPU */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, JUNO_CLOCK_IDX_GPUCLK), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | - MOD_SCMI_CLOCK_PERM_GET_RATE, }, { /* HDLCD0 */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, JUNO_CLOCK_IDX_HDLCD0), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | - MOD_SCMI_CLOCK_PERM_GET_RATE | - MOD_SCMI_CLOCK_PERM_SET_RATE | - MOD_SCMI_CLOCK_PERM_SET_CONFIG, }, { /* HDLCD1 */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, JUNO_CLOCK_IDX_HDLCD1), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES, }, { /* I2S */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, JUNO_CLOCK_IDX_I2SCLK), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | - MOD_SCMI_CLOCK_PERM_GET_RATE | - MOD_SCMI_CLOCK_PERM_SET_RATE | - MOD_SCMI_CLOCK_PERM_SET_CONFIG, }, }; diff --git a/product/sgm775/scp_ramfw/config_resource_perms.c b/product/sgm775/scp_ramfw/config_resource_perms.c new file mode 100644 index 000000000..1618e989a --- /dev/null +++ b/product/sgm775/scp_ramfw/config_resource_perms.c @@ -0,0 +1,79 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "sgm775_scmi.h" + +#include +#include + +#include +#include +#include +#include +#include + +/*! + * If the agent wants to modify permissions at run-time these tables + * must be allocated in writable memory. + */ + +#define AGENT_IDX(agent_id) (agent_id - 1) + +static struct mod_res_agent_protocol_permissions + agent_protocol_permissions[] = { + [AGENT_IDX(SCMI_AGENT_ID_OSPM)] = { + .protocols = MOD_RES_PERMS_SCMI_ALL_PROTOCOLS_ALLOWED, + }, + + /* PSCI agent has no access to clock protocol */ + [AGENT_IDX(SCMI_AGENT_ID_PSCI)] = { + .protocols = MOD_RES_PERMS_SCMI_CLOCK_PROTOCOL_DENIED, + }, +}; + +/* + * Messages have an index offset from 0x3 as all agents can access + * the VERSION/ATTRIBUTES/MSG_ATTRIBUTES messages for all + * protocols, hence message 0x3 maps to bit[0], message 0x4 maps + * to bit[1], etc. + */ +static struct mod_res_agent_msg_permissions agent_msg_permissions[] = { + [AGENT_IDX(SCMI_AGENT_ID_OSPM)] = { + /* Example, Base, disable unused msg 12 */ + .messages[MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX] = 0x0, + /* Power Domain */ + .messages[MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0, + /* System Power Domain */ + .messages[MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0, + /* Performance */ + .messages[MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = 0x0, + /* + * sgm775 denies access to CONFIG_SET + */ + .messages[MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = + MOD_RES_PERMS_ACCESS_DENIED << + (MOD_SCMI_CLOCK_CONFIG_SET - MOD_SCMI_CLOCK_ATTRIBUTES), + /* Sensors */ + .messages[MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0, + /* Reset Domains */ + .messages[MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0, + }, +}; + +static struct mod_res_agent_permission agent_permissions = { + .agent_protocol_permissions = agent_protocol_permissions, + .agent_msg_permissions = agent_msg_permissions, +}; + +struct fwk_module_config config_resource_perms = { + .data = + &(struct mod_res_resource_perms_config){ + .agent_permissions = (uintptr_t)&agent_permissions, + .agent_count = SCMI_AGENT_ID_COUNT, + .protocol_count = 6, + }, +}; diff --git a/product/sgm775/scp_ramfw/config_scmi_clock.c b/product/sgm775/scp_ramfw/config_scmi_clock.c index 62f7b887f..91829ffae 100644 --- a/product/sgm775/scp_ramfw/config_scmi_clock.c +++ b/product/sgm775/scp_ramfw/config_scmi_clock.c @@ -20,37 +20,21 @@ static const struct mod_scmi_clock_device agent_device_table_ospm[] = { /* VPU */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_DEV_IDX_VPU), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | - MOD_SCMI_CLOCK_PERM_GET_RATE | - MOD_SCMI_CLOCK_PERM_SET_RATE, }, { /* DPU */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_DEV_IDX_DPU), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | - MOD_SCMI_CLOCK_PERM_GET_RATE | - MOD_SCMI_CLOCK_PERM_SET_RATE, }, { /* PIXEL_0 */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_DEV_IDX_PIXEL_0), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | - MOD_SCMI_CLOCK_PERM_GET_RATE | - MOD_SCMI_CLOCK_PERM_SET_RATE, }, { /* PIXEL_1 */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_DEV_IDX_PIXEL_1), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | - MOD_SCMI_CLOCK_PERM_GET_RATE | - MOD_SCMI_CLOCK_PERM_SET_RATE, }, }; diff --git a/product/sgm775/scp_ramfw/firmware.mk b/product/sgm775/scp_ramfw/firmware.mk index 6bf37cb8a..73911814c 100644 --- a/product/sgm775/scp_ramfw/firmware.mk +++ b/product/sgm775/scp_ramfw/firmware.mk @@ -11,6 +11,7 @@ BS_FIRMWARE_CPU := cortex-m3 BS_FIRMWARE_HAS_MULTITHREADING := yes BS_FIRMWARE_HAS_NOTIFICATION := yes +BS_FIRMWARE_HAS_RESOURCE_PERMISSIONS := yes BS_FIRMWARE_MODULES := \ sid \ @@ -47,6 +48,10 @@ BS_FIRMWARE_MODULES := \ scmi_apcore \ sds +ifeq ($(BS_FIRMWARE_HAS_RESOURCE_PERMISSIONS),yes) + BS_FIRMWARE_MODULES += resource_perms +endif + BS_FIRMWARE_SOURCES := \ rtx_config.c \ sgm775_core.c \ @@ -83,4 +88,8 @@ ifeq ($(BUILD_HAS_DEBUGGER),yes) BS_FIRMWARE_SOURCES += config_debugger_cli.c endif +ifeq ($(BS_FIRMWARE_HAS_RESOURCE_PERMISSIONS),yes) + BS_FIRMWARE_SOURCES += config_resource_perms.c +endif + include $(BS_DIR)/firmware.mk diff --git a/product/sgm776/scp_ramfw/config_resource_perms.c b/product/sgm776/scp_ramfw/config_resource_perms.c new file mode 100644 index 000000000..f31922062 --- /dev/null +++ b/product/sgm776/scp_ramfw/config_resource_perms.c @@ -0,0 +1,79 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "sgm776_scmi.h" + +#include +#include + +#include +#include +#include +#include +#include + +/*! + * If the agent wants to modify permissions at run-time these tables + * must be allocated in writable memory. + */ + +#define AGENT_IDX(agent_id) (agent_id - 1) + +static struct mod_res_agent_protocol_permissions + agent_protocol_permissions[] = { + [AGENT_IDX(SCMI_AGENT_ID_OSPM)] = { + .protocols = MOD_RES_PERMS_SCMI_ALL_PROTOCOLS_ALLOWED, + }, + + /* PSCI agent has no access to clock protocol */ + [AGENT_IDX(SCMI_AGENT_ID_PSCI)] = { + .protocols = MOD_RES_PERMS_SCMI_CLOCK_PROTOCOL_DENIED, + }, +}; + +/* + * Messages have an index offset from 0x3 as all agents can access + * the VERSION/ATTRIBUTES/MSG_ATTRIBUTES messages for all + * protocols, hence message 0x3 maps to bit[0], message 0x4 maps + * to bit[1], etc. + */ +static struct mod_res_agent_msg_permissions agent_msg_permissions[] = { + [AGENT_IDX(SCMI_AGENT_ID_OSPM)] = { + /* Example, Base, disable unused msg 12 */ + .messages[MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX] = 0x0, + /* Power Domain */ + .messages[MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0, + /* System Power Domain */ + .messages[MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0, + /* Performance */ + .messages[MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = 0x0, + /* + * sgm776 denies access to CONFIG_SET + */ + .messages[MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = + MOD_RES_PERMS_ACCESS_DENIED << + (MOD_SCMI_CLOCK_CONFIG_SET - MOD_SCMI_CLOCK_ATTRIBUTES), + /* Sensors */ + .messages[MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0, + /* Reset Domains */ + .messages[MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0, + }, +}; + +static struct mod_res_agent_permission agent_permissions = { + .agent_protocol_permissions = agent_protocol_permissions, + .agent_msg_permissions = agent_msg_permissions, +}; + +struct fwk_module_config config_resource_perms = { + .data = + &(struct mod_res_resource_perms_config){ + .agent_permissions = (uintptr_t)&agent_permissions, + .agent_count = SCMI_AGENT_ID_COUNT, + .protocol_count = 6, + }, +}; diff --git a/product/sgm776/scp_ramfw/config_scmi_clock.c b/product/sgm776/scp_ramfw/config_scmi_clock.c index cc38feace..a70173e47 100644 --- a/product/sgm776/scp_ramfw/config_scmi_clock.c +++ b/product/sgm776/scp_ramfw/config_scmi_clock.c @@ -20,37 +20,21 @@ static const struct mod_scmi_clock_device agent_device_table_ospm[] = { /* VPU */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_DEV_IDX_VPU), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | - MOD_SCMI_CLOCK_PERM_GET_RATE | - MOD_SCMI_CLOCK_PERM_SET_RATE, }, { /* DPU */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_DEV_IDX_DPU), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | - MOD_SCMI_CLOCK_PERM_GET_RATE | - MOD_SCMI_CLOCK_PERM_SET_RATE, }, { /* PIXEL_0 */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_DEV_IDX_PIXEL_0), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | - MOD_SCMI_CLOCK_PERM_GET_RATE | - MOD_SCMI_CLOCK_PERM_SET_RATE, }, { /* PIXEL_1 */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_DEV_IDX_PIXEL_1), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | - MOD_SCMI_CLOCK_PERM_GET_RATE | - MOD_SCMI_CLOCK_PERM_SET_RATE, }, }; diff --git a/product/sgm776/scp_ramfw/firmware.mk b/product/sgm776/scp_ramfw/firmware.mk index 510420b58..996dadd26 100644 --- a/product/sgm776/scp_ramfw/firmware.mk +++ b/product/sgm776/scp_ramfw/firmware.mk @@ -8,6 +8,7 @@ BS_FIRMWARE_CPU := cortex-m3 BS_FIRMWARE_HAS_MULTITHREADING := yes BS_FIRMWARE_HAS_NOTIFICATION := yes +BS_FIRMWARE_HAS_RESOURCE_PERMISSIONS := yes BS_FIRMWARE_MODULES := \ sid \ @@ -43,6 +44,10 @@ BS_FIRMWARE_MODULES := \ scmi_apcore \ sds +ifeq ($(BS_FIRMWARE_HAS_RESOURCE_PERMISSIONS),yes) + BS_FIRMWARE_MODULES += resource_perms +endif + BS_FIRMWARE_SOURCES := \ rtx_config.c \ config_log.c \ @@ -73,4 +78,7 @@ BS_FIRMWARE_SOURCES := \ config_system_info.c \ config_scmi_power_domain.c +ifeq ($(BS_FIRMWARE_HAS_RESOURCE_PERMISSIONS),yes) + BS_FIRMWARE_SOURCES += config_resource_perms.c +endif include $(BS_DIR)/firmware.mk diff --git a/product/tc0/scp_ramfw/config_resource_perms.c b/product/tc0/scp_ramfw/config_resource_perms.c new file mode 100644 index 000000000..22b2fc997 --- /dev/null +++ b/product/tc0/scp_ramfw/config_resource_perms.c @@ -0,0 +1,79 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "tc0_scmi.h" + +#include +#include + +#include +#include +#include +#include +#include + +/*! + * If the agent wants to modify permissions at run-time these tables + * must be allocated in writable memory. + */ + +#define AGENT_IDX(agent_id) (agent_id - 1) + +static struct mod_res_agent_protocol_permissions + agent_protocol_permissions[] = { + [AGENT_IDX(SCP_SCMI_AGENT_ID_OSPM)] = { + .protocols = MOD_RES_PERMS_SCMI_ALL_PROTOCOLS_ALLOWED, + }, + + /* PSCI agent has no access to clock protocol */ + [AGENT_IDX(SCP_SCMI_AGENT_ID_PSCI)] = { + .protocols = MOD_RES_PERMS_SCMI_CLOCK_PROTOCOL_DENIED, + }, +}; + +/* + * Messages have an index offset from 0x3 as all agents can access + * the VERSION/ATTRIBUTES/MSG_ATTRIBUTES messages for all + * protocols, hence message 0x3 maps to bit[0], message 0x4 maps + * to bit[1], etc. + */ +static struct mod_res_agent_msg_permissions agent_msg_permissions[] = { + [AGENT_IDX(SCP_SCMI_AGENT_ID_OSPM)] = { + /* Example, Base, disable unused msg 12 */ + .messages[MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX] = 0x0, + /* Power Domain */ + .messages[MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0, + /* System Power Domain */ + .messages[MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0, + /* Performance */ + .messages[MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = 0x0, + /* + * tc0 denies access to CONFIG_SET + */ + .messages[MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = + MOD_RES_PERMS_ACCESS_DENIED << + (MOD_SCMI_CLOCK_CONFIG_SET - MOD_SCMI_CLOCK_ATTRIBUTES), + /* Sensors */ + .messages[MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0, + /* Reset Domains */ + .messages[MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0, + }, +}; + +static struct mod_res_agent_permission agent_permissions = { + .agent_protocol_permissions = agent_protocol_permissions, + .agent_msg_permissions = agent_msg_permissions, +}; + +struct fwk_module_config config_resource_perms = { + .data = + &(struct mod_res_resource_perms_config){ + .agent_permissions = (uintptr_t)&agent_permissions, + .agent_count = SCP_SCMI_AGENT_ID_COUNT, + .protocol_count = 6, + }, +}; diff --git a/product/tc0/scp_ramfw/config_scmi_clock.c b/product/tc0/scp_ramfw/config_scmi_clock.c index a2b4a4b7f..8a38aa75f 100644 --- a/product/tc0/scp_ramfw/config_scmi_clock.c +++ b/product/tc0/scp_ramfw/config_scmi_clock.c @@ -20,30 +20,16 @@ static const struct mod_scmi_clock_device agent_device_table_ospm[] = { /* DPU */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_IDX_DPU), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | - MOD_SCMI_CLOCK_PERM_GET_RATE | - MOD_SCMI_CLOCK_PERM_SET_RATE | - MOD_SCMI_CLOCK_PERM_SET_CONFIG, }, { /* PIXEL_0 */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_IDX_PIXEL_0), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | - MOD_SCMI_CLOCK_PERM_GET_RATE | - MOD_SCMI_CLOCK_PERM_SET_RATE | - MOD_SCMI_CLOCK_PERM_SET_CONFIG, }, { /* PIXEL_1 */ .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_IDX_PIXEL_1), - .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | - MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | - MOD_SCMI_CLOCK_PERM_GET_RATE | - MOD_SCMI_CLOCK_PERM_SET_RATE, }, }; diff --git a/product/tc0/scp_ramfw/firmware.mk b/product/tc0/scp_ramfw/firmware.mk index a7a9dd96f..1f702654e 100644 --- a/product/tc0/scp_ramfw/firmware.mk +++ b/product/tc0/scp_ramfw/firmware.mk @@ -9,6 +9,7 @@ BS_FIRMWARE_CPU := cortex-m7 BS_FIRMWARE_HAS_MULTITHREADING := yes BS_FIRMWARE_HAS_NOTIFICATION := yes BS_FIRMWARE_NOTIFICATION_COUNT := 128 +BS_FIRMWARE_HAS_RESOURCE_PERMISSIONS := yes BS_FIRMWARE_MODULES := \ armv7m_mpu \ @@ -36,6 +37,10 @@ BS_FIRMWARE_MODULES := \ psu \ tc0_system +ifeq ($(BS_FIRMWARE_HAS_RESOURCE_PERMISSIONS),yes) + BS_FIRMWARE_MODULES += resource_perms +endif + BS_FIRMWARE_SOURCES := \ config_system_power.c \ rtx_config.c \ @@ -62,4 +67,8 @@ BS_FIRMWARE_SOURCES := \ config_clock.c \ config_scmi_power_domain.c +ifeq ($(BS_FIRMWARE_HAS_RESOURCE_PERMISSIONS),yes) + BS_FIRMWARE_SOURCES += config_resource_perms.c +endif + include $(BS_DIR)/firmware.mk -- GitLab From b8acbb4966316a8f1c69957364ca9e882fa95126 Mon Sep 17 00:00:00 2001 From: Jim Quigley Date: Wed, 17 Jun 2020 11:42:50 +0100 Subject: [PATCH 5/9] SCMI: System Power Protocol Permissions This patch adds the SCMI System Power Protocol Resource Permissions management. Change-Id: Icabb20f69dcba86fc9dff2afc1c21f1151de8962 Signed-off-by: Jim Quigley --- .../src/mod_scmi_system_power.c | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/module/scmi_system_power/src/mod_scmi_system_power.c b/module/scmi_system_power/src/mod_scmi_system_power.c index 476be89a8..6dfe8b2a9 100644 --- a/module/scmi_system_power/src/mod_scmi_system_power.c +++ b/module/scmi_system_power/src/mod_scmi_system_power.c @@ -8,6 +8,9 @@ #include #include +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS +# include +#endif #include #include @@ -30,6 +33,11 @@ struct scmi_sys_power_ctx { int agent_count; fwk_id_t *system_power_notifications; #endif + +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + /* SCMI Resource Permissions API */ + const struct mod_res_permissions_api *res_perms_api; +#endif }; static int scmi_sys_power_version_handler(fwk_id_t service_id, @@ -458,6 +466,42 @@ __attribute((weak)) int scmi_sys_power_state_set_policy( return FWK_SUCCESS; } +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + +/* + * SCMI Resource Permissions handler + */ +static int scmi_sys_power_permissions_handler( + fwk_id_t service_id, + const uint32_t *payload, + size_t payload_size, + unsigned int message_id) +{ + enum mod_res_perms_permissions perms; + unsigned int agent_id; + int status; + + status = scmi_sys_power_ctx.scmi_api->get_agent_id(service_id, &agent_id); + if (status != FWK_SUCCESS) + return FWK_E_ACCESS; + + if (message_id < 3) + return FWK_SUCCESS; + + /* + * We check that the agent has permssions to access the command + */ + perms = scmi_sys_power_ctx.res_perms_api->agent_has_message_permission( + agent_id, MOD_SCMI_PROTOCOL_ID_BASE, message_id); + + if (perms == MOD_RES_PERMS_ACCESS_ALLOWED) + return FWK_SUCCESS; + else + return FWK_E_ACCESS; +} + +#endif + /* * SCMI module -> SCMI system power module interface */ @@ -476,6 +520,9 @@ static int scmi_sys_power_handler(fwk_id_t protocol_id, unsigned int message_id) { int32_t return_value; +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + int status; +#endif static_assert(FWK_ARRAY_SIZE(handler_table) == FWK_ARRAY_SIZE(payload_size_table), @@ -494,6 +541,15 @@ static int scmi_sys_power_handler(fwk_id_t protocol_id, goto error; } +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + status = scmi_sys_power_permissions_handler( + service_id, payload, payload_size, message_id); + if (status != FWK_SUCCESS) { + return_value = SCMI_DENIED; + goto error; + } +#endif + return handler_table[message_id](service_id, payload); error: @@ -558,6 +614,15 @@ static int scmi_sys_power_bind(fwk_id_t id, unsigned int round) if (status != FWK_SUCCESS) return status; +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + status = fwk_module_bind( + FWK_ID_MODULE(FWK_MODULE_IDX_RESOURCE_PERMS), + FWK_ID_API(FWK_MODULE_IDX_RESOURCE_PERMS, MOD_RES_PERM_RESOURCE_PERMS), + &scmi_sys_power_ctx.res_perms_api); + if (status != FWK_SUCCESS) + return status; +#endif + /* Bind to POWER DOMAIN module */ status = fwk_module_bind(fwk_module_id_power_domain, mod_pd_api_id_restricted, &scmi_sys_power_ctx.pd_api); -- GitLab From c7dad8aae3cf668c9930d98783ea03ad991116aa Mon Sep 17 00:00:00 2001 From: Jim Quigley Date: Wed, 17 Jun 2020 11:43:24 +0100 Subject: [PATCH 6/9] SCMI: Power Domain Protocol Permissions This patch adds the SCMI Power Domain Protocol Resource Permissions management. Change-Id: I41849eba98f201029bcf4f2ed2d6d59e8fc4e605 Signed-off-by: Jim Quigley --- .../include/mod_resource_perms.h | 22 ++++ .../src/mod_scmi_power_domain.c | 108 ++++++++++++++++++ .../juno/scp_ramfw/config_resource_perms.c | 34 ++++++ .../sgm775/scp_ramfw/config_resource_perms.c | 12 ++ .../sgm776/scp_ramfw/config_resource_perms.c | 12 ++ 5 files changed, 188 insertions(+) diff --git a/module/resource_perms/include/mod_resource_perms.h b/module/resource_perms/include/mod_resource_perms.h index bf5ba1c2b..187a2d94b 100644 --- a/module/resource_perms/include/mod_resource_perms.h +++ b/module/resource_perms/include/mod_resource_perms.h @@ -178,6 +178,28 @@ enum mod_res_clock_permissions_idx { MOD_SCMI_CLOCK_CONFIG_SET - MOD_RES_PERMS_CLOCK_PERMS_OFFSET, }; +/*! + * \brief SCMI Power Domain Protocol Message index offset + */ +#define MOD_RES_PERMS_POWER_DOMAIN_PERMS_OFFSET \ + MOD_SCMI_PD_POWER_DOMAIN_ATTRIBUTES + +/*! + * \brief SCMI Power Domain Protocol Message Indices + */ +enum mod_res_power_domain_permissions_idx { + MOD_RES_PERMS_SCMI_POWER_DOMAIN_ATTRIBUTES_IDX = + MOD_SCMI_PD_POWER_DOMAIN_ATTRIBUTES - + MOD_RES_PERMS_POWER_DOMAIN_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_POWER_DOMAIN_STATE_SET_IDX = + MOD_SCMI_PD_POWER_STATE_SET - MOD_RES_PERMS_POWER_DOMAIN_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_POWER_DOMAIN_STATE_GET_IDX = + MOD_SCMI_PD_POWER_STATE_GET - MOD_RES_PERMS_POWER_DOMAIN_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_POWER_DOMAIN_STATE_NOTIFY_IDX = + MOD_SCMI_PD_POWER_STATE_NOTIFY - + MOD_RES_PERMS_POWER_DOMAIN_PERMS_OFFSET, +}; + /*! * \brief SCMI Agent Permissions * diff --git a/module/scmi_power_domain/src/mod_scmi_power_domain.c b/module/scmi_power_domain/src/mod_scmi_power_domain.c index 8f273ab24..ac1e9b273 100644 --- a/module/scmi_power_domain/src/mod_scmi_power_domain.c +++ b/module/scmi_power_domain/src/mod_scmi_power_domain.c @@ -11,6 +11,9 @@ #include #include +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS +# include +#endif #include #include @@ -64,6 +67,11 @@ struct scmi_pd_ctx { /* Pointer to a table of scmi_pd operations */ struct scmi_pd_operations *ops; + +#if BUILD_HAS_RESOURCE_PERMISSIONS + /* SCMI Resource Permissions API */ + const struct mod_res_permissions_api *res_perms_api; +#endif }; static int scmi_pd_protocol_version_handler(fwk_id_t service_id, @@ -638,6 +646,87 @@ __attribute__((weak)) int scmi_pd_power_state_set_policy( return FWK_SUCCESS; } +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + +/* + * SCMI Resource Permissions handler + */ +static unsigned int get_pd_domain_id( + const uint32_t *payload, + unsigned int message_id) +{ + const struct scmi_pd_power_state_set_a2p *params_set; + const struct scmi_pd_power_state_get_a2p *params_get; + + switch (message_id) { + case MOD_SCMI_PD_POWER_STATE_SET: + params_set = (const struct scmi_pd_power_state_set_a2p *)payload; + return params_set->domain_id; + + default: + /* + * Every SCMI Power Domains message apart from power_state_set + * is formatted with the domain ID as the first message element. + * We will use the power_state_set message as a basic format to + * retrieve the domain ID to avoid unnecessary code. + */ + params_get = (const struct scmi_pd_power_state_get_a2p *)payload; + return params_get->domain_id; + } +} + +static int scmi_pd_permissions_handler( + fwk_id_t service_id, + const uint32_t *payload, + size_t payload_size, + unsigned int message_id, + int32_t *return_values) +{ + enum mod_res_perms_permissions perms; + unsigned int agent_id, domain_id; + enum mod_pd_type pd_type; + fwk_id_t pd_id; + int status; + + status = scmi_pd_ctx.scmi_api->get_agent_id(service_id, &agent_id); + if (status != FWK_SUCCESS) { + *return_values = SCMI_GENERIC_ERROR; + return FWK_E_PARAM; + } + + if (message_id < 3) + return FWK_SUCCESS; + + domain_id = get_pd_domain_id(payload, message_id); + if (domain_id > UINT16_MAX) { + *return_values = SCMI_NOT_FOUND; + return FWK_E_ACCESS; + } + + pd_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, domain_id); + if (!fwk_module_is_valid_element_id(pd_id)) { + *return_values = SCMI_NOT_FOUND; + return FWK_E_ACCESS; + } + + status = scmi_pd_ctx.pd_api->get_domain_type(pd_id, &pd_type); + if (status != FWK_SUCCESS) { + *return_values = SCMI_GENERIC_ERROR; + return FWK_E_ACCESS; + } + + perms = scmi_pd_ctx.res_perms_api->agent_has_resource_permission( + agent_id, MOD_SCMI_PROTOCOL_ID_POWER_DOMAIN, message_id, domain_id); + + if (perms == MOD_RES_PERMS_ACCESS_ALLOWED) + return FWK_SUCCESS; + + *return_values = SCMI_DENIED; + return FWK_E_ACCESS; +} + +#endif + /* * SCMI module -> SCMI power module interface */ @@ -653,6 +742,9 @@ static int scmi_pd_message_handler(fwk_id_t protocol_id, fwk_id_t service_id, const uint32_t *payload, size_t payload_size, unsigned int message_id) { int32_t return_value; +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + int status; +#endif static_assert(FWK_ARRAY_SIZE(handler_table) == FWK_ARRAY_SIZE(payload_size_table), @@ -669,6 +761,13 @@ static int scmi_pd_message_handler(fwk_id_t protocol_id, fwk_id_t service_id, goto error; } +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + status = scmi_pd_permissions_handler( + service_id, payload, payload_size, message_id, &return_value); + if (status != FWK_SUCCESS) + goto error; +#endif + return handler_table[message_id](service_id, payload); error: @@ -754,6 +853,15 @@ static int scmi_pd_bind(fwk_id_t id, unsigned int round) return status; #endif +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + status = fwk_module_bind( + FWK_ID_MODULE(FWK_MODULE_IDX_RESOURCE_PERMS), + FWK_ID_API(FWK_MODULE_IDX_RESOURCE_PERMS, MOD_RES_PERM_RESOURCE_PERMS), + &scmi_pd_ctx.res_perms_api); + if (status != FWK_SUCCESS) + return status; +#endif + return fwk_module_bind(fwk_module_id_power_domain, mod_pd_api_id_restricted, &scmi_pd_ctx.pd_api); } diff --git a/product/juno/scp_ramfw/config_resource_perms.c b/product/juno/scp_ramfw/config_resource_perms.c index 0bdb3eb21..363d89eff 100644 --- a/product/juno/scp_ramfw/config_resource_perms.c +++ b/product/juno/scp_ramfw/config_resource_perms.c @@ -132,10 +132,44 @@ static mod_res_perms_t scmi_clock_perms[] }, }; +/* + * We are tracking 4 SCMI Power Domain Protocol commands + * + * 0, SCMI_PD_POWER_DOMAIN_ATTRIBUTES + * 1, SCMI_PD_POWER_STATE_SET + * 2, SCMI_PD_POWER_STATE_GET + * 3, SCMI_PD_POWER_STATE_NOTIFY + */ +#define JUNO_PD_RESOURCE_CMDS 4 +#define JUNO_PD_RESOURCE_ELEMENTS \ + ((POWER_DOMAIN_IDX_COUNT >> MOD_RES_PERMS_TYPE_SHIFT) + 1) +static mod_res_perms_t + scmi_pd_perms[][JUNO_PD_RESOURCE_CMDS][JUNO_PD_RESOURCE_ELEMENTS] = { + /* SCMI_PROTOCOL_ID_POWER_DOMAIN */ + /* 0, SCMI_PD_POWER_DOMAIN_ATTRIBUTES */ + /* 1, SCMI_PD_POWER_STATE_SET */ + /* 2, SCMI_PD_POWER_STATE_GET */ + /* 3, SCMI_PD_POWER_STATE_NOTIFY */ + /* For Juno, resource_id == power domain ID */ + [AGENT_IDX(JUNO_SCMI_AGENT_IDX_OSPM)] = { + [MOD_RES_PERMS_SCMI_POWER_DOMAIN_ATTRIBUTES_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_POWER_DOMAIN_STATE_SET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_POWER_DOMAIN_STATE_GET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_POWER_DOMAIN_STATE_NOTIFY_IDX][0] = 0x0, + }, + [AGENT_IDX(JUNO_SCMI_AGENT_IDX_PSCI)] = { + [MOD_RES_PERMS_SCMI_POWER_DOMAIN_ATTRIBUTES_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_POWER_DOMAIN_STATE_SET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_POWER_DOMAIN_STATE_GET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_POWER_DOMAIN_STATE_NOTIFY_IDX][0] = 0x0, + }, +}; + static struct mod_res_agent_permission agent_permissions = { .agent_protocol_permissions = agent_protocol_permissions, .agent_msg_permissions = agent_msg_permissions, .scmi_clock_perms = &scmi_clock_perms[0][0][0], + .scmi_pd_perms = &scmi_pd_perms[0][0][0], }; struct fwk_module_config config_resource_perms = { diff --git a/product/sgm775/scp_ramfw/config_resource_perms.c b/product/sgm775/scp_ramfw/config_resource_perms.c index 1618e989a..a8159ca34 100644 --- a/product/sgm775/scp_ramfw/config_resource_perms.c +++ b/product/sgm775/scp_ramfw/config_resource_perms.c @@ -62,6 +62,18 @@ static struct mod_res_agent_msg_permissions agent_msg_permissions[] = { /* Reset Domains */ .messages[MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0, }, + [AGENT_IDX(SCMI_AGENT_ID_PSCI)] = { + .messages[0] = 0x0, /* Base */ + .messages[1] = 0x0, /* Power Domain */ + .messages[2] = 0x0, /* System Power Domain */ + .messages[3] = 0x0, + /* + * sgm775 denies access to CONFIG_SET + */ + .messages[4] = + (1 << (MOD_SCMI_CLOCK_CONFIG_SET - MOD_SCMI_CLOCK_ATTRIBUTES)), + .messages[5] = 0x0, /* Sensors */ + }, }; static struct mod_res_agent_permission agent_permissions = { diff --git a/product/sgm776/scp_ramfw/config_resource_perms.c b/product/sgm776/scp_ramfw/config_resource_perms.c index f31922062..99c5c3529 100644 --- a/product/sgm776/scp_ramfw/config_resource_perms.c +++ b/product/sgm776/scp_ramfw/config_resource_perms.c @@ -62,6 +62,18 @@ static struct mod_res_agent_msg_permissions agent_msg_permissions[] = { /* Reset Domains */ .messages[MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0, }, + [AGENT_IDX(SCMI_AGENT_ID_PSCI)] = { + .messages[0] = 0x0, /* Base */ + .messages[1] = 0x0, /* Power Domain */ + .messages[2] = 0x0, /* System Power Domain */ + .messages[3] = 0x0, + /* + * sgm776 denies access to CONFIG_SET + */ + .messages[4] = + (1 << (MOD_SCMI_CLOCK_CONFIG_SET - MOD_SCMI_CLOCK_ATTRIBUTES)), + .messages[5] = 0x0, /* Sensors */ + }, }; static struct mod_res_agent_permission agent_permissions = { -- GitLab From c6b7a72528fb11b36250f56ccc4f77abad9bca81 Mon Sep 17 00:00:00 2001 From: Jim Quigley Date: Wed, 3 Jun 2020 12:31:57 +0100 Subject: [PATCH 7/9] SCMI: Performance Protocol Permissions This patch adds the SCMI Performance Protocol Resource Permissions management. Change-Id: Id93882eade3c0614b86b8614625e0b504a8b1a2d Signed-off-by: Jim Quigley --- .../include/mod_resource_perms.h | 29 +++ module/scmi_perf/include/mod_scmi_perf.h | 2 - module/scmi_perf/src/mod_scmi_perf.c | 123 ++++++++++--- .../juno/scp_ramfw/config_resource_perms.c | 84 ++++++++- product/juno/scp_ramfw/config_scmi_perf.c | 15 -- product/rdn1e1/include/scp_rdn1e1_scmi.h | 1 + .../rdn1e1/scp_ramfw/config_resource_perms.c | 166 ++++++++++++++++++ product/rdn1e1/scp_ramfw/config_scmi_perf.c | 10 -- product/rdn1e1/scp_ramfw/firmware.mk | 7 +- product/sgi575/include/scp_sgi575_scmi.h | 1 + .../sgi575/scp_ramfw/config_resource_perms.c | 166 ++++++++++++++++++ product/sgi575/scp_ramfw/config_scmi_perf.c | 10 -- product/sgi575/scp_ramfw/firmware.mk | 7 +- .../sgm775/scp_ramfw/config_resource_perms.c | 29 ++- product/sgm775/scp_ramfw/config_scmi_perf.c | 15 -- .../sgm776/scp_ramfw/config_resource_perms.c | 21 ++- product/sgm776/scp_ramfw/config_scmi_perf.c | 15 -- product/tc0/scp_ramfw/config_resource_perms.c | 95 +++++++--- product/tc0/scp_ramfw/config_scmi_perf.c | 5 - 19 files changed, 670 insertions(+), 131 deletions(-) create mode 100644 product/rdn1e1/scp_ramfw/config_resource_perms.c create mode 100644 product/sgi575/scp_ramfw/config_resource_perms.c diff --git a/module/resource_perms/include/mod_resource_perms.h b/module/resource_perms/include/mod_resource_perms.h index 187a2d94b..d38f1676c 100644 --- a/module/resource_perms/include/mod_resource_perms.h +++ b/module/resource_perms/include/mod_resource_perms.h @@ -200,6 +200,35 @@ enum mod_res_power_domain_permissions_idx { MOD_RES_PERMS_POWER_DOMAIN_PERMS_OFFSET, }; +/*! + * \brief SCMI Performance Protocol Message index offset + */ +#define MOD_RES_PERMS_PERF_PERMS_OFFSET MOD_SCMI_PERF_DOMAIN_ATTRIBUTES + +/*! + * \brief SCMI Performance Protocol Message Indices + */ +enum mod_res_perf_permissions_idx { + MOD_RES_PERMS_SCMI_PERF_ATTRIBUTES_IDX = + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES - MOD_RES_PERMS_PERF_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_PERF_DESCRIBE_LEVELS_IDX = + MOD_SCMI_PERF_DESCRIBE_LEVELS - MOD_RES_PERMS_PERF_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_PERF_LIMITS_SET_IDX = + MOD_SCMI_PERF_LIMITS_SET - MOD_RES_PERMS_PERF_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_PERF_LIMITS_GET_IDX = + MOD_SCMI_PERF_LIMITS_GET - MOD_RES_PERMS_PERF_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_PERF_LEVEL_SET_IDX = + MOD_SCMI_PERF_LEVEL_SET - MOD_RES_PERMS_PERF_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_PERF_LEVEL_GET_IDX = + MOD_SCMI_PERF_LEVEL_GET - MOD_RES_PERMS_PERF_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_PERF_NOTIFY_LIMITS_IDX = + MOD_SCMI_PERF_NOTIFY_LIMITS - MOD_RES_PERMS_PERF_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_PERF_NOTIFY_LEVEL_IDX = + MOD_SCMI_PERF_NOTIFY_LEVEL - MOD_RES_PERMS_PERF_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_PERF_DESCRIBE_FAST_CHANNEL_IDX = + MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL - MOD_RES_PERMS_PERF_PERMS_OFFSET, +}; + /*! * \brief SCMI Agent Permissions * diff --git a/module/scmi_perf/include/mod_scmi_perf.h b/module/scmi_perf/include/mod_scmi_perf.h index 9c464f0ff..4b2250533 100644 --- a/module/scmi_perf/include/mod_scmi_perf.h +++ b/module/scmi_perf/include/mod_scmi_perf.h @@ -79,8 +79,6 @@ enum mod_scmi_perf_fast_channel_memory_offset { * \brief Performance domain configuration data. */ struct mod_scmi_perf_domain_config { - const uint32_t (*permissions)[]; /*!< Per-agent permission flags */ - /*! * \brief Domain fast channels. * diff --git a/module/scmi_perf/src/mod_scmi_perf.c b/module/scmi_perf/src/mod_scmi_perf.c index a31eaa5cd..de4e2aea6 100644 --- a/module/scmi_perf/src/mod_scmi_perf.c +++ b/module/scmi_perf/src/mod_scmi_perf.c @@ -11,6 +11,9 @@ #include #include +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS +# include +#endif #include #include #ifdef BUILD_HAS_STATISTICS @@ -158,6 +161,11 @@ struct scmi_perf_ctx { /* Fast Channels Polling Rate Limit */ uint32_t fast_channels_rate_limit; + +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + /* SCMI Resource Permissions API */ + const struct mod_res_permissions_api *res_perms_api; +#endif }; static struct scmi_perf_ctx scmi_perf_ctx; @@ -181,6 +189,60 @@ static const fwk_id_t scmi_perf_get_limits = FWK_ID_EVENT_INIT(FWK_MODULE_IDX_SCMI_PERF, SCMI_PERF_EVENT_IDX_LIMITS_GET_REQUEST); +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + +/* + * SCMI Resource Permissions handler + */ +static int get_perf_domain_id(const uint32_t *payload, unsigned int *domain_id) +{ + /* + * Every SCMI Performance message is formatted with the domain ID + * as the first message element. We will use the perf_limits_get + * message as a basic format to retrieve the domain ID to avoid + * unnecessary code. + */ + const struct scmi_perf_limits_get_a2p *parameters = + (const struct scmi_perf_limits_get_a2p *)payload; + + if (parameters->domain_id >= scmi_perf_ctx.domain_count) + return FWK_E_PARAM; + + *domain_id = parameters->domain_id; + return FWK_SUCCESS; +} + +static int scmi_perf_permissions_handler( + fwk_id_t service_id, + const uint32_t *payload, + unsigned int message_id) +{ + enum mod_res_perms_permissions perms; + unsigned int agent_id, domain_id; + int status; + + status = scmi_perf_ctx.scmi_api->get_agent_id(service_id, &agent_id); + if (status != FWK_SUCCESS) + return FWK_E_ACCESS; + + if (message_id < 3) + return FWK_SUCCESS; + + status = get_perf_domain_id(payload, &domain_id); + if (status != FWK_SUCCESS) + return FWK_E_PARAM; + + perms = scmi_perf_ctx.res_perms_api->agent_has_resource_permission( + agent_id, MOD_SCMI_PROTOCOL_ID_PERF, message_id, domain_id); + + if (perms == MOD_RES_PERMS_ACCESS_ALLOWED) + return FWK_SUCCESS; + else + return FWK_E_ACCESS; +} + +#endif + /* * Protocol command handlers */ @@ -260,7 +322,6 @@ static int scmi_perf_domain_attributes_handler(fwk_id_t service_id, { int status; unsigned int agent_id; - const struct mod_scmi_perf_domain_config *domain; const struct scmi_perf_domain_attributes_a2p *parameters; uint32_t permissions; fwk_id_t domain_id; @@ -285,8 +346,19 @@ static int scmi_perf_domain_attributes_handler(fwk_id_t service_id, if (status != FWK_SUCCESS) goto exit; - domain = &(*scmi_perf_ctx.config->domains)[parameters->domain_id]; - permissions = (*domain->permissions)[agent_id]; +#ifndef BUILD_HAS_RESOURCE_PERMISSIONS + permissions = + MOD_SCMI_PERF_PERMS_SET_LIMITS | MOD_SCMI_PERF_PERMS_SET_LEVEL; +#else + status = scmi_perf_permissions_handler( + service_id, payload, MOD_SCMI_PERF_LIMITS_SET); + if (status == FWK_SUCCESS) + permissions = MOD_SCMI_PERF_PERMS_SET_LIMITS; + status = scmi_perf_permissions_handler( + service_id, payload, MOD_SCMI_PERF_LEVEL_SET); + if (status == FWK_SUCCESS) + permissions |= MOD_SCMI_PERF_PERMS_SET_LEVEL; +#endif domain_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_DVFS, parameters->domain_id); status = scmi_perf_ctx.dvfs_api->get_sustained_opp(domain_id, &opp); @@ -435,11 +507,9 @@ static int scmi_perf_limits_set_handler(fwk_id_t service_id, { int status; unsigned int agent_id; - const struct mod_scmi_perf_domain_config *domain; const struct scmi_perf_limits_set_a2p *parameters; uint64_t range_min, range_max; fwk_id_t domain_id; - uint32_t permissions; struct scmi_perf_limits_set_p2a return_values = { .status = SCMI_GENERIC_ERROR, }; @@ -458,15 +528,6 @@ static int scmi_perf_limits_set_handler(fwk_id_t service_id, if (status != FWK_SUCCESS) goto exit; - /* Ensure the agent has permission to do this */ - domain = &(*scmi_perf_ctx.config->domains)[parameters->domain_id]; - permissions = (*domain->permissions)[agent_id]; - if (!(permissions & MOD_SCMI_PERF_PERMS_SET_LIMITS)) { - return_values.status = SCMI_DENIED; - - goto exit; - } - if (parameters->range_min > parameters->range_max) { return_values.status = SCMI_INVALID_PARAMETERS; goto exit; @@ -575,10 +636,8 @@ static int scmi_perf_level_set_handler(fwk_id_t service_id, { int status; unsigned int agent_id; - const struct mod_scmi_perf_domain_config *domain; const struct scmi_perf_level_set_a2p *parameters; fwk_id_t domain_id; - uint32_t permissions; struct scmi_perf_level_set_p2a return_values = { .status = SCMI_GENERIC_ERROR, }; @@ -597,15 +656,6 @@ static int scmi_perf_level_set_handler(fwk_id_t service_id, if (status != FWK_SUCCESS) goto exit; - /* Ensure the agent has permission to do this */ - domain = &(*scmi_perf_ctx.config->domains)[parameters->domain_id]; - permissions = (*domain->permissions)[agent_id]; - if (!(permissions & MOD_SCMI_PERF_PERMS_SET_LEVEL)) { - return_values.status = SCMI_DENIED; - - goto exit; - } - /* * Note that the policy handler may change the performance level */ @@ -954,6 +1004,9 @@ static int scmi_perf_message_handler(fwk_id_t protocol_id, fwk_id_t service_id, const uint32_t *payload, size_t payload_size, unsigned int message_id) { int32_t return_value; +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + int status; +#endif static_assert(FWK_ARRAY_SIZE(handler_table) == FWK_ARRAY_SIZE(payload_size_table), @@ -970,6 +1023,17 @@ static int scmi_perf_message_handler(fwk_id_t protocol_id, fwk_id_t service_id, goto error; } +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + status = scmi_perf_permissions_handler(service_id, payload, message_id); + if (status != FWK_SUCCESS) { + if (status == FWK_E_PARAM) + return_value = SCMI_NOT_FOUND; + else + return_value = SCMI_DENIED; + goto error; + } +#endif + return handler_table[message_id](service_id, payload); error: @@ -1218,6 +1282,15 @@ static int scmi_perf_bind(fwk_id_t id, unsigned int round) } #endif +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + status = fwk_module_bind( + FWK_ID_MODULE(FWK_MODULE_IDX_RESOURCE_PERMS), + FWK_ID_API(FWK_MODULE_IDX_RESOURCE_PERMS, MOD_RES_PERM_RESOURCE_PERMS), + &scmi_perf_ctx.res_perms_api); + if (status != FWK_SUCCESS) + return status; +#endif + return fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_DVFS), FWK_ID_API(FWK_MODULE_IDX_DVFS, 0), &scmi_perf_ctx.dvfs_api); } diff --git a/product/juno/scp_ramfw/config_resource_perms.c b/product/juno/scp_ramfw/config_resource_perms.c index 363d89eff..34748223c 100644 --- a/product/juno/scp_ramfw/config_resource_perms.c +++ b/product/juno/scp_ramfw/config_resource_perms.c @@ -42,7 +42,7 @@ static struct mod_res_agent_protocol_permissions /* PSCI agent has no access to clock protocol */ [AGENT_IDX(JUNO_SCMI_AGENT_IDX_PSCI)] = { - .protocols = MOD_RES_PERMS_SCMI_CLOCK_PROTOCOL_DENIED, + .protocols = MOD_RES_PERMS_SCMI_CLOCK_PROTOCOL_DENIED, }, }; @@ -74,7 +74,26 @@ static struct mod_res_agent_msg_permissions agent_msg_permissions[] = { .messages[MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX] = 0x0, .messages[MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0, .messages[MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0, - .messages[MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = + ((1 << (MOD_SCMI_PERF_DOMAIN_ATTRIBUTES - + MOD_RES_PERMS_SCMI_PERF_BITMASK_IDX)) | + /* DESCRIBE_LEVELS is required for some reason ... */ + (0 << (MOD_SCMI_PERF_DESCRIBE_LEVELS - + MOD_RES_PERMS_SCMI_PERF_BITMASK_IDX)) | + (1 << (MOD_SCMI_PERF_LIMITS_SET - + MOD_RES_PERMS_SCMI_PERF_BITMASK_IDX)) | + (1 << (MOD_SCMI_PERF_LIMITS_GET - + MOD_RES_PERMS_SCMI_PERF_BITMASK_IDX)) | + (1 << (MOD_SCMI_PERF_LEVEL_SET - + MOD_RES_PERMS_SCMI_PERF_BITMASK_IDX)) | + (1 << (MOD_SCMI_PERF_LEVEL_GET - + MOD_RES_PERMS_SCMI_PERF_BITMASK_IDX)) | + (1 << (MOD_SCMI_PERF_NOTIFY_LIMITS - + MOD_RES_PERMS_SCMI_PERF_BITMASK_IDX)) | + (1 << (MOD_SCMI_PERF_NOTIFY_LEVEL - + MOD_RES_PERMS_SCMI_PERF_BITMASK_IDX)) | + (1 << (MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL - + MOD_RES_PERMS_SCMI_PERF_BITMASK_IDX))), /* Clocks, no access */ .messages[MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = 0xff, .messages[MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0, @@ -111,7 +130,6 @@ static mod_res_perms_t scmi_clock_perms[] /* 4, SCMI_CLOCK_DESCRIBE_RATES */ [AGENT_IDX(JUNO_SCMI_AGENT_IDX_OSPM)] = { [MOD_RES_PERMS_SCMI_CLOCK_ATTRIBUTES_IDX][0] = 0x0, - [MOD_RES_PERMS_SCMI_CLOCK_DESCRIBE_RATE_IDX][0] = 0x0, /* * Clocks 0, 1, 2, 4 do not allow set commands, * Clocks 3 and 5 allow rate_set/config_set @@ -121,14 +139,15 @@ static mod_res_perms_t scmi_clock_perms[] [MOD_RES_PERMS_SCMI_CLOCK_RATE_GET_IDX][0] = ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)), [MOD_RES_PERMS_SCMI_CLOCK_CONFIG_SET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_CLOCK_DESCRIBE_RATE_IDX][0] = 0x0, }, [AGENT_IDX(JUNO_SCMI_AGENT_IDX_PSCI)] = { /* No access to clocks for PSCI agent, so bits [4:0] set */ [MOD_RES_PERMS_SCMI_CLOCK_ATTRIBUTES_IDX][0] = 0x1f, - [MOD_RES_PERMS_SCMI_CLOCK_DESCRIBE_RATE_IDX][0] = 0x1f, [MOD_RES_PERMS_SCMI_CLOCK_RATE_SET_IDX][0] = 0x1f, [MOD_RES_PERMS_SCMI_CLOCK_RATE_GET_IDX][0] = 0x1f, [MOD_RES_PERMS_SCMI_CLOCK_CONFIG_SET_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_DESCRIBE_RATE_IDX][0] = 0x1f, }, }; @@ -165,11 +184,68 @@ static mod_res_perms_t }, }; +/* + * We are tracking 9 SCMI Performance Protocol commands + * + * 0, SCMI_PERF_DOMAIN_ATTRIBUTES + * 1, SCMI_PERF_DESCRIBE_LEVELS + * 2, SCMI_PERF_LIMITS_SET + * 3, SCMI_PERF_LIMITS_GET + * 4, SCMI_PERF_LEVEL_SET + * 5, SCMI_PERF_LEVEL_GET + * 6, SCMI_PERF_NOTIFY_LIMITS + * 7, SCMI_PERF_NOTIFY_LEVEL + * 8, SCMI_PERF_DESCRIBE_FAST_CHANNEL + */ +#define JUNO_PERF_RESOURCE_CMDS 9 +#define JUNO_PERF_RESOURCE_ELEMENTS \ + ((DVFS_ELEMENT_IDX_COUNT >> MOD_RES_PERMS_TYPE_SHIFT) + 1) +static mod_res_perms_t + scmi_perf_perms[][JUNO_PERF_RESOURCE_CMDS][JUNO_PERF_RESOURCE_ELEMENTS] = { + /* SCMI_PROTOCOL_ID_PERF */ + /* 0, SCMI_PERF_DOMAIN_ATTRIBUTES */ + /* 1, SCMI_PERF_DESCRIBE_LEVELS */ + /* 2, SCMI_PERF_LIMITS_SET */ + /* 3, SCMI_PERF_LIMITS_GET */ + /* 4, SCMI_PERF_LEVEL_SET */ + /* 5, SCMI_PERF_LEVEL_GET */ + /* 6, SCMI_PERF_NOTIFY_LIMITS */ + /* 7, SCMI_PERF_NOTIFY_LEVEL */ + /* 8, SCMI_PERF_DESCRIBE_FAST_CHANNEL */ + /* + * For Juno, resource_id == performance domain_id + * see mod_scmi_perf_domain_config domains[] + */ + [AGENT_IDX(JUNO_SCMI_AGENT_IDX_OSPM)] = { + [MOD_RES_PERMS_SCMI_PERF_ATTRIBUTES_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_PERF_DESCRIBE_LEVELS_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_PERF_LIMITS_SET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_PERF_LIMITS_GET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_PERF_LEVEL_SET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_PERF_LEVEL_GET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_PERF_NOTIFY_LIMITS_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_PERF_NOTIFY_LEVEL_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_PERF_DESCRIBE_FAST_CHANNEL_IDX][0] = 0x0, + }, + [AGENT_IDX(JUNO_SCMI_AGENT_IDX_PSCI)] = { + [MOD_RES_PERMS_SCMI_PERF_ATTRIBUTES_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_PERF_DESCRIBE_LEVELS_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_PERF_LIMITS_SET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_PERF_LIMITS_GET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_PERF_LEVEL_SET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_PERF_LEVEL_GET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_PERF_NOTIFY_LIMITS_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_PERF_NOTIFY_LEVEL_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_PERF_DESCRIBE_FAST_CHANNEL_IDX][0] = 0x0, + }, +}; + static struct mod_res_agent_permission agent_permissions = { .agent_protocol_permissions = agent_protocol_permissions, .agent_msg_permissions = agent_msg_permissions, .scmi_clock_perms = &scmi_clock_perms[0][0][0], .scmi_pd_perms = &scmi_pd_perms[0][0][0], + .scmi_perf_perms = &scmi_perf_perms[0][0][0], }; struct fwk_module_config config_resource_perms = { diff --git a/product/juno/scp_ramfw/config_scmi_perf.c b/product/juno/scp_ramfw/config_scmi_perf.c index b1deaecc4..b8a7ec76d 100644 --- a/product/juno/scp_ramfw/config_scmi_perf.c +++ b/product/juno/scp_ramfw/config_scmi_perf.c @@ -27,11 +27,6 @@ static const struct mod_scmi_perf_domain_config domains[] = { [DVFS_ELEMENT_IDX_LITTLE] = { - .permissions = &(const uint32_t[]) { - [JUNO_SCMI_AGENT_IDX_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL | - MOD_SCMI_PERF_PERMS_SET_LIMITS, - [JUNO_SCMI_AGENT_IDX_PSCI] = 0 /* No Access */, - }, #ifdef BUILD_HAS_FAST_CHANNELS .fast_channels_addr_scp = (uint64_t[]) { [MOD_SMCI_PERF_FAST_CHANNEL_LEVEL_SET] = SCMI_FAST_CHANNEL_BASE @@ -79,11 +74,6 @@ static const struct mod_scmi_perf_domain_config domains[] = { #endif }, [DVFS_ELEMENT_IDX_BIG] = { - .permissions = &(const uint32_t[]) { - [JUNO_SCMI_AGENT_IDX_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL | - MOD_SCMI_PERF_PERMS_SET_LIMITS, - [JUNO_SCMI_AGENT_IDX_PSCI] = 0 /* No Access */, - }, #ifdef BUILD_HAS_FAST_CHANNELS .fast_channels_addr_scp = (uint64_t[]) { [MOD_SMCI_PERF_FAST_CHANNEL_LEVEL_SET] = SCMI_FAST_CHANNEL_BASE @@ -131,11 +121,6 @@ static const struct mod_scmi_perf_domain_config domains[] = { #endif }, [DVFS_ELEMENT_IDX_GPU] = { - .permissions = &(const uint32_t[]) { - [JUNO_SCMI_AGENT_IDX_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL | - MOD_SCMI_PERF_PERMS_SET_LIMITS, - [JUNO_SCMI_AGENT_IDX_PSCI] = 0 /* No Access */, - }, #ifdef BUILD_HAS_FAST_CHANNELS .fast_channels_addr_scp = (uint64_t[]) { [MOD_SMCI_PERF_FAST_CHANNEL_LEVEL_SET] = SCMI_FAST_CHANNEL_BASE diff --git a/product/rdn1e1/include/scp_rdn1e1_scmi.h b/product/rdn1e1/include/scp_rdn1e1_scmi.h index ac7da1fb2..ab30a53af 100644 --- a/product/rdn1e1/include/scp_rdn1e1_scmi.h +++ b/product/rdn1e1/include/scp_rdn1e1_scmi.h @@ -16,6 +16,7 @@ enum scp_rdn1e1_scmi_agent_id { /* 0 is reserved for the platform */ SCP_SCMI_AGENT_ID_OSPM = 1, SCP_SCMI_AGENT_ID_PSCI, + SCP_SCMI_AGENT_ID_COUNT, }; /* SCMI service indexes */ diff --git a/product/rdn1e1/scp_ramfw/config_resource_perms.c b/product/rdn1e1/scp_ramfw/config_resource_perms.c new file mode 100644 index 000000000..e326d49cb --- /dev/null +++ b/product/rdn1e1/scp_ramfw/config_resource_perms.c @@ -0,0 +1,166 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config_clock.h" +#include "scp_rdn1e1_scmi.h" + +#include +#include + +#include +#include +#include +#include +#include + +/*! + * If the agent wants to modify permissions at run-time these tables + * must be allocated in writable memory. + */ + +/*! + * Agent 0 gets access to all resources. + */ +#define AGENT_IDX(agent_id) (agent_id - 1) + +/*! + * Note that permissions are denied when a bit is set. + */ +static struct mod_res_agent_protocol_permissions + agent_protocol_permissions[] = { + [AGENT_IDX(SCP_SCMI_AGENT_ID_OSPM)] = { + .protocols = MOD_RES_PERMS_SCMI_ALL_PROTOCOLS_ALLOWED, + }, + + /* PSCI agent has no access to clock protocol */ + [AGENT_IDX(SCP_SCMI_AGENT_ID_PSCI)] = { + .protocols = MOD_RES_PERMS_SCMI_CLOCK_PROTOCOL_DENIED, + }, +}; + +/* + * Messages have an index offset from 0x3 as all agents can access + * the VERSION/ATTRIBUTES/MSG_ATTRIBUTES messages for all + * protocols, hence message 0x3 maps to bit[0], message 0x4 maps + * to bit[1], etc. + */ +static struct mod_res_agent_msg_permissions agent_msg_permissions[] = { + [AGENT_IDX(SCP_SCMI_AGENT_ID_OSPM)] = { + /* Example, Base, disable unused msg 12 */ + .messages[MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX] = + (1 << 12), /* Example, Base, disable unused msg 12 */ + /* Power Domain */ + .messages[MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0, + /* System Power Domain */ + .messages[MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0, + /* Performance */ + .messages[MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = 0x0, + /* Clocks */ + .messages[MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = 0x0, + /* Sensors */ + .messages[MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0, + /* Reset Domains */ + .messages[MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0, + }, + + [AGENT_IDX(SCP_SCMI_AGENT_ID_PSCI)] = { + .messages[MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = + ((1 << (MOD_SCMI_PERF_DOMAIN_ATTRIBUTES - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + /* DESCRIBE_LEVELS is required for some reason ... */ + (0 << (MOD_SCMI_PERF_DESCRIBE_LEVELS - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LIMITS_SET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LIMITS_GET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LEVEL_SET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LEVEL_GET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_NOTIFY_LIMITS - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_NOTIFY_LEVEL - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES))), + /* Clocks, no access */ + .messages[MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = 0xff, + .messages[MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0, + }, +}; + +/* + * Protocols have an index offset from SCMI_BASE protocol, 0x10 + * Note that the BASE and SYSTEM_POWER protocols are managed + * on a protocol:command basis, there is no resource permissions + * associated with the protocols. + */ + +/* + * We are tracking 5 SCMI Clock Protocol commands + * + * 0, SCMI_CLOCK_ATTRIBUTES + * 1, SCMI_CLOCK_RATE_GET + * 2, SCMI_CLOCK_RATE_SET + * 3, SCMI_CLOCK_CONFIG_SET + * 4, SCMI_CLOCK_DESCRIBE_RATES + */ +#define RDN1E1_CLOCK_RESOURCE_CMDS 5 +#define RDN1E1_CLOCK_RESOURCE_ELEMENTS \ + ((CLOCK_IDX_COUNT >> MOD_RES_PERMS_TYPE_SHIFT) + 1) +static mod_res_perms_t scmi_clock_perms[][RDN1E1_CLOCK_RESOURCE_CMDS] + [RDN1E1_CLOCK_RESOURCE_ELEMENTS] = { + /* SCMI_PROTOCOL_ID_CLOCK */ + /* 0, SCMI_CLOCK_ATTRIBUTES */ + /* 1, SCMI_CLOCK_RATE_GET */ + /* 2, SCMI_CLOCK_RATE_SET */ + /* 3, SCMI_CLOCK_CONFIG_SET */ + /* 4, SCMI_CLOCK_DESCRIBE_RATES */ + [AGENT_IDX(SCP_SCMI_AGENT_ID_OSPM)] = { + [MOD_RES_PERMS_SCMI_CLOCK_ATTRIBUTES_IDX][0] = 0x0, + /* + * Clocks 0, 1, 2, 4 do not allow set commands, + * Clocks 3 and 5 allow rate_set/config_set + */ + [MOD_RES_PERMS_SCMI_CLOCK_RATE_SET_IDX][0] = + ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)), + [MOD_RES_PERMS_SCMI_CLOCK_RATE_GET_IDX][0] = + ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)), + [MOD_RES_PERMS_SCMI_CLOCK_CONFIG_SET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_CLOCK_DESCRIBE_RATE_IDX][0] = 0x0, + }, + + [AGENT_IDX(SCP_SCMI_AGENT_ID_PSCI)] = { + /* No access to clocks for PSCI agent, set bits [4:0] */ + [MOD_RES_PERMS_SCMI_CLOCK_ATTRIBUTES_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_RATE_SET_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_RATE_GET_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_CONFIG_SET_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_DESCRIBE_RATE_IDX][0] = 0x1f, + }, +}; + +static struct mod_res_agent_permission agent_permissions = { + .agent_protocol_permissions = agent_protocol_permissions, + .agent_msg_permissions = agent_msg_permissions, + .scmi_clock_perms = &scmi_clock_perms[0][0][0], +}; + +struct fwk_module_config config_resource_perms = { + .data = + &(struct mod_res_resource_perms_config){ + .agent_permissions = (uintptr_t)&agent_permissions, + .agent_count = SCP_SCMI_AGENT_ID_COUNT, + .protocol_count = 6, + .clock_count = CLOCK_IDX_COUNT, + }, +}; diff --git a/product/rdn1e1/scp_ramfw/config_scmi_perf.c b/product/rdn1e1/scp_ramfw/config_scmi_perf.c index 44b2abfe7..7954f11ea 100644 --- a/product/rdn1e1/scp_ramfw/config_scmi_perf.c +++ b/product/rdn1e1/scp_ramfw/config_scmi_perf.c @@ -16,18 +16,8 @@ static const struct mod_scmi_perf_domain_config domains[] = { [0] = { - .permissions = &(const uint32_t[]) { - [SCP_SCMI_AGENT_ID_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL | - MOD_SCMI_PERF_PERMS_SET_LIMITS, - [SCP_SCMI_AGENT_ID_PSCI] = MOD_SCMI_PERF_PERMS_NONE, - } }, [1] = { - .permissions = &(const uint32_t[]) { - [SCP_SCMI_AGENT_ID_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL | - MOD_SCMI_PERF_PERMS_SET_LIMITS, - [SCP_SCMI_AGENT_ID_PSCI] = MOD_SCMI_PERF_PERMS_NONE, - } }, }; diff --git a/product/rdn1e1/scp_ramfw/firmware.mk b/product/rdn1e1/scp_ramfw/firmware.mk index f0a2a7bbd..d5402949a 100644 --- a/product/rdn1e1/scp_ramfw/firmware.mk +++ b/product/rdn1e1/scp_ramfw/firmware.mk @@ -8,6 +8,7 @@ BS_FIRMWARE_CPU := cortex-m7 BS_FIRMWARE_HAS_MULTITHREADING := yes BS_FIRMWARE_HAS_NOTIFICATION := yes +BS_FIRMWARE_HAS_RESOURCE_PERMISSIONS := yes BS_FIRMWARE_MODULE_HEADERS_ONLY := BS_FIRMWARE_MODULES := \ @@ -45,7 +46,8 @@ BS_FIRMWARE_MODULES := \ psu \ dvfs \ scmi_perf \ - rdn1e1_system + rdn1e1_system \ + resource_perms BS_FIRMWARE_SOURCES := \ config_system_power.c \ @@ -77,6 +79,7 @@ BS_FIRMWARE_SOURCES := \ config_scmi_perf.c \ config_scmi_apcore.c \ config_apcontext.c \ - config_scmi_power_domain.c + config_scmi_power_domain.c \ + config_resource_perms.c include $(BS_DIR)/firmware.mk diff --git a/product/sgi575/include/scp_sgi575_scmi.h b/product/sgi575/include/scp_sgi575_scmi.h index 53da67cac..f9b0aa718 100644 --- a/product/sgi575/include/scp_sgi575_scmi.h +++ b/product/sgi575/include/scp_sgi575_scmi.h @@ -16,6 +16,7 @@ enum scp_sgi575_scmi_agent_id { /* 0 is reserved for the platform */ SCP_SCMI_AGENT_ID_OSPM = 1, SCP_SCMI_AGENT_ID_PSCI, + SCP_SCMI_AGENT_ID_COUNT, }; /* SCMI service indexes */ diff --git a/product/sgi575/scp_ramfw/config_resource_perms.c b/product/sgi575/scp_ramfw/config_resource_perms.c new file mode 100644 index 000000000..164d840bd --- /dev/null +++ b/product/sgi575/scp_ramfw/config_resource_perms.c @@ -0,0 +1,166 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config_clock.h" +#include "scp_sgi575_scmi.h" + +#include +#include + +#include +#include +#include +#include +#include + +/*! + * If the agent wants to modify permissions at run-time these tables + * must be allocated in writable memory. + */ + +/*! + * Agent 0 gets access to all resources. + */ +#define AGENT_IDX(agent_id) (agent_id - 1) + +/*! + * Note that permissions are denied when a bit is set. + */ +static struct mod_res_agent_protocol_permissions + agent_protocol_permissions[] = { + [AGENT_IDX(SCP_SCMI_AGENT_ID_OSPM)] = { + .protocols = MOD_RES_PERMS_SCMI_ALL_PROTOCOLS_ALLOWED, + }, + + /* PSCI agent has no access to clock protocol */ + [AGENT_IDX(SCP_SCMI_AGENT_ID_PSCI)] = { + .protocols = MOD_RES_PERMS_SCMI_CLOCK_PROTOCOL_DENIED, + }, +}; + +/* + * Messages have an index offset from 0x3 as all agents can access + * the VERSION/ATTRIBUTES/MSG_ATTRIBUTES messages for all + * protocols, hence message 0x3 maps to bit[0], message 0x4 maps + * to bit[1], etc. + */ +static struct mod_res_agent_msg_permissions agent_msg_permissions[] = { + [AGENT_IDX(SCP_SCMI_AGENT_ID_OSPM)] = { + /* Example, Base, disable unused msg 12 */ + .messages[MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX] = + (1 << 12), /* Example, Base, disable unused msg 12 */ + /* Power Domain */ + .messages[MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0, + /* System Power Domain */ + .messages[MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0, + /* Performance */ + .messages[MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = 0x0, + /* Clocks */ + .messages[MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = 0x0, + /* Sensors */ + .messages[MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0, + /* Reset Domains */ + .messages[MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0, + }, + + [AGENT_IDX(SCP_SCMI_AGENT_ID_PSCI)] = { + .messages[MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = + ((1 << (MOD_SCMI_PERF_DOMAIN_ATTRIBUTES - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + /* DESCRIBE_LEVELS is required for some reason ... */ + (0 << (MOD_SCMI_PERF_DESCRIBE_LEVELS - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LIMITS_SET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LIMITS_GET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LEVEL_SET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LEVEL_GET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_NOTIFY_LIMITS - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_NOTIFY_LEVEL - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES))), + /* Clocks, no access */ + .messages[MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = 0xff, + .messages[MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0, + }, +}; + +/* + * Protocols have an index offset from SCMI_BASE protocol, 0x10 + * Note that the BASE and SYSTEM_POWER protocols are managed + * on a protocol:command basis, there is no resource permissions + * associated with the protocols. + */ + +/* + * We are tracking 5 SCMI Clock Protocol commands + * + * 0, SCMI_CLOCK_ATTRIBUTES + * 1, SCMI_CLOCK_RATE_GET + * 2, SCMI_CLOCK_RATE_SET + * 3, SCMI_CLOCK_CONFIG_SET + * 4, SCMI_CLOCK_DESCRIBE_RATES + */ +#define SGI575_CLOCK_RESOURCE_CMDS 5 +#define SGI575_CLOCK_RESOURCE_ELEMENTS \ + ((CLOCK_IDX_COUNT >> MOD_RES_PERMS_TYPE_SHIFT) + 1) +static mod_res_perms_t + scmi_clock_perms[][SGI575_CLOCK_RESOURCE_CMDS] + [SGI575_CLOCK_RESOURCE_ELEMENTS] = { + /* SCMI_PROTOCOL_ID_CLOCK */ + /* 0, SCMI_CLOCK_ATTRIBUTES */ + /* 1, SCMI_CLOCK_RATE_GET */ + /* 2, SCMI_CLOCK_RATE_SET */ + /* 3, SCMI_CLOCK_CONFIG_SET */ + /* 4, SCMI_CLOCK_DESCRIBE_RATES */ + [AGENT_IDX(SCP_SCMI_AGENT_ID_OSPM)] = { + [MOD_RES_PERMS_SCMI_CLOCK_ATTRIBUTES_IDX][0] = 0x0, + /* + * Clocks 0, 1, 2, 4 do not allow set commands, + * Clocks 3 and 5 allow rate_set/config_set + */ + [MOD_RES_PERMS_SCMI_CLOCK_RATE_SET_IDX][0] = + ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)), + [MOD_RES_PERMS_SCMI_CLOCK_RATE_GET_IDX][0] = + ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)), + [MOD_RES_PERMS_SCMI_CLOCK_CONFIG_SET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_CLOCK_DESCRIBE_RATE_IDX][0] = 0x0, + }, + [AGENT_IDX(SCP_SCMI_AGENT_ID_PSCI)] = { + /* No access to clocks for PSCI agent, so bits [4:0] set */ + [MOD_RES_PERMS_SCMI_CLOCK_ATTRIBUTES_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_RATE_SET_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_RATE_GET_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_CONFIG_SET_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_DESCRIBE_RATE_IDX][0] = 0x1f, + }, +}; + +static struct mod_res_agent_permission agent_permissions = { + .agent_protocol_permissions = agent_protocol_permissions, + .agent_msg_permissions = agent_msg_permissions, + .scmi_clock_perms = &scmi_clock_perms[0][0][0], +}; + +struct fwk_module_config config_resource_perms = { + .data = + &(struct mod_res_resource_perms_config){ + .agent_permissions = (uintptr_t)&agent_permissions, + .agent_count = SCP_SCMI_AGENT_ID_COUNT, + .protocol_count = 6, + .clock_count = CLOCK_IDX_COUNT, + }, +}; diff --git a/product/sgi575/scp_ramfw/config_scmi_perf.c b/product/sgi575/scp_ramfw/config_scmi_perf.c index bb9b94f5a..81e6d692f 100644 --- a/product/sgi575/scp_ramfw/config_scmi_perf.c +++ b/product/sgi575/scp_ramfw/config_scmi_perf.c @@ -16,18 +16,8 @@ static const struct mod_scmi_perf_domain_config domains[] = { [0] = { - .permissions = &(const uint32_t[]) { - [SCP_SCMI_AGENT_ID_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL | - MOD_SCMI_PERF_PERMS_SET_LIMITS, - [SCP_SCMI_AGENT_ID_PSCI] = MOD_SCMI_PERF_PERMS_NONE, - } }, [1] = { - .permissions = &(const uint32_t[]) { - [SCP_SCMI_AGENT_ID_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL | - MOD_SCMI_PERF_PERMS_SET_LIMITS, - [SCP_SCMI_AGENT_ID_PSCI] = MOD_SCMI_PERF_PERMS_NONE, - } }, }; diff --git a/product/sgi575/scp_ramfw/firmware.mk b/product/sgi575/scp_ramfw/firmware.mk index f61397c9b..ead41a033 100644 --- a/product/sgi575/scp_ramfw/firmware.mk +++ b/product/sgi575/scp_ramfw/firmware.mk @@ -11,6 +11,7 @@ BS_FIRMWARE_CPU := cortex-m7 BS_FIRMWARE_HAS_MULTITHREADING := yes BS_FIRMWARE_HAS_NOTIFICATION := yes +BS_FIRMWARE_HAS_RESOURCE_PERMISSIONS := yes BS_FIRMWARE_MODULE_HEADERS_ONLY := BS_FIRMWARE_MODULES := \ @@ -47,7 +48,8 @@ BS_FIRMWARE_MODULES := \ scmi_system_power \ ssc \ system_info \ - scmi_apcore + scmi_apcore \ + resource_perms BS_FIRMWARE_SOURCES := \ rtx_config.c \ @@ -79,6 +81,7 @@ BS_FIRMWARE_SOURCES := \ config_ssc.c \ config_system_info.c \ config_apcontext.c \ - config_scmi_power_domain.c + config_scmi_power_domain.c \ + config_resource_perms.c include $(BS_DIR)/firmware.mk diff --git a/product/sgm775/scp_ramfw/config_resource_perms.c b/product/sgm775/scp_ramfw/config_resource_perms.c index a8159ca34..b7189af27 100644 --- a/product/sgm775/scp_ramfw/config_resource_perms.c +++ b/product/sgm775/scp_ramfw/config_resource_perms.c @@ -66,14 +66,33 @@ static struct mod_res_agent_msg_permissions agent_msg_permissions[] = { .messages[0] = 0x0, /* Base */ .messages[1] = 0x0, /* Power Domain */ .messages[2] = 0x0, /* System Power Domain */ - .messages[3] = 0x0, - /* - * sgm775 denies access to CONFIG_SET - */ + .messages[3] = + ((1 << (MOD_SCMI_PERF_DOMAIN_ATTRIBUTES - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + /* DESCRIBE_LEVELS is required for some reason ... */ + (0 << (MOD_SCMI_PERF_DESCRIBE_LEVELS - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LIMITS_SET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LIMITS_GET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LEVEL_SET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LEVEL_GET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_NOTIFY_LIMITS - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_NOTIFY_LEVEL - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES))), + /* + * sgm775 denies access to CONFIG_SET + */ .messages[4] = (1 << (MOD_SCMI_CLOCK_CONFIG_SET - MOD_SCMI_CLOCK_ATTRIBUTES)), .messages[5] = 0x0, /* Sensors */ - }, + }, }; static struct mod_res_agent_permission agent_permissions = { diff --git a/product/sgm775/scp_ramfw/config_scmi_perf.c b/product/sgm775/scp_ramfw/config_scmi_perf.c index c781b2f48..deee66c4d 100644 --- a/product/sgm775/scp_ramfw/config_scmi_perf.c +++ b/product/sgm775/scp_ramfw/config_scmi_perf.c @@ -17,25 +17,10 @@ static const struct mod_scmi_perf_domain_config domains[] = { [DVFS_ELEMENT_IDX_LITTLE] = { - .permissions = &(const uint32_t[]) { - [SCMI_AGENT_ID_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL | - MOD_SCMI_PERF_PERMS_SET_LIMITS, - [SCMI_AGENT_ID_PSCI] = MOD_SCMI_PERF_PERMS_NONE, - } }, [DVFS_ELEMENT_IDX_BIG] = { - .permissions = &(const uint32_t[]) { - [SCMI_AGENT_ID_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL | - MOD_SCMI_PERF_PERMS_SET_LIMITS, - [SCMI_AGENT_ID_PSCI] = MOD_SCMI_PERF_PERMS_NONE, - } }, [DVFS_ELEMENT_IDX_GPU] = { - .permissions = &(const uint32_t[]) { - [SCMI_AGENT_ID_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL | - MOD_SCMI_PERF_PERMS_SET_LIMITS, - [SCMI_AGENT_ID_PSCI] = MOD_SCMI_PERF_PERMS_NONE, - } }, }; diff --git a/product/sgm776/scp_ramfw/config_resource_perms.c b/product/sgm776/scp_ramfw/config_resource_perms.c index 99c5c3529..e93981085 100644 --- a/product/sgm776/scp_ramfw/config_resource_perms.c +++ b/product/sgm776/scp_ramfw/config_resource_perms.c @@ -66,7 +66,26 @@ static struct mod_res_agent_msg_permissions agent_msg_permissions[] = { .messages[0] = 0x0, /* Base */ .messages[1] = 0x0, /* Power Domain */ .messages[2] = 0x0, /* System Power Domain */ - .messages[3] = 0x0, + .messages[3] = + ((1 << (MOD_SCMI_PERF_DOMAIN_ATTRIBUTES - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + /* DESCRIBE_LEVELS is required for some reason ... */ + (0 << (MOD_SCMI_PERF_DESCRIBE_LEVELS - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LIMITS_SET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LIMITS_GET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LEVEL_SET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LEVEL_GET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_NOTIFY_LIMITS - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_NOTIFY_LEVEL - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES))), /* * sgm776 denies access to CONFIG_SET */ diff --git a/product/sgm776/scp_ramfw/config_scmi_perf.c b/product/sgm776/scp_ramfw/config_scmi_perf.c index 1e58347b6..5f3ace118 100644 --- a/product/sgm776/scp_ramfw/config_scmi_perf.c +++ b/product/sgm776/scp_ramfw/config_scmi_perf.c @@ -16,25 +16,10 @@ static const struct mod_scmi_perf_domain_config domains[] = { [DVFS_ELEMENT_IDX_LITTLE] = { - .permissions = &(const uint32_t[]) { - [SCMI_AGENT_ID_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL | - MOD_SCMI_PERF_PERMS_SET_LIMITS, - [SCMI_AGENT_ID_PSCI] = MOD_SCMI_PERF_PERMS_NONE, - } }, [DVFS_ELEMENT_IDX_BIG] = { - .permissions = &(const uint32_t[]) { - [SCMI_AGENT_ID_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL | - MOD_SCMI_PERF_PERMS_SET_LIMITS, - [SCMI_AGENT_ID_PSCI] = MOD_SCMI_PERF_PERMS_NONE, - } }, [DVFS_ELEMENT_IDX_GPU] = { - .permissions = &(const uint32_t[]) { - [SCMI_AGENT_ID_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL | - MOD_SCMI_PERF_PERMS_SET_LIMITS, - [SCMI_AGENT_ID_PSCI] = MOD_SCMI_PERF_PERMS_NONE, - } }, }; diff --git a/product/tc0/scp_ramfw/config_resource_perms.c b/product/tc0/scp_ramfw/config_resource_perms.c index 22b2fc997..4b88663a6 100644 --- a/product/tc0/scp_ramfw/config_resource_perms.c +++ b/product/tc0/scp_ramfw/config_resource_perms.c @@ -42,31 +42,86 @@ static struct mod_res_agent_protocol_permissions * to bit[1], etc. */ static struct mod_res_agent_msg_permissions agent_msg_permissions[] = { - [AGENT_IDX(SCP_SCMI_AGENT_ID_OSPM)] = { - /* Example, Base, disable unused msg 12 */ - .messages[MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX] = 0x0, - /* Power Domain */ - .messages[MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0, - /* System Power Domain */ - .messages[MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0, - /* Performance */ - .messages[MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = 0x0, - /* - * tc0 denies access to CONFIG_SET - */ - .messages[MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = - MOD_RES_PERMS_ACCESS_DENIED << - (MOD_SCMI_CLOCK_CONFIG_SET - MOD_SCMI_CLOCK_ATTRIBUTES), - /* Sensors */ - .messages[MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0, - /* Reset Domains */ - .messages[MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0, - }, + [AGENT_IDX(SCP_SCMI_AGENT_ID_OSPM)] = { + .messages[MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0, + }, + [AGENT_IDX(SCP_SCMI_AGENT_ID_PSCI)] = { + .messages[MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = + ((1 << (MOD_SCMI_PERF_DOMAIN_ATTRIBUTES - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + /* DESCRIBE_LEVELS is required for some reason ... */ + (0 << (MOD_SCMI_PERF_DESCRIBE_LEVELS - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LIMITS_SET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LIMITS_GET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LEVEL_SET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_LEVEL_GET - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_NOTIFY_LIMITS - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_NOTIFY_LEVEL - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) | + (1 << (MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL - + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES))), + /* Clocks, no access */ + .messages[MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = 0xff, + .messages[MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0, + .messages[MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0, + }, + }; + +/* + * Protocols have an index offset from SCMI_BASE protocol, 0x10 + * Note that the BASE and SYSTEM_POWER protocols are managed + * on a protocol:command basis, there is no resource permissions + * associated with the protocols. + */ +static mod_res_perms_t scmi_clock_perms[][5][1] = { + /* SCMI_PROTOCOL_ID_CLOCK */ + /* 0, SCMI_CLOCK_ATTRIBUTES */ + /* 1, SCMI_CLOCK_RATE_GET */ + /* 2, SCMI_CLOCK_RATE_SET */ + /* 3, SCMI_CLOCK_CONFIG_SET */ + /* 4, SCMI_CLOCK_DESCRIBE_RATES */ + [AGENT_IDX(SCP_SCMI_AGENT_ID_OSPM)] = { + [MOD_RES_PERMS_SCMI_CLOCK_ATTRIBUTES_IDX][0] = 0x0, + /* + * Clocks 0, 1, 2, 4 do not allow set commands, + * Clocks 3 and 5 allow rate_set/config_set + */ + [MOD_RES_PERMS_SCMI_CLOCK_RATE_SET_IDX][0] = + ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)), + [MOD_RES_PERMS_SCMI_CLOCK_RATE_GET_IDX][0] = + ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)), + [MOD_RES_PERMS_SCMI_CLOCK_CONFIG_SET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_CLOCK_DESCRIBE_RATE_IDX][0] = 0x0, + }, + [AGENT_IDX(SCP_SCMI_AGENT_ID_PSCI)] = { + /* No access to clocks for PSCI agent, so bits [4:0] set */ + [MOD_RES_PERMS_SCMI_CLOCK_ATTRIBUTES_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_RATE_SET_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_RATE_GET_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_CONFIG_SET_IDX][0] = 0x1f, + [MOD_RES_PERMS_SCMI_CLOCK_DESCRIBE_RATE_IDX][0] = 0x1f, + }, }; static struct mod_res_agent_permission agent_permissions = { .agent_protocol_permissions = agent_protocol_permissions, .agent_msg_permissions = agent_msg_permissions, + .scmi_clock_perms = &scmi_clock_perms[0][0][0], }; struct fwk_module_config config_resource_perms = { diff --git a/product/tc0/scp_ramfw/config_scmi_perf.c b/product/tc0/scp_ramfw/config_scmi_perf.c index 25b5f515b..61a0c5789 100644 --- a/product/tc0/scp_ramfw/config_scmi_perf.c +++ b/product/tc0/scp_ramfw/config_scmi_perf.c @@ -15,11 +15,6 @@ static const struct mod_scmi_perf_domain_config domains[] = { [0] = { - .permissions = &(const uint32_t[]) { - [SCP_SCMI_AGENT_ID_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL | - MOD_SCMI_PERF_PERMS_SET_LIMITS, - [SCP_SCMI_AGENT_ID_PSCI] = MOD_SCMI_PERF_PERMS_NONE, - } }, }; -- GitLab From 1d9d8b5e262e06ded37234b2a49b5868e0256253 Mon Sep 17 00:00:00 2001 From: Jim Quigley Date: Wed, 17 Jun 2020 12:23:08 +0100 Subject: [PATCH 8/9] SCMI: Sensor Protocol Permissions This patch adds the SCMI Sensor Protocol Resource Permissions management. Change-Id: Idae4b95ce2b066b6e3652d38129b4b1c048e2588 Signed-off-by: Jim Quigley --- .../include/mod_resource_perms.h | 19 +++++ module/scmi_sensor/src/mod_scmi_sensor.c | 71 +++++++++++++++++++ .../juno/scp_ramfw/config_resource_perms.c | 37 ++++++++++ 3 files changed, 127 insertions(+) diff --git a/module/resource_perms/include/mod_resource_perms.h b/module/resource_perms/include/mod_resource_perms.h index d38f1676c..a6085ff89 100644 --- a/module/resource_perms/include/mod_resource_perms.h +++ b/module/resource_perms/include/mod_resource_perms.h @@ -229,6 +229,25 @@ enum mod_res_perf_permissions_idx { MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL - MOD_RES_PERMS_PERF_PERMS_OFFSET, }; +/*! + * \brief SCMI Sensor Protocol Message index offset + */ +#define MOD_RES_PERMS_SENSOR_PERMS_OFFSET MOD_SCMI_SENSOR_DESCRIPTION_GET + +/*! + * \brief SCMI Sensor Protocol Message Indices + */ +enum mod_res_sensor_permissions_idx { + MOD_RES_PERMS_SCMI_SENSOR_DESCRIPTION_GET_IDX = + MOD_SCMI_PERF_DOMAIN_ATTRIBUTES - MOD_RES_PERMS_SENSOR_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_SENSOR_CONFIG_SET_IDX = + MOD_SCMI_SENSOR_CONFIG_SET - MOD_RES_PERMS_SENSOR_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_SENSOR_TRIP_POINT_SET_IDX = + MOD_SCMI_SENSOR_TRIP_POINT_SET - MOD_RES_PERMS_SENSOR_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_SENSOR_READING_GET_IDX = + MOD_SCMI_SENSOR_READING_GET - MOD_RES_PERMS_SENSOR_PERMS_OFFSET, +}; + /*! * \brief SCMI Agent Permissions * diff --git a/module/scmi_sensor/src/mod_scmi_sensor.c b/module/scmi_sensor/src/mod_scmi_sensor.c index d7e5df5a8..4bbe96d4c 100644 --- a/module/scmi_sensor/src/mod_scmi_sensor.c +++ b/module/scmi_sensor/src/mod_scmi_sensor.c @@ -10,6 +10,9 @@ #include +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS +# include +#endif #include #include @@ -47,6 +50,11 @@ struct scmi_sensor_ctx { /* Pointer to a table of sensor operations */ struct sensor_operations *sensor_ops_table; + +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + /* SCMI Resource Permissions API */ + const struct mod_res_permissions_api *res_perms_api; +#endif }; static int scmi_sensor_protocol_version_handler(fwk_id_t service_id, @@ -405,6 +413,52 @@ static int scmi_sensor_get_scmi_protocol_id(fwk_id_t protocol_id, return FWK_SUCCESS; } +/* + * SCMI Resource Permissions handler + */ +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS +static unsigned int get_sensor_id(const uint32_t *payload) +{ + /* + * Every SCMI Performance message is formatted with the sensor ID + * as the first message element. We will use the reading_get + * message as a basic format to retrieve the sensor ID to avoid + * unnecessary code. + */ + const struct scmi_sensor_protocol_reading_get_a2p *parameters = + (const struct scmi_sensor_protocol_reading_get_a2p *)payload; + return parameters->sensor_id; +} + +static int scmi_sensor_permissions_handler( + fwk_id_t service_id, + const uint32_t *payload, + size_t payload_size, + unsigned int message_id) +{ + enum mod_res_perms_permissions perms; + unsigned int agent_id, sensor_id; + int status; + + status = scmi_sensor_ctx.scmi_api->get_agent_id(service_id, &agent_id); + if (status != FWK_SUCCESS) + return FWK_E_ACCESS; + + if (message_id < 3) + return FWK_SUCCESS; + + sensor_id = get_sensor_id(payload); + + perms = scmi_sensor_ctx.res_perms_api->agent_has_resource_permission( + agent_id, MOD_SCMI_PROTOCOL_ID_SENSOR, message_id, sensor_id); + + if (perms == MOD_RES_PERMS_ACCESS_ALLOWED) + return FWK_SUCCESS; + else + return FWK_E_ACCESS; +} +#endif + static int scmi_sensor_message_handler(fwk_id_t protocol_id, fwk_id_t service_id, const uint32_t *payload, @@ -429,6 +483,14 @@ static int scmi_sensor_message_handler(fwk_id_t protocol_id, goto error; } +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + if (scmi_sensor_permissions_handler( + service_id, payload, payload_size, message_id) != FWK_SUCCESS) { + return_value = SCMI_DENIED; + goto error; + } +#endif + return handler_table[message_id](service_id, payload); error: @@ -503,6 +565,15 @@ static int scmi_sensor_bind(fwk_id_t id, unsigned int round) return status; } +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + status = fwk_module_bind( + FWK_ID_MODULE(FWK_MODULE_IDX_RESOURCE_PERMS), + FWK_ID_API(FWK_MODULE_IDX_RESOURCE_PERMS, MOD_RES_PERM_RESOURCE_PERMS), + &scmi_sensor_ctx.res_perms_api); + if (status != FWK_SUCCESS) + return status; +#endif + return FWK_SUCCESS; } diff --git a/product/juno/scp_ramfw/config_resource_perms.c b/product/juno/scp_ramfw/config_resource_perms.c index 34748223c..606ad00ec 100644 --- a/product/juno/scp_ramfw/config_resource_perms.c +++ b/product/juno/scp_ramfw/config_resource_perms.c @@ -240,12 +240,49 @@ static mod_res_perms_t }, }; +/* + * We are tracking 4 SCMI Sensor Protocol commands + * + * 0, SCMI_SENSOR_DESCRIPTION_GET + * 1, SCMI_SENSOR_CONFIG_SET + * 2, SCMI_SENSOR_TRIP_POINT_SET + * 3, SCMI_SENSOR_READING_GET + */ +#define JUNO_SENSOR_RESOURCE_CMDS 4 +#define JUNO_SENSOR_RESOURCE_ELEMENTS \ + ((MOD_JUNO_R1_R2_SENSOR_IDX_COUNT >> MOD_RES_PERMS_TYPE_SHIFT) + 1) +static mod_res_perms_t + scmi_sensor_perms[][JUNO_SENSOR_RESOURCE_CMDS] + [JUNO_SENSOR_RESOURCE_ELEMENTS] = { + /* SCMI_PROTOCOL_ID_SENSOR */ + /* 0, SCMI_SENSOR_DESCRIPTION_GET */ + /* 1, SCMI_SENSOR_CONFIG_SET */ + /* 2, SCMI_SENSOR_TRIP_POINT_SET */ + /* 3, SCMI_SENSOR_READING_GET */ + [AGENT_IDX(JUNO_SCMI_AGENT_IDX_OSPM)] = { + [MOD_RES_PERMS_SCMI_SENSOR_DESCRIPTION_GET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_SENSOR_CONFIG_SET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_SENSOR_TRIP_POINT_SET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_SENSOR_READING_GET_IDX][0] = 0x0, + }, + [AGENT_IDX(JUNO_SCMI_AGENT_IDX_PSCI)] = { + [MOD_RES_PERMS_SCMI_SENSOR_DESCRIPTION_GET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_SENSOR_CONFIG_SET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_SENSOR_TRIP_POINT_SET_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_SENSOR_READING_GET_IDX][0] = 0x0, + }, + }; + +/* + * Juno Platform Permissions + */ static struct mod_res_agent_permission agent_permissions = { .agent_protocol_permissions = agent_protocol_permissions, .agent_msg_permissions = agent_msg_permissions, .scmi_clock_perms = &scmi_clock_perms[0][0][0], .scmi_pd_perms = &scmi_pd_perms[0][0][0], .scmi_perf_perms = &scmi_perf_perms[0][0][0], + .scmi_sensor_perms = &scmi_sensor_perms[0][0][0], }; struct fwk_module_config config_resource_perms = { -- GitLab From dd4fdf1148aa12e5eae09247a77eafdfd55483b9 Mon Sep 17 00:00:00 2001 From: Jim Quigley Date: Fri, 3 Jul 2020 13:09:04 +0100 Subject: [PATCH 9/9] SCMI: Reset Domain Protocol Permissions This patch adds the SCMI Reset Domain Resource Permissions management. Change-Id: If36ad0891f85b2dd24f8757a277f91ad49e641c5 Signed-off-by: Jim Quigley --- .../include/mod_resource_perms.h | 18 +++++ .../src/mod_scmi_reset_domain.c | 67 +++++++++++++++++++ .../juno/scp_ramfw/config_resource_perms.c | 43 ++++++++++++ 3 files changed, 128 insertions(+) diff --git a/module/resource_perms/include/mod_resource_perms.h b/module/resource_perms/include/mod_resource_perms.h index a6085ff89..9d223651f 100644 --- a/module/resource_perms/include/mod_resource_perms.h +++ b/module/resource_perms/include/mod_resource_perms.h @@ -248,6 +248,24 @@ enum mod_res_sensor_permissions_idx { MOD_SCMI_SENSOR_READING_GET - MOD_RES_PERMS_SENSOR_PERMS_OFFSET, }; +/*! + * \brief SCMI Reset Domain Management Protocol Message index offset + */ +#define MOD_RES_PERMS_RESET_DOMAIN_PERMS_OFFSET MOD_SCMI_RESET_DOMAIN_ATTRIBUTES + +/*! + * \brief SCMI Reset Domain Management Protocol Message Indices + */ +enum mod_res_reset_domain_permissions_idx { + MOD_RES_PERMS_SCMI_RESET_DOMAIN_ATTRIBUTES_IDX = + MOD_SCMI_RESET_DOMAIN_ATTRIBUTES - + MOD_RES_PERMS_RESET_DOMAIN_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_RESET_DOMAIN_RESET_REQUEST_IDX = + MOD_SCMI_RESET_REQUEST - MOD_RES_PERMS_RESET_DOMAIN_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_RESET_DOMAIN_RESET_NOTIFY_IDX = + MOD_SCMI_RESET_NOTIFY - MOD_RES_PERMS_RESET_DOMAIN_PERMS_OFFSET, +}; + /*! * \brief SCMI Agent Permissions * diff --git a/module/scmi_reset_domain/src/mod_scmi_reset_domain.c b/module/scmi_reset_domain/src/mod_scmi_reset_domain.c index 4baad1646..648190359 100644 --- a/module/scmi_reset_domain/src/mod_scmi_reset_domain.c +++ b/module/scmi_reset_domain/src/mod_scmi_reset_domain.c @@ -17,6 +17,9 @@ #include #include #include +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS +# include +#endif #include #include #include @@ -46,6 +49,11 @@ struct scmi_rd_ctx { struct agent_notifications **agent_notifications; fwk_id_t notification_id; #endif + +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + /* SCMI Resource Permissions API */ + const struct mod_res_permissions_api *res_perms_api; +#endif }; static int protocol_version_handler(fwk_id_t service_id, @@ -465,6 +473,48 @@ static void scmi_reset_issued_notify(uint32_t domain_id, } } #endif + +/* + * SCMI Resource Permissions handler + */ +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS +static unsigned int get_reset_domain_id(const uint32_t *payload) +{ + struct scmi_reset_domain_request_a2p *params; + + params = (struct scmi_reset_domain_request_a2p *)payload; + return params->domain_id; +} + +static int scmi_reset_domain_permissions_handler( + fwk_id_t service_id, + const uint32_t *payload, + size_t payload_size, + unsigned int message_id) +{ + enum mod_res_perms_permissions perms; + unsigned int agent_id, domain_id; + int status; + + status = scmi_rd_ctx.scmi_api->get_agent_id(service_id, &agent_id); + if (status != FWK_SUCCESS) + return FWK_E_ACCESS; + + if (message_id < 3) + return FWK_SUCCESS; + + domain_id = get_reset_domain_id(payload); + + perms = scmi_rd_ctx.res_perms_api->agent_has_resource_permission( + agent_id, MOD_SCMI_PROTOCOL_ID_RESET_DOMAIN, message_id, domain_id); + + if (perms == MOD_RES_PERMS_ACCESS_ALLOWED) + return FWK_SUCCESS; + else + return FWK_E_ACCESS; +} +#endif + /* * SCMI module -> SCMI reset module interface */ @@ -500,6 +550,14 @@ static int scmi_reset_message_handler(fwk_id_t protocol_id, goto error; } +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + if (scmi_reset_domain_permissions_handler( + service_id, payload, payload_size, message_id) != FWK_SUCCESS) { + return_value = SCMI_DENIED; + goto error; + } +#endif + return msg_handler_table[message_id](service_id, payload); error: @@ -586,6 +644,15 @@ static int scmi_reset_bind(fwk_id_t id, unsigned int round) return status; #endif +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + status = fwk_module_bind( + FWK_ID_MODULE(FWK_MODULE_IDX_RESOURCE_PERMS), + FWK_ID_API(FWK_MODULE_IDX_RESOURCE_PERMS, MOD_RES_PERM_RESOURCE_PERMS), + &scmi_rd_ctx.res_perms_api); + if (status != FWK_SUCCESS) + return status; +#endif + return fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_RESET_DOMAIN), FWK_ID_API(FWK_MODULE_IDX_RESET_DOMAIN, 0), &scmi_rd_ctx.reset_api); diff --git a/product/juno/scp_ramfw/config_resource_perms.c b/product/juno/scp_ramfw/config_resource_perms.c index 606ad00ec..eaf984b49 100644 --- a/product/juno/scp_ramfw/config_resource_perms.c +++ b/product/juno/scp_ramfw/config_resource_perms.c @@ -11,6 +11,10 @@ #include "juno_clock.h" #include "juno_scmi.h" +#ifdef BUILD_HAS_SCMI_RESET +# include +#endif + #include #include @@ -273,6 +277,39 @@ static mod_res_perms_t }, }; +/* + * We are tracking 3 SCMI Reset Domain Protocol commands + * + * 0, MOD_SCMI_RESET_DOMAIN_ATTRIBUTES + * 1, MOD_SCMI_RESET_REQUEST + * 2, MOD_SCMI_RESET_NOTIFY + */ +#ifdef BUILD_HAS_SCMI_RESET + +# define JUNO_RESET_DOMAIN_RESOURCE_CMDS 3 +# define JUNO_RESET_DOMAIN_RESOURCE_ELEMENTS \ + ((JUNO_RESET_DOMAIN_IDX_COUNT >> MOD_RES_PERMS_TYPE_SHIFT) + 1) +static mod_res_perms_t + scmi_reset_domain_perms[] [JUNO_RESET_DOMAIN_RESOURCE_CMDS] + [JUNO_RESET_DOMAIN_RESOURCE_ELEMENTS] = { + /* SCMI_PROTOCOL_ID_RESET_DOMAIN */ + /* 0, MOD_SCMI_RESET_DOMAIN_ATTRIBUTES */ + /* 1, MOD_SCMI_RESET_REQUEST */ + /* 2, MOD_SCMI_RESET_NOTIFY */ + [AGENT_IDX(JUNO_SCMI_AGENT_IDX_OSPM)] = { + [MOD_RES_PERMS_SCMI_RESET_DOMAIN_ATTRIBUTES_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_RESET_DOMAIN_RESET_REQUEST_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_RESET_DOMAIN_RESET_NOTIFY_IDX][0] = 0x0, + }, + [AGENT_IDX(JUNO_SCMI_AGENT_IDX_PSCI)] = { + [MOD_RES_PERMS_SCMI_RESET_DOMAIN_ATTRIBUTES_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_RESET_DOMAIN_RESET_REQUEST_IDX][0] = 0x0, + [MOD_RES_PERMS_SCMI_RESET_DOMAIN_RESET_NOTIFY_IDX][0] = 0x0, + }, + }; + +#endif + /* * Juno Platform Permissions */ @@ -283,6 +320,9 @@ static struct mod_res_agent_permission agent_permissions = { .scmi_pd_perms = &scmi_pd_perms[0][0][0], .scmi_perf_perms = &scmi_perf_perms[0][0][0], .scmi_sensor_perms = &scmi_sensor_perms[0][0][0], +#ifdef BUILD_HAS_SCMI_RESET + .scmi_reset_domain_perms = &scmi_reset_domain_perms[0][0][0], +#endif }; struct fwk_module_config config_resource_perms = { @@ -295,5 +335,8 @@ struct fwk_module_config config_resource_perms = { .sensor_count = MOD_JUNO_R0_SENSOR_IDX_COUNT, .pd_count = POWER_DOMAIN_IDX_COUNT, .perf_count = DVFS_ELEMENT_IDX_COUNT, +#ifdef BUILD_HAS_SCMI_RESET + .reset_domain_count = JUNO_RESET_DOMAIN_IDX_COUNT, +#endif }, }; -- GitLab