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