From ebd9ad1171c31a424e8f778853c1450042b8431a Mon Sep 17 00:00:00 2001 From: Jim Quigley Date: Mon, 20 Jul 2020 12:54:38 +0100 Subject: [PATCH 1/6] SCMI: Device permissions This patch adds the basic definitions for SCMI device permissions management. Change-Id: Iee4de39de514275cd2692165e6d3728e1bbf98db Signed-off-by: Jim Quigley --- .../include/mod_resource_perms.h | 93 ++++++++++++++++++- .../resource_perms/src/mod_resource_perms.c | 47 ++++++++++ 2 files changed, 139 insertions(+), 1 deletion(-) diff --git a/module/resource_perms/include/mod_resource_perms.h b/module/resource_perms/include/mod_resource_perms.h index 9d223651f..0a1284d95 100644 --- a/module/resource_perms/include/mod_resource_perms.h +++ b/module/resource_perms/include/mod_resource_perms.h @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -266,6 +267,44 @@ enum mod_res_reset_domain_permissions_idx { MOD_SCMI_RESET_NOTIFY - MOD_RES_PERMS_RESET_DOMAIN_PERMS_OFFSET, }; +/*! + * \brief SCMI Domain Types + */ +enum mod_res_domain_device_types { + MOD_RES_POWER_DOMAIN_DEVICE = 0, + MOD_RES_PERF_DOMAIN_DEVICE, + MOD_RES_CLOCK_DOMAIN_DEVICE, + MOD_RES_SENSOR_DOMAIN_DEVICE, + MOD_RES_RESET_DOMAIN_DEVICE, + MOD_RES_PLATFORM_DOMAIN_DEVICE, + MOD_RES_DOMAIN_DEVICE_INVALID +}; + +/*! + * \brief Each device is made up multiple domain devices. + * The protocol is determined by the device type. + * The resource ID for a protocol is the element ID of the + * device_id. + */ +struct mod_res_domain_device { + /*! \brief Identifier of the domain device instance */ + fwk_id_t device_id; + + /*! \brief Type of the domain device instance */ + enum mod_res_domain_device_types type; +}; + +/*! + * \brief Device definition. + */ +struct mod_res_device { + /*! \brief Device Identifier */ + uint16_t device_id; + + /*! \brief List of domain devices in the device */ + struct mod_res_domain_device *domain_devices; +}; + /*! * \brief SCMI Agent Permissions * @@ -359,6 +398,52 @@ struct mod_res_permissions_api { uint32_t protocol_id, uint32_t message_id, uint32_t resource_id); + + /*! + * \brief Set device permissions for an agent + * + * \param agent_id identifier of the agent. + * \param device_id identifier of the device. + * \param flags permissions to set. + * + * \retval FWK_SUCCESS The operation has completed successfully. + * \retval FWK_E_PARAM Unknown agent_id or device_id. + * \retval FWK_E_INVAL Invalid flags. + */ + int (*agent_set_device_permission)( + uint32_t agent_id, + uint32_t device_id, + uint32_t flags); + + /*! + * \brief Set device protocol permissions for an agent + * + * \param agent_id identifier of the agent. + * \param device_id identifier of the device. + * \param device_id identifier of the protocol. + * \param flags permissions to set. + * + * \retval FWK_SUCCESS The operation has completed successfully. + * \retval FWK_E_PARAM Unknown agent_id or device_id. + * \retval FWK_E_INVAL Invalid flags or protocol_ID. + */ + int (*agent_set_device_protocol_permission)( + uint32_t agent_id, + uint32_t device_id, + uint32_t protocol_id, + uint32_t flags); + + /*! + * \brief Reset permissions for an agent + * + * \param agent_id identifier of the agent. + * \param flags permissions to set. + * + * \retval FWK_SUCCESS The operation has completed successfully. + * \retval FWK_E_PARAM Unknown agent_id. + * \retval FWK_E_INVAL Invalid flags. + */ + int (*agent_reset_config)(uint32_t agent_id, uint32_t flags); }; /*! @@ -387,12 +472,18 @@ struct mod_res_resource_perms_config { uint32_t perf_count; #ifdef BUILD_HAS_SCMI_RESET - /*! \brief Number of performance domains supported by the platform. */ + /*! \brief Number of reset domains supported by the platform. */ uint32_t reset_domain_count; #endif + /*! \brief Number of devices supported by the platform. */ + uint32_t device_count; + /*! \brief Address of the permissions table */ uintptr_t agent_permissions; + + /*! \brief Address of the domain devices */ + uintptr_t domain_devices; }; /*! diff --git a/module/resource_perms/src/mod_resource_perms.c b/module/resource_perms/src/mod_resource_perms.c index 410f4d860..b41555770 100644 --- a/module/resource_perms/src/mod_resource_perms.c +++ b/module/resource_perms/src/mod_resource_perms.c @@ -39,6 +39,9 @@ struct res_perms_ctx { /*! Number of performance domain resources for the platform. */ uint32_t perf_count; + /*! Number of devices for the platform. */ + uint32_t device_count; + #ifdef BUILD_HAS_SCMI_RESET /*! Number of reset domain resources for the platform. */ uint32_t reset_domain_count; @@ -61,6 +64,12 @@ struct res_perms_ctx { * memory. */ struct mod_res_agent_permission *agent_permissions; + + /*! + * The list of domain devices in the system. If this is not set then setting + * device permissions for an agent is not supported. + */ + struct mod_res_device *domain_devices; }; static struct res_perms_ctx res_perms_ctx; @@ -649,10 +658,45 @@ static enum mod_res_perms_permissions agent_resource_permissions( return MOD_RES_PERMS_ACCESS_ALLOWED; } +/* + * Set the permissions for an agent:device. + */ +static int mod_res_agent_set_device_permission( + uint32_t agent_id, + uint32_t device_id, + uint32_t flags) +{ + return FWK_SUCCESS; +} + +/* + * Set the permissions for an agent:device:protocol. + */ +static int mod_res_agent_set_device_protocol_permission( + uint32_t agent_id, + uint32_t device_id, + uint32_t protocol_id, + uint32_t flags) +{ + return FWK_SUCCESS; +} + +/* + * Reset the permissions for an agent to the default configuration. + */ +static int mod_res_agent_reset_config(uint32_t agent_id, uint32_t flags) +{ + return FWK_SUCCESS; +} + 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, + .agent_set_device_permission = mod_res_agent_set_device_permission, + .agent_set_device_protocol_permission = + mod_res_agent_set_device_protocol_permission, + .agent_reset_config = mod_res_agent_reset_config, }; /* @@ -691,9 +735,12 @@ static int mod_res_perms_resources_init( res_perms_ctx.sensor_count = config->sensor_count; res_perms_ctx.pd_count = config->pd_count; res_perms_ctx.perf_count = config->perf_count; + res_perms_ctx.device_count = config->device_count; #ifdef BUILD_HAS_SCMI_RESET res_perms_ctx.reset_domain_count = config->reset_domain_count; #endif + res_perms_ctx.domain_devices = + (struct mod_res_device *)config->domain_devices; } return FWK_SUCCESS; -- GitLab From 6422beda1fdabcf34d41d38702166274c478c085 Mon Sep 17 00:00:00 2001 From: Jim Quigley Date: Mon, 20 Jul 2020 10:31:29 +0100 Subject: [PATCH 2/6] SCMI: Base Protocol permissions message handlers This patch adds the framework for implementing the SCMI Base Protocol permissions message handlers. Change-Id: I9e0889427d9cd3af210a5bb86486510c436a9333 Signed-off-by: Jim Quigley --- .../include/mod_resource_perms.h | 2 + module/scmi/include/internal/scmi_base.h | 39 +++++ module/scmi/include/mod_scmi_std.h | 3 + module/scmi/src/mod_scmi.c | 152 +++++++++++++++++- 4 files changed, 194 insertions(+), 2 deletions(-) diff --git a/module/resource_perms/include/mod_resource_perms.h b/module/resource_perms/include/mod_resource_perms.h index 0a1284d95..40e250b7b 100644 --- a/module/resource_perms/include/mod_resource_perms.h +++ b/module/resource_perms/include/mod_resource_perms.h @@ -46,6 +46,8 @@ enum mod_res_perms_permissions { MOD_RES_PERMS_ACCESS_DENIED = 1, }; +#define MOD_RES_PERMS_PERMISSIONS_MASK 0x1 + #define MOD_RES_PERMS_PROTOCOL_OFFSET MOD_SCMI_PROTOCOL_ID_BASE enum mod_res_perms_protocol_deny { diff --git a/module/scmi/include/internal/scmi_base.h b/module/scmi/include/internal/scmi_base.h index 07b414b54..a89cf5807 100644 --- a/module/scmi/include/internal/scmi_base.h +++ b/module/scmi/include/internal/scmi_base.h @@ -76,4 +76,43 @@ struct __attribute((packed)) scmi_base_discover_agent_p2a { char name[16]; }; +/* + * BASE_SET_DEVICE_PERMISSIONS + */ +struct __attribute((packed)) scmi_base_set_device_permissions_a2p { + uint32_t agent_id; + uint32_t device_id; + uint32_t flags; +}; + +struct __attribute((packed)) scmi_base_set_device_permissions_p2a { + int32_t status; +}; + +/* + * BASE_SET_PROTOCOL_PERMISSIONS + */ +struct __attribute((packed)) scmi_base_set_protocol_permissions_a2p { + uint32_t agent_id; + uint32_t device_id; + uint32_t command_id; + uint32_t flags; +}; + +struct __attribute((packed)) scmi_base_set_protocol_permissions_p2a { + int32_t status; +}; + +/* + * BASE_RESET_AGENT_CONFIG + */ +struct __attribute((packed)) scmi_base_reset_agent_config_a2p { + uint32_t agent_id; + uint32_t flags; +}; + +struct __attribute((packed)) scmi_base_reset_agent_config_p2a { + int32_t status; +}; + #endif /* INTERNAL_SCMI_BASE_H */ diff --git a/module/scmi/include/mod_scmi_std.h b/module/scmi/include/mod_scmi_std.h index 3398e5fbc..9a05ddd65 100644 --- a/module/scmi/include/mod_scmi_std.h +++ b/module/scmi/include/mod_scmi_std.h @@ -88,6 +88,9 @@ enum scmi_base_command_id { MOD_SCMI_BASE_DISCOVER_LIST_PROTOCOLS = 0x006, MOD_SCMI_BASE_DISCOVER_AGENT = 0x007, MOD_SCMI_BASE_NOTIFY_ERRORS = 0x008, + MOD_SCMI_BASE_SET_DEVICE_PERMISSIONS = 0x009, + MOD_SCMI_BASE_SET_PROTOCOL_PERMISSIONS = 0x00A, + MOD_SCMI_BASE_RESET_AGENT_CONFIG = 0x00B, MOD_SCMI_BASE_COMMAND_COUNT, }; diff --git a/module/scmi/src/mod_scmi.c b/module/scmi/src/mod_scmi.c index 6f382ee19..ffb367d1b 100644 --- a/module/scmi/src/mod_scmi.c +++ b/module/scmi/src/mod_scmi.c @@ -95,6 +95,17 @@ static int scmi_base_discover_list_protocols_handler( fwk_id_t service_id, const uint32_t *payload); static int scmi_base_discover_agent_handler( fwk_id_t service_id, const uint32_t *payload); +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS +static int scmi_base_set_device_permissions( + fwk_id_t service_id, + const uint32_t *payload); +static int scmi_base_set_protocol_permissions( + fwk_id_t service_id, + const uint32_t *payload); +static int scmi_base_reset_agent_config( + fwk_id_t service_id, + const uint32_t *payload); +#endif static int (*const base_handler_table[])(fwk_id_t, const uint32_t *) = { [MOD_SCMI_PROTOCOL_VERSION] = scmi_base_protocol_version_handler, @@ -102,13 +113,18 @@ static int (*const base_handler_table[])(fwk_id_t, const uint32_t *) = { [MOD_SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = scmi_base_protocol_message_attributes_handler, [MOD_SCMI_BASE_DISCOVER_VENDOR] = scmi_base_discover_vendor_handler, - [MOD_SCMI_BASE_DISCOVER_SUB_VENDOR] = - scmi_base_discover_sub_vendor_handler, + [MOD_SCMI_BASE_DISCOVER_SUB_VENDOR] = scmi_base_discover_sub_vendor_handler, [MOD_SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION] = scmi_base_discover_implementation_version_handler, [MOD_SCMI_BASE_DISCOVER_LIST_PROTOCOLS] = scmi_base_discover_list_protocols_handler, [MOD_SCMI_BASE_DISCOVER_AGENT] = scmi_base_discover_agent_handler, +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + [MOD_SCMI_BASE_SET_DEVICE_PERMISSIONS] = scmi_base_set_device_permissions, + [MOD_SCMI_BASE_SET_PROTOCOL_PERMISSIONS] = + scmi_base_set_protocol_permissions, + [MOD_SCMI_BASE_RESET_AGENT_CONFIG] = scmi_base_reset_agent_config, +#endif }; static const unsigned int base_payload_size_table[] = { @@ -123,6 +139,14 @@ static const unsigned int base_payload_size_table[] = { sizeof(struct scmi_base_discover_list_protocols_a2p), [MOD_SCMI_BASE_DISCOVER_AGENT] = sizeof(struct scmi_base_discover_agent_a2p), +#ifdef BUILD_HAS_RESOURCE_PERMISSIONS + [MOD_SCMI_BASE_SET_DEVICE_PERMISSIONS] = + sizeof(struct scmi_base_set_device_permissions_a2p), + [MOD_SCMI_BASE_SET_PROTOCOL_PERMISSIONS] = + sizeof(struct scmi_base_set_protocol_permissions_a2p), + [MOD_SCMI_BASE_RESET_AGENT_CONFIG] = + sizeof(struct scmi_base_reset_agent_config_a2p), +#endif }; static const char * const default_agent_names[] = { @@ -639,6 +663,129 @@ exit: } #ifdef BUILD_HAS_RESOURCE_PERMISSIONS + +/* + * BASE_SET_DEVICE_PERMISSIONS + */ +static int scmi_base_set_device_permissions( + fwk_id_t service_id, + const uint32_t *payload) +{ + const struct scmi_base_set_device_permissions_a2p *parameters; + struct scmi_base_set_device_permissions_p2a return_values = { + .status = SCMI_NOT_FOUND, + }; + + parameters = (const struct scmi_base_set_device_permissions_a2p *)payload; + + if (parameters->agent_id > scmi_ctx.config->agent_count) + goto exit; + + if (parameters->agent_id == MOD_SCMI_PLATFORM_ID) { + return_values.status = SCMI_SUCCESS; + goto exit; + } + + if (parameters->flags & ~MOD_RES_PERMS_PERMISSIONS_MASK) { + return_values.status = SCMI_INVALID_PARAMETERS; + goto exit; + } + + return_values.status = SCMI_NOT_SUPPORTED; + +exit: + respond( + service_id, + &return_values, + (return_values.status == SCMI_SUCCESS) ? sizeof(return_values) : + sizeof(return_values.status)); + + return FWK_SUCCESS; +} + +/* + * BASE_SET_PROTOCOL_PERMISSIONS + */ +static int scmi_base_set_protocol_permissions( + fwk_id_t service_id, + const uint32_t *payload) +{ + const struct scmi_base_set_protocol_permissions_a2p *parameters; + struct scmi_base_set_protocol_permissions_p2a return_values = { + .status = SCMI_NOT_FOUND, + }; + + parameters = (const struct scmi_base_set_protocol_permissions_a2p *)payload; + + if (parameters->agent_id > scmi_ctx.config->agent_count) + goto exit; + + if (parameters->agent_id == MOD_SCMI_PLATFORM_ID) { + return_values.status = SCMI_SUCCESS; + goto exit; + } + + if (parameters->flags & ~MOD_RES_PERMS_PERMISSIONS_MASK) { + return_values.status = SCMI_INVALID_PARAMETERS; + goto exit; + } + + if (parameters->command_id == MOD_SCMI_PROTOCOL_ID_BASE) { + return_values.status = SCMI_DENIED; + goto exit; + } + + return_values.status = SCMI_NOT_SUPPORTED; + +exit: + respond( + service_id, + &return_values, + (return_values.status == SCMI_SUCCESS) ? sizeof(return_values) : + sizeof(return_values.status)); + + return FWK_SUCCESS; +} + +/* + * BASE_RESET_AGENT_CONFIG + */ +static int scmi_base_reset_agent_config( + fwk_id_t service_id, + const uint32_t *payload) +{ + const struct scmi_base_reset_agent_config_a2p *parameters; + struct scmi_base_reset_agent_config_p2a return_values = { + .status = SCMI_NOT_FOUND, + }; + + parameters = (const struct scmi_base_reset_agent_config_a2p *)payload; + + if (parameters->agent_id > scmi_ctx.config->agent_count) + goto exit; + + if (parameters->agent_id == MOD_SCMI_PLATFORM_ID) { + return_values.status = SCMI_SUCCESS; + goto exit; + } + + if (parameters->flags & ~MOD_RES_PERMS_PERMISSIONS_MASK) { + return_values.status = SCMI_INVALID_PARAMETERS; + goto exit; + } + + return_values.status = SCMI_NOT_SUPPORTED; + +exit: + respond( + service_id, + &return_values, + (return_values.status == SCMI_SUCCESS) ? sizeof(return_values) : + sizeof(return_values.status)); + + return FWK_SUCCESS; +} + /* * SCMI Resource Permissions handler */ @@ -670,6 +817,7 @@ static int scmi_base_permissions_handler( else return FWK_E_ACCESS; } + #endif static int scmi_base_message_handler(fwk_id_t protocol_id, fwk_id_t service_id, -- GitLab From 338c6fe9631e8730ac3443ab651ceac01b34394b Mon Sep 17 00:00:00 2001 From: Jim Quigley Date: Mon, 20 Jul 2020 14:09:54 +0100 Subject: [PATCH 3/6] SCMI: Base Protocol set permissions commands This patch adds the SCMI Base Protocol device/protocol permissions commands. Change-Id: I48dd43404cc7f1c71e4988ea1a08cd53aeaa86fb Signed-off-by: Jim Quigley --- .../include/mod_resource_perms.h | 12 +-- module/scmi/src/mod_scmi.c | 74 +++++++++++++++++-- 2 files changed, 73 insertions(+), 13 deletions(-) diff --git a/module/resource_perms/include/mod_resource_perms.h b/module/resource_perms/include/mod_resource_perms.h index 40e250b7b..dac026c87 100644 --- a/module/resource_perms/include/mod_resource_perms.h +++ b/module/resource_perms/include/mod_resource_perms.h @@ -409,8 +409,8 @@ struct mod_res_permissions_api { * \param flags permissions to set. * * \retval FWK_SUCCESS The operation has completed successfully. - * \retval FWK_E_PARAM Unknown agent_id or device_id. - * \retval FWK_E_INVAL Invalid flags. + * \retval FWK_E_ACCESS Unknown agent_id or device_id. + * \retval FWK_E_PARAM Invalid flags or protocol_ID. */ int (*agent_set_device_permission)( uint32_t agent_id, @@ -426,8 +426,8 @@ struct mod_res_permissions_api { * \param flags permissions to set. * * \retval FWK_SUCCESS The operation has completed successfully. - * \retval FWK_E_PARAM Unknown agent_id or device_id. - * \retval FWK_E_INVAL Invalid flags or protocol_ID. + * \retval FWK_E_ACCESS Unknown agent_id or device_id. + * \retval FWK_E_PARAM Invalid flags or protocol_ID. */ int (*agent_set_device_protocol_permission)( uint32_t agent_id, @@ -442,8 +442,8 @@ struct mod_res_permissions_api { * \param flags permissions to set. * * \retval FWK_SUCCESS The operation has completed successfully. - * \retval FWK_E_PARAM Unknown agent_id. - * \retval FWK_E_INVAL Invalid flags. + * \retval FWK_E_ACCESS Unknown agent_id. + * \retval FWK_E_PARAM Invalid flags. */ int (*agent_reset_config)(uint32_t agent_id, uint32_t flags); }; diff --git a/module/scmi/src/mod_scmi.c b/module/scmi/src/mod_scmi.c index ffb367d1b..76e30eeab 100644 --- a/module/scmi/src/mod_scmi.c +++ b/module/scmi/src/mod_scmi.c @@ -675,11 +675,14 @@ static int scmi_base_set_device_permissions( struct scmi_base_set_device_permissions_p2a return_values = { .status = SCMI_NOT_FOUND, }; + int status = FWK_SUCCESS; parameters = (const struct scmi_base_set_device_permissions_a2p *)payload; - if (parameters->agent_id > scmi_ctx.config->agent_count) + if (parameters->agent_id > scmi_ctx.config->agent_count) { + status = FWK_E_ACCESS; goto exit; + } if (parameters->agent_id == MOD_SCMI_PLATFORM_ID) { return_values.status = SCMI_SUCCESS; @@ -688,10 +691,27 @@ static int scmi_base_set_device_permissions( if (parameters->flags & ~MOD_RES_PERMS_PERMISSIONS_MASK) { return_values.status = SCMI_INVALID_PARAMETERS; + status = FWK_E_PARAM; goto exit; } - return_values.status = SCMI_NOT_SUPPORTED; + status = scmi_ctx.res_perms_api->agent_set_device_permission( + parameters->agent_id, parameters->device_id, parameters->flags); + + switch (status) { + case FWK_SUCCESS: + return_values.status = SCMI_SUCCESS; + break; + case FWK_E_PARAM: + return_values.status = SCMI_INVALID_PARAMETERS; + break; + case FWK_E_ACCESS: + return_values.status = SCMI_NOT_FOUND; + break; + default: + return_values.status = SCMI_NOT_SUPPORTED; + break; + } exit: respond( @@ -700,7 +720,7 @@ exit: (return_values.status == SCMI_SUCCESS) ? sizeof(return_values) : sizeof(return_values.status)); - return FWK_SUCCESS; + return status; } /* @@ -714,11 +734,14 @@ static int scmi_base_set_protocol_permissions( struct scmi_base_set_protocol_permissions_p2a return_values = { .status = SCMI_NOT_FOUND, }; + int status = FWK_SUCCESS; parameters = (const struct scmi_base_set_protocol_permissions_a2p *)payload; - if (parameters->agent_id > scmi_ctx.config->agent_count) + if (parameters->agent_id > scmi_ctx.config->agent_count) { + status = FWK_E_ACCESS; goto exit; + } if (parameters->agent_id == MOD_SCMI_PLATFORM_ID) { return_values.status = SCMI_SUCCESS; @@ -726,6 +749,7 @@ static int scmi_base_set_protocol_permissions( } if (parameters->flags & ~MOD_RES_PERMS_PERMISSIONS_MASK) { + status = FWK_E_PARAM; return_values.status = SCMI_INVALID_PARAMETERS; goto exit; } @@ -735,7 +759,26 @@ static int scmi_base_set_protocol_permissions( goto exit; } - return_values.status = SCMI_NOT_SUPPORTED; + status = scmi_ctx.res_perms_api->agent_set_device_protocol_permission( + parameters->agent_id, + parameters->device_id, + parameters->command_id, + parameters->flags); + + switch (status) { + case FWK_SUCCESS: + return_values.status = SCMI_SUCCESS; + break; + case FWK_E_PARAM: + return_values.status = SCMI_INVALID_PARAMETERS; + break; + case FWK_E_ACCESS: + return_values.status = SCMI_NOT_FOUND; + break; + default: + return_values.status = SCMI_NOT_SUPPORTED; + break; + } exit: respond( @@ -744,7 +787,7 @@ exit: (return_values.status == SCMI_SUCCESS) ? sizeof(return_values) : sizeof(return_values.status)); - return FWK_SUCCESS; + return status; } /* @@ -758,6 +801,7 @@ static int scmi_base_reset_agent_config( struct scmi_base_reset_agent_config_p2a return_values = { .status = SCMI_NOT_FOUND, }; + int status; parameters = (const struct scmi_base_reset_agent_config_a2p *)payload; @@ -774,7 +818,23 @@ static int scmi_base_reset_agent_config( goto exit; } - return_values.status = SCMI_NOT_SUPPORTED; + status = scmi_ctx.res_perms_api->agent_reset_config( + parameters->agent_id, parameters->flags); + + switch (status) { + case FWK_SUCCESS: + return_values.status = SCMI_SUCCESS; + break; + case FWK_E_PARAM: + return_values.status = SCMI_INVALID_PARAMETERS; + break; + case FWK_E_ACCESS: + return_values.status = SCMI_NOT_FOUND; + break; + default: + return_values.status = SCMI_NOT_SUPPORTED; + break; + } exit: respond( -- GitLab From 02bce97de1c405698e154d04dbd4215ac95116ef Mon Sep 17 00:00:00 2001 From: Jim Quigley Date: Tue, 21 Jul 2020 13:55:07 +0100 Subject: [PATCH 4/6] SCMI: Set device permissions This patch implements the set_device_permissions function for SCMI v2. Change-Id: I5c76e3cde3ccd68d340ce121d26c18351bad0040 Signed-off-by: Jim Quigley --- .../resource_perms/src/mod_resource_perms.c | 361 ++++++++++++++++++ 1 file changed, 361 insertions(+) diff --git a/module/resource_perms/src/mod_resource_perms.c b/module/resource_perms/src/mod_resource_perms.c index b41555770..18541e4e5 100644 --- a/module/resource_perms/src/mod_resource_perms.c +++ b/module/resource_perms/src/mod_resource_perms.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -661,11 +662,298 @@ static enum mod_res_perms_permissions agent_resource_permissions( /* * Set the permissions for an agent:device. */ +static int set_agent_resource_message_perms( + uint32_t agent_id, + uint32_t protocol_id, + uint32_t message_idx, + uint32_t resource_id, + mod_res_perms_t *perms, + enum mod_res_perms_permissions flags) +{ + int status; + int32_t resource_idx; + mod_res_perms_t permissions; + + status = mod_res_resource_id_to_index( + agent_id, protocol_id, message_idx, resource_id, &resource_idx); + if (status != FWK_SUCCESS) + return status; + + permissions = perms[resource_idx]; + + flags = + ((flags == 0) ? MOD_RES_PERMS_ACCESS_DENIED : + MOD_RES_PERMS_ACCESS_ALLOWED); + + if (flags == MOD_RES_PERMS_ACCESS_ALLOWED) + permissions &= ~(1 << (MOD_RES_PERMS_RESOURCE_BIT(resource_id))); + else + permissions |= (1 << (MOD_RES_PERMS_RESOURCE_BIT(resource_id))); + + perms[resource_idx] = permissions; + + return FWK_SUCCESS; +} + +static int set_agent_resource_pd_permissions( + uint32_t agent_id, + uint32_t resource_id, + enum mod_res_perms_permissions flags) +{ + int status; + int32_t message_idx; + + if (res_perms_ctx.agent_permissions->scmi_pd_perms == NULL) + return FWK_SUCCESS; + if (resource_id >= res_perms_ctx.pd_count) + return FWK_E_ACCESS; + + for (message_idx = MOD_SCMI_PD_POWER_DOMAIN_ATTRIBUTES; + message_idx <= MOD_SCMI_PD_POWER_STATE_NOTIFY; + message_idx++) { + status = set_agent_resource_message_perms( + agent_id, + MOD_SCMI_PROTOCOL_ID_POWER_DOMAIN, + message_idx, + resource_id, + res_perms_ctx.agent_permissions->scmi_pd_perms, + flags); + + if (status != FWK_SUCCESS) + return status; + } + return FWK_SUCCESS; +} + +static int set_agent_resource_perf_permissions( + uint32_t agent_id, + uint32_t resource_id, + enum mod_res_perms_permissions flags) +{ + int status; + int32_t message_idx; + + if (res_perms_ctx.agent_permissions->scmi_perf_perms == NULL) + return FWK_SUCCESS; + if (resource_id >= res_perms_ctx.perf_count) + return FWK_E_ACCESS; + + for (message_idx = MOD_SCMI_PERF_DOMAIN_ATTRIBUTES; + message_idx <= MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL; + message_idx++) { + status = set_agent_resource_message_perms( + agent_id, + MOD_SCMI_PROTOCOL_ID_PERF, + message_idx, + resource_id, + res_perms_ctx.agent_permissions->scmi_perf_perms, + flags); + + if (status != FWK_SUCCESS) + return status; + } + + return FWK_SUCCESS; +} + +static int set_agent_resource_clock_permissions( + uint32_t agent_id, + uint32_t resource_id, + enum mod_res_perms_permissions flags) +{ + int status; + int32_t message_idx; + + if (res_perms_ctx.agent_permissions->scmi_clock_perms == NULL) + return FWK_SUCCESS; + if (resource_id >= res_perms_ctx.clock_count) + return FWK_E_ACCESS; + + for (message_idx = MOD_SCMI_CLOCK_ATTRIBUTES; + message_idx <= MOD_SCMI_CLOCK_CONFIG_SET; + message_idx++) { + status = set_agent_resource_message_perms( + agent_id, + MOD_SCMI_PROTOCOL_ID_CLOCK, + message_idx, + resource_id, + res_perms_ctx.agent_permissions->scmi_clock_perms, + flags); + + if (status != FWK_SUCCESS) + return status; + } + + return FWK_SUCCESS; +} + +#ifdef BUILD_HAS_SCMI_RESET + +static int set_agent_resource_reset_permissions( + uint32_t agent_id, + uint32_t resource_id, + enum mod_res_perms_permissions flags) +{ + int status; + int32_t message_idx; + + if (res_perms_ctx.agent_permissions->scmi_reset_perms == NULL) + return FWK_SUCCESS; + if (resource_id >= res_perms_ctx.reset_domain_count) + return FWK_E_ACCESS; + + for (message_idx = MOD_SCMI_RESET_DOMAIN_ATTRIBUTES; + message_idx <= MOD_SCMI_RESET_NOTIFY; + message_idx++) { + status = set_agent_resource_message_perms( + agent_id, + MOD_SCMI_PROTOCOL_ID_RESET_DOMAIN, + message_idx, + resource_id, + res_perms_ctx.agent_permissions->scmi_reset_domain_perms, + flags); + + if (status != FWK_SUCCESS) + return status; + } + + return FWK_SUCCESS; +} + +#endif + +static int set_agent_resource_sensor_permissions( + uint32_t agent_id, + uint32_t resource_id, + enum mod_res_perms_permissions flags) +{ + int status; + int32_t message_idx; + + if (res_perms_ctx.agent_permissions->scmi_sensor_perms == NULL) + return FWK_SUCCESS; + if (resource_id >= res_perms_ctx.sensor_count) + return FWK_E_ACCESS; + + for (message_idx = MOD_SCMI_SENSOR_DESCRIPTION_GET; + message_idx <= MOD_SCMI_SENSOR_READING_GET; + message_idx++) { + status = set_agent_resource_message_perms( + agent_id, + MOD_SCMI_PROTOCOL_ID_SENSOR, + message_idx, + resource_id, + res_perms_ctx.agent_permissions->scmi_sensor_perms, + flags); + + if (status != FWK_SUCCESS) + return status; + } + + return FWK_SUCCESS; +} + +static int mod_res_agent_set_permissions( + enum mod_res_domain_device_types type, + uint32_t agent_id, + uint32_t resource_id, + enum mod_res_perms_permissions flags) +{ + int status; + + switch (type) { + case MOD_RES_POWER_DOMAIN_DEVICE: + status = + set_agent_resource_pd_permissions(agent_id, resource_id, flags); + break; + + case MOD_RES_PERF_DOMAIN_DEVICE: + status = + set_agent_resource_perf_permissions(agent_id, resource_id, flags); + break; + + case MOD_RES_CLOCK_DOMAIN_DEVICE: + status = + set_agent_resource_clock_permissions(agent_id, resource_id, flags); + break; + + case MOD_RES_SENSOR_DOMAIN_DEVICE: + status = + set_agent_resource_sensor_permissions(agent_id, resource_id, flags); + break; + +#ifdef BUILD_HAS_SCMI_RESET + case MOD_RES_RESET_DOMAIN_DEVICE: + status = + set_agent_resource_reset_permissions(agent_id, resource_id, flags); + break; +#endif + + default: + status = FWK_E_ACCESS; + break; + } + + if (status != FWK_SUCCESS) + FWK_LOG_WARN( + "[perms] set_permissions for agent %d type %d device %d failed\n", + (int)agent_id, + (int)type, + (int)resource_id); + + return status; +} + static int mod_res_agent_set_device_permission( uint32_t agent_id, uint32_t device_id, uint32_t flags) { + struct mod_res_domain_device *dev; + uint32_t resource_id; + int status; + uint32_t i; + + /* No device permissons */ + if ((res_perms_ctx.device_count == 0) || + (res_perms_ctx.domain_devices == NULL)) + return FWK_E_ACCESS; + + if (device_id >= res_perms_ctx.device_count) + return FWK_E_PARAM; + + if ((flags != 0) && (flags != 1)) + return FWK_E_PARAM; + + /* Find device */ + for (i = 0; i < res_perms_ctx.device_count; i++) { + if (res_perms_ctx.domain_devices[i].device_id == device_id) + break; + } + + if (i == res_perms_ctx.device_count) + return FWK_E_ACCESS; + + dev = res_perms_ctx.domain_devices[i].domain_devices; + while (dev->type != MOD_RES_DOMAIN_DEVICE_INVALID) { + if (fwk_id_is_equal(dev->device_id, FWK_ID_NONE)) + return FWK_SUCCESS; + + resource_id = fwk_id_get_element_idx(dev->device_id); + + status = mod_res_agent_set_permissions( + dev->type, agent_id, resource_id, flags); + + if (status != FWK_SUCCESS) + FWK_LOG_WARN( + "[perms] set_permissions for agent %d device %d failed\n", + (int)agent_id, + (int)i); + + /* next domain device */ + dev++; + }; + return FWK_SUCCESS; } @@ -678,6 +966,79 @@ static int mod_res_agent_set_device_protocol_permission( uint32_t protocol_id, uint32_t flags) { + enum mod_res_domain_device_types dev_type; + struct mod_res_domain_device *dev; + uint32_t resource_id; + int status; + uint32_t i; + + /* No device permissons */ + if ((res_perms_ctx.device_count == 0) || + (res_perms_ctx.domain_devices == NULL)) + return FWK_E_ACCESS; + + if (device_id >= res_perms_ctx.device_count) + return FWK_E_PARAM; + + if ((flags != 0) && (flags != 1)) + return FWK_E_PARAM; + + /* Find device */ + for (i = 0; i < res_perms_ctx.device_count; i++) { + if (res_perms_ctx.domain_devices[i].device_id == device_id) + break; + } + + if (i == res_perms_ctx.device_count) + return FWK_E_ACCESS; + + switch (protocol_id) { + case MOD_SCMI_PROTOCOL_ID_POWER_DOMAIN: + dev_type = MOD_RES_POWER_DOMAIN_DEVICE; + break; + case MOD_SCMI_PROTOCOL_ID_PERF: + dev_type = MOD_RES_PERF_DOMAIN_DEVICE; + break; + case MOD_SCMI_PROTOCOL_ID_CLOCK: + dev_type = MOD_RES_CLOCK_DOMAIN_DEVICE; + break; + case MOD_SCMI_PROTOCOL_ID_SENSOR: + dev_type = MOD_RES_SENSOR_DOMAIN_DEVICE; + break; + case MOD_SCMI_PROTOCOL_ID_RESET_DOMAIN: + dev_type = MOD_RES_RESET_DOMAIN_DEVICE; + break; + default: + case MOD_SCMI_PROTOCOL_ID_BASE: + case MOD_SCMI_PROTOCOL_ID_SYS_POWER: + return FWK_E_ACCESS; + } + + dev = res_perms_ctx.domain_devices[i].domain_devices; + while (dev->type != MOD_RES_DOMAIN_DEVICE_INVALID) { + if (fwk_id_is_equal(dev->device_id, FWK_ID_NONE)) + return FWK_SUCCESS; + + if (dev->type != dev_type) { + dev++; + continue; + } + + resource_id = fwk_id_get_element_idx(dev->device_id); + + status = mod_res_agent_set_permissions( + dev->type, agent_id, resource_id, flags); + + if (status != FWK_SUCCESS) + FWK_LOG_WARN( + "[perms] set_permissions for agent %d device %d failed\n", + (int)agent_id, + (int)i); + + /* next domain device */ + dev++; + }; + return FWK_SUCCESS; } -- GitLab From cdb9f2ea3583775510d5f79699cdd10c3ee35861 Mon Sep 17 00:00:00 2001 From: Jim Quigley Date: Thu, 23 Jul 2020 15:48:49 +0100 Subject: [PATCH 5/6] SCMI: Reset agent permission configuration command This patch implements the SCMI v2 reset_config command of the SCMI Base protocol. Change-Id: I8b3f8cd627e5bd59e2fb8561be037fd3b01abe3c Signed-off-by: Jim Quigley --- .../include/mod_resource_perms.h | 32 ++- .../resource_perms/src/mod_resource_perms.c | 222 +++++++++++++++++- 2 files changed, 252 insertions(+), 2 deletions(-) diff --git a/module/resource_perms/include/mod_resource_perms.h b/module/resource_perms/include/mod_resource_perms.h index dac026c87..8a3bd64a2 100644 --- a/module/resource_perms/include/mod_resource_perms.h +++ b/module/resource_perms/include/mod_resource_perms.h @@ -464,18 +464,48 @@ struct mod_res_resource_perms_config { /*! \brief Number of clocks supported by the platform. */ uint32_t clock_count; + /*! \brief Number of clock commands supported by the platform. */ + uint32_t clock_cmd_count; + + /*! \brief Number of clock resources supported by the platform. */ + uint32_t clock_resource_count; + /*! \brief Number of sensors supported by the platform. */ uint32_t sensor_count; + /*! \brief Number of sensor commands supported by the platform. */ + uint32_t sensor_cmd_count; + + /*! \brief Number of sensor resources supported by the platform. */ + uint32_t sensor_resource_count; + /*! \brief Number of power domains supported by the platform. */ uint32_t pd_count; - /*! \brief Number of performance domains supported by the platform. */ + /*! \brief Number of power domain commands supported by the platform. */ + uint32_t pd_cmd_count; + + /*! \brief Number of power domain resources supported by the platform. */ + uint32_t pd_resource_count; + + /*! \brief Number of perf domains supported by the platform. */ uint32_t perf_count; + /*! \brief Number of perf domain commands supported by the platform. */ + uint32_t perf_cmd_count; + + /*! \brief Number of perf domain resources supported by the platform. */ + uint32_t perf_resource_count; + #ifdef BUILD_HAS_SCMI_RESET /*! \brief Number of reset domains supported by the platform. */ uint32_t reset_domain_count; + + /*! \brief Number of reset domain commands supported by the platform. */ + uint32_t reset_domain_cmd_count; + + /*! \brief Number of reset domain resources supported by the platform. */ + uint32_t reset_domain_resource_count; #endif /*! \brief Number of devices supported by the platform. */ diff --git a/module/resource_perms/src/mod_resource_perms.c b/module/resource_perms/src/mod_resource_perms.c index 18541e4e5..21628056d 100644 --- a/module/resource_perms/src/mod_resource_perms.c +++ b/module/resource_perms/src/mod_resource_perms.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -22,6 +23,9 @@ #include struct res_perms_ctx { + /*! platform config data */ + struct mod_res_resource_perms_config *config; + /*! Number of agents for the platform. */ uint32_t agent_count; @@ -73,7 +77,27 @@ struct res_perms_ctx { struct mod_res_device *domain_devices; }; +struct res_perms_backup { + /*! \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 +}; + static struct res_perms_ctx res_perms_ctx; +static struct res_perms_backup res_perms_backup; /* * Map the agent-id to the corresponding index in the table. @@ -708,6 +732,22 @@ static int set_agent_resource_pd_permissions( if (resource_id >= res_perms_ctx.pd_count) return FWK_E_ACCESS; + /* Do a backup before making the changes if required */ + if ((res_perms_ctx.config->pd_cmd_count != 0) && + (res_perms_ctx.config->pd_resource_count != 0) && + (res_perms_backup.scmi_pd_perms == NULL)) { + res_perms_backup.scmi_pd_perms = (mod_res_perms_t *)fwk_mm_alloc( + res_perms_ctx.agent_count * res_perms_ctx.config->pd_cmd_count * + res_perms_ctx.config->pd_resource_count, + sizeof(mod_res_perms_t)); + memcpy( + res_perms_backup.scmi_pd_perms, + res_perms_ctx.agent_permissions->scmi_pd_perms, + res_perms_ctx.agent_count * res_perms_ctx.config->pd_cmd_count * + res_perms_ctx.config->pd_resource_count * + sizeof(mod_res_perms_t)); + } + for (message_idx = MOD_SCMI_PD_POWER_DOMAIN_ATTRIBUTES; message_idx <= MOD_SCMI_PD_POWER_STATE_NOTIFY; message_idx++) { @@ -722,6 +762,7 @@ static int set_agent_resource_pd_permissions( if (status != FWK_SUCCESS) return status; } + return FWK_SUCCESS; } @@ -738,6 +779,22 @@ static int set_agent_resource_perf_permissions( if (resource_id >= res_perms_ctx.perf_count) return FWK_E_ACCESS; + /* Do a backup before making the changes if required */ + if ((res_perms_ctx.config->perf_cmd_count != 0) && + (res_perms_ctx.config->perf_resource_count != 0) && + (res_perms_backup.scmi_perf_perms == NULL)) { + res_perms_backup.scmi_perf_perms = (mod_res_perms_t *)fwk_mm_alloc( + res_perms_ctx.agent_count * res_perms_ctx.config->perf_cmd_count * + res_perms_ctx.config->perf_resource_count, + sizeof(mod_res_perms_t)); + memcpy( + res_perms_backup.scmi_perf_perms, + res_perms_ctx.agent_permissions->scmi_perf_perms, + res_perms_ctx.agent_count * res_perms_ctx.config->perf_cmd_count * + res_perms_ctx.config->perf_resource_count * + sizeof(mod_res_perms_t)); + } + for (message_idx = MOD_SCMI_PERF_DOMAIN_ATTRIBUTES; message_idx <= MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL; message_idx++) { @@ -769,6 +826,22 @@ static int set_agent_resource_clock_permissions( if (resource_id >= res_perms_ctx.clock_count) return FWK_E_ACCESS; + /* Do a backup before making the changes if required */ + if ((res_perms_ctx.config->clock_cmd_count != 0) && + (res_perms_ctx.config->clock_resource_count != 0) && + (res_perms_backup.scmi_clock_perms == NULL)) { + res_perms_backup.scmi_clock_perms = (mod_res_perms_t *)fwk_mm_alloc( + res_perms_ctx.agent_count * res_perms_ctx.config->clock_cmd_count * + res_perms_ctx.config->clock_resource_count, + sizeof(mod_res_perms_t)); + memcpy( + res_perms_backup.scmi_clock_perms, + res_perms_ctx.agent_permissions->scmi_clock_perms, + res_perms_ctx.agent_count * res_perms_ctx.config->clock_cmd_count * + res_perms_ctx.config->clock_resource_count * + sizeof(mod_res_perms_t)); + } + for (message_idx = MOD_SCMI_CLOCK_ATTRIBUTES; message_idx <= MOD_SCMI_CLOCK_CONFIG_SET; message_idx++) { @@ -802,6 +875,25 @@ static int set_agent_resource_reset_permissions( if (resource_id >= res_perms_ctx.reset_domain_count) return FWK_E_ACCESS; + /* Do a backup before making the changes if required */ + if ((res_perms_ctx.config->reset_domain_cmd_count != 0) && + (res_perms_ctx.config->reset_domain_resource_count != 0) && + (res_perms_backup.scmi_reset_domain_perms == NULL)) { + res_perms_backup.scmi_reset_domain_perms = + (mod_res_perms_t *)fwk_mm_alloc( + res_perms_ctx.agent_count * + res_perms_ctx.config->reset_domain_cmd_count * + res_perms_ctx.config->reset_domain_resource_count, + sizeof(mod_res_perms_t)); + memcpy( + res_perms_backup.scmi_reset_domain_perms, + res_perms_ctx.agent_permissions->scmi_reset_domain_perms, + res_perms_ctx.agent_count * + res_perms_ctx.config->reset_domain_cmd_count * + res_perms_ctx.config->reset_domain_cmd_count * + sizeof(mod_res_perms_t)); + } + for (message_idx = MOD_SCMI_RESET_DOMAIN_ATTRIBUTES; message_idx <= MOD_SCMI_RESET_NOTIFY; message_idx++) { @@ -835,6 +927,22 @@ static int set_agent_resource_sensor_permissions( if (resource_id >= res_perms_ctx.sensor_count) return FWK_E_ACCESS; + /* Do a backup before making the changes if required */ + if ((res_perms_ctx.config->sensor_cmd_count != 0) && + (res_perms_ctx.config->sensor_resource_count != 0) && + (res_perms_backup.scmi_sensor_perms == NULL)) { + res_perms_backup.scmi_sensor_perms = (mod_res_perms_t *)fwk_mm_alloc( + res_perms_ctx.agent_count * res_perms_ctx.config->sensor_cmd_count * + res_perms_ctx.config->sensor_resource_count, + sizeof(mod_res_perms_t)); + memcpy( + res_perms_backup.scmi_sensor_perms, + res_perms_ctx.agent_permissions->scmi_sensor_perms, + res_perms_ctx.agent_count * res_perms_ctx.config->sensor_cmd_count * + res_perms_ctx.config->sensor_resource_count * + sizeof(mod_res_perms_t)); + } + for (message_idx = MOD_SCMI_SENSOR_DESCRIPTION_GET; message_idx <= MOD_SCMI_SENSOR_READING_GET; message_idx++) { @@ -1044,9 +1152,121 @@ static int mod_res_agent_set_device_protocol_permission( /* * Reset the permissions for an agent to the default configuration. + * Note that we only save and restore the permissions for protocols + * which have set _cmd_count and _resource_count + * in the platform config data. Also, the backup copies of the + * permissions are not cleared after they are restored, the backup may + * be re-used for any future reset requests. */ +static void mod_res_agent_copy_config( + uint32_t agent_id, + mod_res_perms_t *perms, + mod_res_perms_t *backup_perms, + uint32_t protocol_id) +{ + int cmd_count; + int resource_count; + int32_t resource_idx; + int i, j; + int status; + + switch (protocol_id) { + case MOD_SCMI_PROTOCOL_ID_POWER_DOMAIN: + cmd_count = MOD_SCMI_PD_POWER_COMMAND_COUNT; + resource_count = res_perms_ctx.config->pd_resource_count; + break; + case MOD_SCMI_PROTOCOL_ID_PERF: + cmd_count = MOD_SCMI_PERF_COMMAND_COUNT; + resource_count = res_perms_ctx.config->perf_resource_count; + break; + case MOD_SCMI_PROTOCOL_ID_CLOCK: + cmd_count = MOD_SCMI_CLOCK_COMMAND_COUNT; + resource_count = res_perms_ctx.config->clock_resource_count; + break; + case MOD_SCMI_PROTOCOL_ID_SENSOR: + cmd_count = MOD_SCMI_SENSOR_COMMAND_COUNT; + resource_count = res_perms_ctx.config->sensor_resource_count; + break; +#ifdef BUILD_HAS_SCMI_RESET + case MOD_SCMI_PROTOCOL_ID_RESET_DOMAIN: + cmd_count = MOD_SCMI_RESET_DOMAIN_COMMAND_COUNT; + resource_count = res_perms_ctx.config->reset_domainresource_count; + break; +#endif + default: + return; + } + + for (i = 3; i < cmd_count; i++) { /* commands < 3 are excluded */ + for (j = 0; j < resource_count; j++) { + status = mod_res_resource_id_to_index( + agent_id, + protocol_id, + i, /* message id */ + j, /* resource id */ + &resource_idx); + if ((status != FWK_SUCCESS) || (resource_idx < 0)) + continue; + perms[resource_idx] = backup_perms[resource_idx]; + } + } +} + static int mod_res_agent_reset_config(uint32_t agent_id, uint32_t flags) { + /* No device permissons */ + if ((res_perms_ctx.device_count == 0) || + (res_perms_ctx.domain_devices == NULL)) + return FWK_E_ACCESS; + + if (flags == 0) + return FWK_SUCCESS; + + if (agent_id >= res_perms_ctx.agent_count) + return FWK_E_ACCESS; + + if (res_perms_backup.scmi_pd_perms != NULL) { + mod_res_agent_copy_config( + agent_id, + res_perms_ctx.agent_permissions->scmi_pd_perms, + res_perms_backup.scmi_pd_perms, + MOD_SCMI_PROTOCOL_ID_POWER_DOMAIN); + } + + if (res_perms_backup.scmi_perf_perms != NULL) { + mod_res_agent_copy_config( + agent_id, + res_perms_ctx.agent_permissions->scmi_perf_perms, + res_perms_backup.scmi_perf_perms, + MOD_SCMI_PROTOCOL_ID_PERF); + } + + if (res_perms_backup.scmi_clock_perms != NULL) { + mod_res_agent_copy_config( + agent_id, + res_perms_ctx.agent_permissions->scmi_clock_perms, + res_perms_backup.scmi_clock_perms, + MOD_SCMI_PROTOCOL_ID_CLOCK); + } + + if (res_perms_backup.scmi_sensor_perms != NULL) { + mod_res_agent_copy_config( + agent_id, + res_perms_ctx.agent_permissions->scmi_sensor_perms, + res_perms_backup.scmi_sensor_perms, + MOD_SCMI_PROTOCOL_ID_SENSOR); + } + +#ifdef BUILD_HAS_SCMI_RESET + if (res_perms_backup.scmi_reset_domain_perms != NULL) { + mod_res_agent_copy_config( + agent_id, + res_perms_ctx.agent_permissions->scmi_reset_domain_perms, + res_perms_backup.scmi_reset_domain_perms, + MOD_SCMI_PROTOCOL_ID_RESET_DOMAIN); + } +#endif + return FWK_SUCCESS; } @@ -1103,7 +1323,7 @@ static int mod_res_perms_resources_init( res_perms_ctx.domain_devices = (struct mod_res_device *)config->domain_devices; } - + res_perms_ctx.config = config; return FWK_SUCCESS; } -- GitLab From b3b205d58b69a2aa6bfb3a9eb4441089670070dc Mon Sep 17 00:00:00 2001 From: Jim Quigley Date: Tue, 21 Jul 2020 12:14:19 +0100 Subject: [PATCH 6/6] juno: Specify the devices for the Juno platform. This patch adds the domain devices, the devices and the device list to the Juno configuration. Change-Id: I9fb5ed6ebd525d9880b9f92e795aa75753a4a931 Signed-off-by: Jim Quigley --- .../juno/scp_ramfw/config_resource_perms.c | 163 ++++++++++++++++++ .../juno/scp_ramfw/config_resource_perms.h | 18 ++ 2 files changed, 181 insertions(+) create mode 100644 product/juno/scp_ramfw/config_resource_perms.h diff --git a/product/juno/scp_ramfw/config_resource_perms.c b/product/juno/scp_ramfw/config_resource_perms.c index eaf984b49..03c51d6f0 100644 --- a/product/juno/scp_ramfw/config_resource_perms.c +++ b/product/juno/scp_ramfw/config_resource_perms.c @@ -7,6 +7,7 @@ #include "config_dvfs.h" #include "config_power_domain.h" +#include "config_resource_perms.h" #include "config_sensor.h" #include "juno_clock.h" #include "juno_scmi.h" @@ -325,6 +326,164 @@ static struct mod_res_agent_permission agent_permissions = { #endif }; +/* + * Juno Platform devices + * + * Note that a device must be terminated with + * {FWK_ID_NONE, MOD_RES_DOMAIN_DEVICE_INVALID} + * + */ +static struct mod_res_domain_device devices_cpu[] = { + { + .device_id = + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SCMI_PERF, DVFS_ELEMENT_IDX_BIG), + .type = MOD_RES_PERF_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI_CLOCK, + JUNO_CLOCK_IDX_BIGCLK), + .type = MOD_RES_CLOCK_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI_POWER_DOMAIN, + POWER_DOMAIN_IDX_BIG_CPU0), + .type = MOD_RES_POWER_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI_POWER_DOMAIN, + POWER_DOMAIN_IDX_BIG_CPU1), + .type = MOD_RES_POWER_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI_POWER_DOMAIN, + POWER_DOMAIN_IDX_BIG_SSTOP), + .type = MOD_RES_POWER_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI_PERF, + DVFS_ELEMENT_IDX_LITTLE), + .type = MOD_RES_PERF_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI_CLOCK, + JUNO_CLOCK_IDX_LITTLECLK), + .type = MOD_RES_CLOCK_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI_POWER_DOMAIN, + POWER_DOMAIN_IDX_LITTLE_CPU0), + .type = MOD_RES_POWER_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI_POWER_DOMAIN, + POWER_DOMAIN_IDX_LITTLE_CPU1), + .type = MOD_RES_POWER_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI_POWER_DOMAIN, + POWER_DOMAIN_IDX_LITTLE_CPU2), + .type = MOD_RES_POWER_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI_POWER_DOMAIN, + POWER_DOMAIN_IDX_LITTLE_CPU3), + .type = MOD_RES_POWER_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI_POWER_DOMAIN, + POWER_DOMAIN_IDX_LITTLE_SSTOP), + .type = MOD_RES_POWER_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_NONE_INIT, + .type = MOD_RES_DOMAIN_DEVICE_INVALID, + }, +}; + +static struct mod_res_domain_device devices_gpu[] = { + { + .device_id = + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SCMI_PERF, DVFS_ELEMENT_IDX_GPU), + .type = MOD_RES_PERF_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI_CLOCK, + JUNO_CLOCK_IDX_GPUCLK), + .type = MOD_RES_CLOCK_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI_POWER_DOMAIN, + POWER_DOMAIN_IDX_GPUTOP), + .type = MOD_RES_POWER_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_NONE_INIT, + .type = MOD_RES_DOMAIN_DEVICE_INVALID, + }, +}; + +static struct mod_res_domain_device devices_io[] = { + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI_CLOCK, + JUNO_CLOCK_IDX_HDLCD0), + .type = MOD_RES_CLOCK_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI_CLOCK, + JUNO_CLOCK_IDX_HDLCD1), + .type = MOD_RES_CLOCK_DOMAIN_DEVICE, + }, + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI_CLOCK, + JUNO_CLOCK_IDX_I2SCLK), + .type = MOD_RES_CLOCK_DOMAIN_DEVICE, + }, +#ifdef BUILD_HAS_SCMI_RESET + { + .device_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_RESET_DOMAIN, + JUNO_RESET_DOMAIN_IDX_UART), + .type = MOD_RES_RESET_DOMAIN_DEVICE, + }, +#endif + { + .device_id = FWK_ID_NONE_INIT, + .type = MOD_RES_DOMAIN_DEVICE_INVALID, + }, +}; + +static struct mod_res_device juno_devices[] = { + { + .device_id = JUNO_RES_PERMS_DEVICES_CPU, + .domain_devices = devices_cpu, + }, + { + .device_id = JUNO_RES_PERMS_DEVICES_GPU, + .domain_devices = devices_gpu, + }, + { + .device_id = JUNO_RES_PERMS_DEVICES_IO, + .domain_devices = devices_io, + }, + { 0 }, +}; + struct fwk_module_config config_resource_perms = { .data = &(struct mod_res_resource_perms_config){ @@ -335,8 +494,12 @@ 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, + .perf_cmd_count = JUNO_PERF_RESOURCE_CMDS, + .perf_resource_count = JUNO_PERF_RESOURCE_ELEMENTS, + .device_count = JUNO_RES_PERMS_DEVICES_COUNT, #ifdef BUILD_HAS_SCMI_RESET .reset_domain_count = JUNO_RESET_DOMAIN_IDX_COUNT, #endif + .domain_devices = (uintptr_t)&juno_devices, }, }; diff --git a/product/juno/scp_ramfw/config_resource_perms.h b/product/juno/scp_ramfw/config_resource_perms.h new file mode 100644 index 000000000..303687c20 --- /dev/null +++ b/product/juno/scp_ramfw/config_resource_perms.h @@ -0,0 +1,18 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CONFIG_RESOURCE_PERMS_H +#define CONFIG_RESOURCE_PERMS_H + +enum juno_res_perms_devices { + JUNO_RES_PERMS_DEVICES_CPU = 0, + JUNO_RES_PERMS_DEVICES_GPU, + JUNO_RES_PERMS_DEVICES_IO, + JUNO_RES_PERMS_DEVICES_COUNT +}; + +#endif /* CONFIG_RESOURCE_PERMS_H */ -- GitLab