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_sgi575_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 SGI575_CLOCK_RESOURCE_CMDS 5
127 #define SGI575_CLOCK_RESOURCE_ELEMENTS \
128 ((CLOCK_IDX_COUNT >> MOD_RES_PERMS_TYPE_SHIFT) + 1)
129 static mod_res_perms_t
130 scmi_clock_perms[][SGI575_CLOCK_RESOURCE_CMDS]
131 [SGI575_CLOCK_RESOURCE_ELEMENTS] = {
132 /* SCMI_PROTOCOL_ID_CLOCK */
133 /* 0, SCMI_CLOCK_ATTRIBUTES */
134 /* 1, SCMI_CLOCK_RATE_GET */
135 /* 2, SCMI_CLOCK_RATE_SET */
136 /* 3, SCMI_CLOCK_CONFIG_SET */
137 /* 4, SCMI_CLOCK_DESCRIBE_RATES */
138 [AGENT_IDX(SCP_SCMI_AGENT_ID_OSPM)] = {
139 [MOD_RES_PERMS_SCMI_CLOCK_ATTRIBUTES_IDX][0] = 0x0,
140 /*
141 * Clocks 0, 1, 2, 4 do not allow set commands,
142 * Clocks 3 and 5 allow rate_set/config_set
143 */
144 [MOD_RES_PERMS_SCMI_CLOCK_RATE_SET_IDX][0] =
145 ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)),
146 [MOD_RES_PERMS_SCMI_CLOCK_RATE_GET_IDX][0] =
147 ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)),
148 [MOD_RES_PERMS_SCMI_CLOCK_CONFIG_SET_IDX][0] = 0x0,
149 [MOD_RES_PERMS_SCMI_CLOCK_DESCRIBE_RATE_IDX][0] = 0x0,
150 },
151 [AGENT_IDX(SCP_SCMI_AGENT_ID_PSCI)] = {
152 /* No access to clocks for PSCI agent, so bits [4:0] set */
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
198 return MOD_RES_PERMS_ACCESS_DENIED;
199 }
200
201 /*
202 * Check the permissions for agent:protocol:message:resource.
203 *
204 * This overrides the version in the resource_perms module
205 * for the platform specific protocol:message:resources.
206 */
mod_res_plat_agent_resource_permissions(uint32_t agent_id,uint32_t protocol_id,uint32_t message_id,uint32_t resource_id)207 enum mod_res_perms_permissions mod_res_plat_agent_resource_permissions(
208 uint32_t agent_id,
209 uint32_t protocol_id,
210 uint32_t message_id,
211 uint32_t resource_id)
212 {
213 if ((protocol_id == MOD_SCMI_PROTOCOL_ID_APCORE) &&
214 (message_id <= MOD_SCMI_APCORE_RESET_ADDRESS_GET)) {
215 return MOD_RES_PERMS_ACCESS_ALLOWED;
216 }
217
218 return MOD_RES_PERMS_ACCESS_DENIED;
219 }
220 static struct mod_res_agent_permission agent_permissions = {
221 .agent_protocol_permissions = agent_protocol_permissions,
222 .agent_msg_permissions = agent_msg_permissions,
223 .scmi_clock_perms = &scmi_clock_perms[0][0][0],
224 };
225
226 struct fwk_module_config config_resource_perms = {
227 .data =
228 &(struct mod_res_resource_perms_config){
229 .agent_permissions = (uintptr_t)&agent_permissions,
230 .agent_count = SCP_SCMI_AGENT_ID_COUNT,
231 .protocol_count = 6,
232 .clock_count = CLOCK_IDX_COUNT,
233 },
234 };
235