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 "sgm776_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             /*
61             * sgm776 denies access to CONFIG_SET
62             */
63             [MOD_RES_PERMS_SCMI_CLOCK_MESSAGE_IDX] =
64                 MOD_RES_PERMS_ACCESS_DENIED <<
65                 (MOD_SCMI_CLOCK_CONFIG_SET - MOD_SCMI_CLOCK_ATTRIBUTES),
66             /* Sensors */
67             [MOD_RES_PERMS_SCMI_SENSOR_MESSAGE_IDX] = 0x0,
68             /* Reset Domains */
69             [MOD_RES_PERMS_SCMI_RESET_DOMAIN_MESSAGE_IDX] = 0x0,
70         },
71 
72     },
73     [AGENT_IDX(SCMI_AGENT_ID_PSCI)] = {
74         .messages = {
75             [0] = 0x0, /* Base */
76             [1] = 0x0, /* Power Domain */
77             [2] = 0x0, /* System Power Domain */
78             [3] =
79                 ((1 << (MOD_SCMI_PERF_DOMAIN_ATTRIBUTES -
80                     MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
81                 /* DESCRIBE_LEVELS is required for some reason ... */
82                 (0 << (MOD_SCMI_PERF_DESCRIBE_LEVELS -
83                     MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
84                 (1 << (MOD_SCMI_PERF_LIMITS_SET -
85                     MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
86                 (1 << (MOD_SCMI_PERF_LIMITS_GET -
87                     MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
88                 (1 << (MOD_SCMI_PERF_LEVEL_SET -
89                     MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
90                 (1 << (MOD_SCMI_PERF_LEVEL_GET -
91                     MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
92                 (1 << (MOD_SCMI_PERF_NOTIFY_LIMITS -
93                     MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
94                 (1 << (MOD_SCMI_PERF_NOTIFY_LEVEL -
95                     MOD_SCMI_PERF_DOMAIN_ATTRIBUTES)) |
96                 (1 << (MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL -
97                     MOD_SCMI_PERF_DOMAIN_ATTRIBUTES))),
98                 /* SGM776 denies access to CONFIG_SET */
99             [4] =
100                 (1 << (MOD_SCMI_CLOCK_CONFIG_SET - MOD_SCMI_CLOCK_ATTRIBUTES)),
101             [5] = 0x0, /* Sensors */
102         },
103     },
104 };
105 
106 /*
107  * Check whether an agent has access to a protocol.
108  *
109  * Note that we will always check the higher permissions levels
110  * when called, so
111  *
112  *      protocol -> message -> resource
113  *
114  * This overrides the version in the resource_perms module
115  * for the platform specific protocols.
116  */
mod_res_plat_agent_protocol_permissions(uint32_t agent_id,uint32_t protocol_id)117 enum mod_res_perms_permissions mod_res_plat_agent_protocol_permissions(
118     uint32_t agent_id,
119     uint32_t protocol_id)
120 {
121     if (protocol_id == MOD_SCMI_PROTOCOL_ID_APCORE)
122         return MOD_RES_PERMS_ACCESS_ALLOWED;
123 
124     return MOD_RES_PERMS_ACCESS_DENIED;
125 }
126 
127 /*
128  * Check whether an agent can access a protocol:message.
129  *
130  * This overrides the version in the resource_perms module
131  * for the platform specific protocol:messages.
132  */
mod_res_plat_agent_message_permissions(uint32_t agent_id,uint32_t protocol_id,uint32_t message_id)133 enum mod_res_perms_permissions mod_res_plat_agent_message_permissions(
134     uint32_t agent_id,
135     uint32_t protocol_id,
136     uint32_t message_id)
137 {
138     if ((protocol_id == MOD_SCMI_PROTOCOL_ID_APCORE) &&
139         (message_id <= MOD_SCMI_APCORE_RESET_ADDRESS_GET)) {
140         return MOD_RES_PERMS_ACCESS_ALLOWED;
141     }
142 
143     return MOD_RES_PERMS_ACCESS_DENIED;
144 }
145 
146 /*
147  * Check the permissions for agent:protocol:message:resource.
148  *
149  * This overrides the version in the resource_perms module
150  * for the platform specific protocol:message:resources.
151  */
mod_res_plat_agent_resource_permissions(uint32_t agent_id,uint32_t protocol_id,uint32_t message_id,uint32_t resource_id)152 enum mod_res_perms_permissions mod_res_plat_agent_resource_permissions(
153     uint32_t agent_id,
154     uint32_t protocol_id,
155     uint32_t message_id,
156     uint32_t resource_id)
157 {
158     if ((protocol_id == MOD_SCMI_PROTOCOL_ID_APCORE) &&
159         (message_id <= MOD_SCMI_APCORE_RESET_ADDRESS_GET)) {
160         return MOD_RES_PERMS_ACCESS_ALLOWED;
161     }
162 
163     return MOD_RES_PERMS_ACCESS_DENIED;
164 }
165 static struct mod_res_agent_permission agent_permissions = {
166     .agent_protocol_permissions = agent_protocol_permissions,
167     .agent_msg_permissions = agent_msg_permissions,
168 };
169 
170 struct fwk_module_config config_resource_perms = {
171     .data =
172         &(struct mod_res_resource_perms_config){
173             .agent_permissions = (uintptr_t)&agent_permissions,
174             .agent_count = SCMI_AGENT_ID_COUNT,
175             .protocol_count = 6,
176         },
177 };
178