diff options
-rw-r--r-- | module/resource_perms/include/mod_resource_perms.h | 2 | ||||
-rw-r--r-- | module/scmi/include/internal/scmi_base.h | 39 | ||||
-rw-r--r-- | module/scmi/include/mod_scmi_std.h | 3 | ||||
-rw-r--r-- | 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 0a1284d9..40e250b7 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 170f88da..4be32e1c 100644 --- a/module/scmi/include/internal/scmi_base.h +++ b/module/scmi/include/internal/scmi_base.h @@ -76,4 +76,43 @@ struct 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 3398e5fb..9a05ddd6 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 6f382ee1..ffb367d1 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, |