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 "config_clock.h"
9 #include "scp_rdn1e1_scmi.h"
10
11 #include <mod_resource_perms.h>
12 #include <mod_scmi_apcore.h>
13 #include <mod_scmi_std.h>
14
15 #include <fwk_element.h>
16 #include <fwk_id.h>
17 #include <fwk_macros.h>
18 #include <fwk_module.h>
19 #include <fwk_module_idx.h>
20
21 /*!
22 * If the agent wants to modify permissions at run-time these tables
23 * must be allocated in writable memory.
24 */
25
26 /*!
27 * Agent 0 gets access to all resources.
28 */
29 #define AGENT_IDX(agent_id) (agent_id - 1)
30
31 /*!
32 * Note that permissions are denied when a bit is set.
33 */
34 static struct mod_res_agent_protocol_permissions agent_protocol_permissions[] =
35 {
36 [AGENT_IDX(SCP_SCMI_AGENT_ID_OSPM)] =
37 {
38 .protocols = MOD_RES_PERMS_SCMI_ALL_PROTOCOLS_ALLOWED,
39 },
40
41 /* PSCI agent has no access to clock, perf and sensor protocol */
42 [AGENT_IDX(SCP_SCMI_AGENT_ID_PSCI)] =
43 {
44 .protocols = MOD_RES_PERMS_SCMI_CLOCK_PROTOCOL_DENIED |
45 MOD_RES_PERMS_SCMI_PERF_PROTOCOL_DENIED |
46 MOD_RES_PERMS_SCMI_SENSOR_PROTOCOL_DENIED,
47 },
48 };
49
50 /*
51 * Messages have an index offset from 0x3 as all agents can access
52 * the VERSION/ATTRIBUTES/MSG_ATTRIBUTES messages for all
53 * protocols, hence message 0x3 maps to bit[0], message 0x4 maps
54 * to bit[1], etc.
55 */
56 static struct mod_res_agent_msg_permissions agent_msg_permissions[] = {
57 [AGENT_IDX(SCP_SCMI_AGENT_ID_OSPM)] = {
58 .messages = {
59 /* Example, Base, disable unused msg 12 */
60 [MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX] =
61 (1 << 12), /* Example, Base, disable unused msg 12 */
62 /* Power Domain */
63 [MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0,
64 /* System Power Domain */
65 [MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0,
66 /* Performance */
67 [MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] = 0x0,
68 /* Clocks */
69 [MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = 0x0,
70 /* Sensors */
71 [MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0,
72 /* Reset Domains */
73 [MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0,
74 },
75 },
76
77 [AGENT_IDX(SCP_SCMI_AGENT_ID_PSCI)] = {
78 .messages = {
79 [MOD_RES_PERMS_SCMI_BASE_MESSAGE_IDX] = 0x0,
80 [MOD_RES_PERMS_SCMI_POWER_DOMAIN_MESSAGE_IDX] = 0x0,
81 [MOD_RES_PERMS_SCMI_SYS_POWER_MESSAGE_IDX] = 0x0,
82 [MOD_RES_PERMS_SCMI_PERF_MESSAGE_IDX] =
83 ((1 << (MOD_SCMI_PERF_DOMAIN_ATTRIBUTES -
84 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
85 /* DESCRIBE_LEVELS is required for some reason ... */
86 (0 << (MOD_SCMI_PERF_DESCRIBE_LEVELS -
87 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
88 (1 << (MOD_SCMI_PERF_LIMITS_SET -
89 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
90 (1 << (MOD_SCMI_PERF_LIMITS_GET -
91 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
92 (1 << (MOD_SCMI_PERF_LEVEL_SET -
93 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
94 (1 << (MOD_SCMI_PERF_LEVEL_GET -
95 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
96 (1 << (MOD_SCMI_PERF_NOTIFY_LIMITS -
97 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
98 (1 << (MOD_SCMI_PERF_NOTIFY_LEVEL -
99 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
100 (1 << (MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL -
101 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES))),
102 /* Clocks, no access */
103 [MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] = 0xff,
104 [MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0,
105 [MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0,
106 },
107 },
108 };
109
110 /*
111 * Protocols have an index offset from SCMI_BASE protocol, 0x10
112 * Note that the BASE and SYSTEM_POWER protocols are managed
113 * on a protocol:command basis, there is no resource permissions
114 * associated with the protocols.
115 */
116
117 /*
118 * We are tracking 5 SCMI Clock Protocol commands
119 *
120 * 0, SCMI_CLOCK_ATTRIBUTES
121 * 1, SCMI_CLOCK_RATE_GET
122 * 2, SCMI_CLOCK_RATE_SET
123 * 3, SCMI_CLOCK_CONFIG_SET
124 * 4, SCMI_CLOCK_DESCRIBE_RATES
125 */
126 #define RDN1E1_CLOCK_RESOURCE_CMDS 5
127 #define RDN1E1_CLOCK_RESOURCE_ELEMENTS \
128 ((CLOCK_IDX_COUNT >> MOD_RES_PERMS_TYPE_SHIFT) + 1)
129 static mod_res_perms_t scmi_clock_perms[][RDN1E1_CLOCK_RESOURCE_CMDS]
130 [RDN1E1_CLOCK_RESOURCE_ELEMENTS] = {
131 /* SCMI_PROTOCOL_ID_CLOCK */
132 /* 0, SCMI_CLOCK_ATTRIBUTES */
133 /* 1, SCMI_CLOCK_RATE_GET */
134 /* 2, SCMI_CLOCK_RATE_SET */
135 /* 3, SCMI_CLOCK_CONFIG_SET */
136 /* 4, SCMI_CLOCK_DESCRIBE_RATES */
137 [AGENT_IDX(SCP_SCMI_AGENT_ID_OSPM)] = {
138 [MOD_RES_PERMS_SCMI_CLOCK_ATTRIBUTES_IDX][0] = 0x0,
139 /*
140 * Clocks 0, 1, 2, 4 do not allow set commands,
141 * Clocks 3 and 5 allow rate_set/config_set
142 */
143 [MOD_RES_PERMS_SCMI_CLOCK_RATE_SET_IDX][0] =
144 ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)),
145 [MOD_RES_PERMS_SCMI_CLOCK_RATE_GET_IDX][0] =
146 ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)),
147 [MOD_RES_PERMS_SCMI_CLOCK_CONFIG_SET_IDX][0] = 0x0,
148 [MOD_RES_PERMS_SCMI_CLOCK_DESCRIBE_RATE_IDX][0] = 0x0,
149 },
150
151 [AGENT_IDX(SCP_SCMI_AGENT_ID_PSCI)] = {
152 /* No access to clocks for PSCI agent, set bits [4:0] */
153 [MOD_RES_PERMS_SCMI_CLOCK_ATTRIBUTES_IDX][0] = 0x1f,
154 [MOD_RES_PERMS_SCMI_CLOCK_RATE_SET_IDX][0] = 0x1f,
155 [MOD_RES_PERMS_SCMI_CLOCK_RATE_GET_IDX][0] = 0x1f,
156 [MOD_RES_PERMS_SCMI_CLOCK_CONFIG_SET_IDX][0] = 0x1f,
157 [MOD_RES_PERMS_SCMI_CLOCK_DESCRIBE_RATE_IDX][0] = 0x1f,
158 },
159 };
160
161 /*
162 * Check whether an agent has access to a protocol.
163 *
164 * Note that we will always check the higher permissions levels
165 * when called, so
166 *
167 * protocol -> message -> resource
168 *
169 * This overrides the version in the resource_perms module
170 * for the platform specific protocols.
171 */
mod_res_plat_agent_protocol_permissions(uint32_t agent_id,uint32_t protocol_id)172 enum mod_res_perms_permissions mod_res_plat_agent_protocol_permissions(
173 uint32_t agent_id,
174 uint32_t protocol_id)
175 {
176 if (protocol_id == MOD_SCMI_PROTOCOL_ID_APCORE)
177 return MOD_RES_PERMS_ACCESS_ALLOWED;
178
179 return MOD_RES_PERMS_ACCESS_DENIED;
180 }
181
182 /*
183 * Check whether an agent can access a protocol:message.
184 *
185 * This overrides the version in the resource_perms module
186 * for the platform specific protocol:messages.
187 */
mod_res_plat_agent_message_permissions(uint32_t agent_id,uint32_t protocol_id,uint32_t message_id)188 enum mod_res_perms_permissions mod_res_plat_agent_message_permissions(
189 uint32_t agent_id,
190 uint32_t protocol_id,
191 uint32_t message_id)
192 {
193 if ((protocol_id == MOD_SCMI_PROTOCOL_ID_APCORE) &&
194 (message_id <= MOD_SCMI_APCORE_RESET_ADDRESS_GET))
195 return MOD_RES_PERMS_ACCESS_ALLOWED;
196
197 return MOD_RES_PERMS_ACCESS_DENIED;
198 }
199
200 /*
201 * Check the permissions for agent:protocol:message:resource.
202 *
203 * This overrides the version in the resource_perms module
204 * for the platform specific protocol:message:resources.
205 */
mod_res_plat_agent_resource_permissions(uint32_t agent_id,uint32_t protocol_id,uint32_t message_id,uint32_t resource_id)206 enum mod_res_perms_permissions mod_res_plat_agent_resource_permissions(
207 uint32_t agent_id,
208 uint32_t protocol_id,
209 uint32_t message_id,
210 uint32_t resource_id)
211 {
212 if ((protocol_id == MOD_SCMI_PROTOCOL_ID_APCORE) &&
213 (message_id <= MOD_SCMI_APCORE_RESET_ADDRESS_GET))
214 return MOD_RES_PERMS_ACCESS_ALLOWED;
215
216 return MOD_RES_PERMS_ACCESS_DENIED;
217 }
218 static struct mod_res_agent_permission agent_permissions = {
219 .agent_protocol_permissions = agent_protocol_permissions,
220 .agent_msg_permissions = agent_msg_permissions,
221 .scmi_clock_perms = &scmi_clock_perms[0][0][0],
222 };
223
224 struct fwk_module_config config_resource_perms = {
225 .data =
226 &(struct mod_res_resource_perms_config){
227 .agent_permissions = (uintptr_t)&agent_permissions,
228 .agent_count = SCP_SCMI_AGENT_ID_COUNT,
229 .protocol_count = 6,
230 .clock_count = CLOCK_IDX_COUNT,
231 },
232 };
233