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