aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Quigley <jim.quigley@arm.com>2020-07-20 10:31:29 +0100
committerChris Kay <chris@cjkay.com>2020-07-31 16:40:53 +0100
commit78ae18495727c0e849215ced76b2359f7c06b612 (patch)
tree818d6c2ce24a04b13b009bfb82fc910d0faeb190
parentbdccb0c7bf3e3337accf734911c1b062915b2de3 (diff)
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 <jim.quigley@arm.com>
-rw-r--r--module/resource_perms/include/mod_resource_perms.h2
-rw-r--r--module/scmi/include/internal/scmi_base.h39
-rw-r--r--module/scmi/include/mod_scmi_std.h3
-rw-r--r--module/scmi/src/mod_scmi.c152
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,