1 /*
2 * Arm SCP/MCP Software
3 * Copyright (c) 2019-2021, Arm Limited and Contributors. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "sgm775_scmi.h"
9
10 #include <mod_resource_perms.h>
11 #include <mod_scmi_apcore.h>
12 #include <mod_scmi_std.h>
13
14 #include <fwk_element.h>
15 #include <fwk_id.h>
16 #include <fwk_macros.h>
17 #include <fwk_module.h>
18 #include <fwk_module_idx.h>
19
20 /*!
21 * If the agent wants to modify permissions at run-time these tables
22 * must be allocated in writable memory.
23 */
24
25 #define AGENT_IDX(agent_id) (agent_id - 1)
26
27 static struct mod_res_agent_protocol_permissions agent_protocol_permissions[] =
28 {
29 [AGENT_IDX(SCMI_AGENT_ID_OSPM)] =
30 {
31 .protocols = MOD_RES_PERMS_SCMI_ALL_PROTOCOLS_ALLOWED,
32 },
33
34 /* PSCI agent has no access to clock, perf and sensor protocol */
35 [AGENT_IDX(SCMI_AGENT_ID_PSCI)] =
36 {
37 .protocols = MOD_RES_PERMS_SCMI_CLOCK_PROTOCOL_DENIED |
38 MOD_RES_PERMS_SCMI_PERF_PROTOCOL_DENIED |
39 MOD_RES_PERMS_SCMI_SENSOR_PROTOCOL_DENIED,
40 },
41 };
42
43 /*
44 * Messages have an index offset from 0x3 as all agents can access
45 * the VERSION/ATTRIBUTES/MSG_ATTRIBUTES messages for all
46 * protocols, hence message 0x3 maps to bit[0], message 0x4 maps
47 * to bit[1], etc.
48 */
49 static struct mod_res_agent_msg_permissions agent_msg_permissions[] = {
50 [AGENT_IDX(SCMI_AGENT_ID_OSPM)] = {
51 .messages = {
52 /* Example, Base, disable unused msg 12 */
53 [MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX] = 0x0,
54 /* Power Domain */
55 [MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0,
56 /* System Power Domain */
57 [MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0,
58 /* Performance */
59 [MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = 0x0,
60 /* Clock */
61 [MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = 0x0,
62 /* Sensors */
63 [MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0,
64 /* Reset Domains */
65 [MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0,
66 },
67 },
68 [AGENT_IDX(SCMI_AGENT_ID_PSCI)] = {
69 .messages = {
70 [0] = 0x0, /* Base */
71 [1] = 0x0, /* Power Domain */
72 [2] = 0x0, /* System Power Domain */
73 [3] =
74 ((1 << (MOD_SCMI_PERF_DOMAIN_ATTRIBUTES -
75 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
76 /* DESCRIBE_LEVELS is required for some reason ... */
77 (0 << (MOD_SCMI_PERF_DESCRIBE_LEVELS -
78 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
79 (1 << (MOD_SCMI_PERF_LIMITS_SET -
80 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
81 (1 << (MOD_SCMI_PERF_LIMITS_GET -
82 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
83 (1 << (MOD_SCMI_PERF_LEVEL_SET -
84 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
85 (1 << (MOD_SCMI_PERF_LEVEL_GET -
86 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
87 (1 << (MOD_SCMI_PERF_NOTIFY_LIMITS -
88 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
89 (1 << (MOD_SCMI_PERF_NOTIFY_LEVEL -
90 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
91 (1 << (MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL -
92 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES))),
93 [4] = 0x0, /* Clock */
94 [5] = 0x0, /* Sensors */
95 },
96 },
97 };
98
99 /*
100 * Check whether an agent has access to a protocol.
101 *
102 * Note that we will always check the higher permissions levels
103 * when called, so
104 *
105 * protocol -> message -> resource
106 *
107 * This overrides the version in the resource_perms module
108 * for the platform specific protocols.
109 */
mod_res_plat_agent_protocol_permissions(uint32_t agent_id,uint32_t protocol_id)110 enum mod_res_perms_permissions mod_res_plat_agent_protocol_permissions(
111 uint32_t agent_id,
112 uint32_t protocol_id)
113 {
114 if (protocol_id == MOD_SCMI_PROTOCOL_ID_APCORE)
115 return MOD_RES_PERMS_ACCESS_ALLOWED;
116
117 return MOD_RES_PERMS_ACCESS_DENIED;
118 }
119
120 /*
121 * Check whether an agent can access a protocol:message.
122 *
123 * This overrides the version in the resource_perms module
124 * for the platform specific protocol:messages.
125 */
mod_res_plat_agent_message_permissions(uint32_t agent_id,uint32_t protocol_id,uint32_t message_id)126 enum mod_res_perms_permissions mod_res_plat_agent_message_permissions(
127 uint32_t agent_id,
128 uint32_t protocol_id,
129 uint32_t message_id)
130 {
131 if ((protocol_id == MOD_SCMI_PROTOCOL_ID_APCORE) &&
132 (message_id <= MOD_SCMI_APCORE_RESET_ADDRESS_GET)) {
133 return MOD_RES_PERMS_ACCESS_ALLOWED;
134 }
135
136 return MOD_RES_PERMS_ACCESS_DENIED;
137 }
138
139 /*
140 * Check the permissions for agent:protocol:message:resource.
141 *
142 * This overrides the version in the resource_perms module
143 * for the platform specific protocol:message:resources.
144 */
mod_res_plat_agent_resource_permissions(uint32_t agent_id,uint32_t protocol_id,uint32_t message_id,uint32_t resource_id)145 enum mod_res_perms_permissions mod_res_plat_agent_resource_permissions(
146 uint32_t agent_id,
147 uint32_t protocol_id,
148 uint32_t message_id,
149 uint32_t resource_id)
150 {
151 if ((protocol_id == MOD_SCMI_PROTOCOL_ID_APCORE) &&
152 (message_id <= MOD_SCMI_APCORE_RESET_ADDRESS_GET)) {
153 return MOD_RES_PERMS_ACCESS_ALLOWED;
154 }
155
156 return MOD_RES_PERMS_ACCESS_DENIED;
157 }
158
159 static struct mod_res_agent_permission agent_permissions = {
160 .agent_protocol_permissions = agent_protocol_permissions,
161 .agent_msg_permissions = agent_msg_permissions,
162 };
163
164 struct fwk_module_config config_resource_perms = {
165 .data =
166 &(struct mod_res_resource_perms_config){
167 .agent_permissions = (uintptr_t)&agent_permissions,
168 .agent_count = SCMI_AGENT_ID_COUNT,
169 .protocol_count = 6,
170 },
171 };
172