1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (C) 2016-2022 Texas Instruments Incorporated - https://www.ti.com/
4  *	Lokesh Vutla <lokeshvutla@ti.com>
5  *	Manorit Chawdhry <m-chawdhry@ti.com>
6  */
7 
8 #ifndef TI_SCI_PROTOCOL_H
9 #define TI_SCI_PROTOCOL_H
10 
11 #include <compiler.h>
12 #include <stdint.h>
13 #include <util.h>
14 
15 /* Generic Messages */
16 #define TI_SCI_MSG_VERSION               0x0002
17 
18 /* Device requests */
19 #define TI_SCI_MSG_SET_DEVICE_STATE      0x0200
20 
21 /* Security Management Messages */
22 #define TI_SCI_MSG_FWL_SET               0x9000
23 #define TI_SCI_MSG_FWL_GET               0x9001
24 #define TI_SCI_MSG_FWL_CHANGE_OWNER      0x9002
25 #define TI_SCI_MSG_SA2UL_GET_DKEK        0x9029
26 
27 /**
28  * struct ti_sci_secure_msg_hdr - Secure Message Header for All messages
29  *				 and responses
30  *
31  * @checksum:	Integrity check for HS devices
32  * @reserved:	Reserved for future uses
33  */
34 struct ti_sci_secure_msg_hdr {
35 	uint16_t checksum;
36 	uint16_t reserved;
37 } __packed;
38 
39 /**
40  * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses
41  * @type:	Type of messages: One of TI_SCI_MSG* values
42  * @host:	Host of the message
43  * @seq:	Message identifier indicating a transfer sequence
44  * @flags:	Flag for the message
45  */
46 struct ti_sci_msg_hdr {
47 	struct ti_sci_secure_msg_hdr sec_hdr;
48 	uint16_t type;
49 	uint8_t host;
50 	uint8_t seq;
51 #define TI_SCI_MSG_FLAG(val)			BIT(val)
52 #define TI_SCI_FLAG_REQ_GENERIC_NORESPONSE	0x0
53 #define TI_SCI_FLAG_REQ_ACK_ON_RECEIVED		TI_SCI_MSG_FLAG(0)
54 #define TI_SCI_FLAG_REQ_ACK_ON_PROCESSED	TI_SCI_MSG_FLAG(1)
55 #define TI_SCI_FLAG_RESP_GENERIC_NACK		0x0
56 #define TI_SCI_FLAG_RESP_GENERIC_ACK		TI_SCI_MSG_FLAG(1)
57 	/* Additional Flags */
58 	uint32_t flags;
59 } __packed;
60 
61 /**
62  * struct ti_sci_msg_version_req - Request for firmware version information
63  * @hdr:	Generic header
64  *
65  * Request for TI_SCI_MSG_VERSION
66  */
67 struct ti_sci_msg_req_version {
68 	struct ti_sci_msg_hdr hdr;
69 } __packed;
70 
71 /**
72  * struct ti_sci_msg_resp_version - Response for firmware version information
73  * @hdr:		Generic header
74  * @firmware_description: String describing the firmware
75  * @firmware_revision:	Firmware revision
76  * @abi_major:		Major version of the ABI that firmware supports
77  * @abi_minor:		Minor version of the ABI that firmware supports
78  * @sub_version:	Sub-version number of the firmware
79  * @patch_version:	Patch-version number of the firmware.
80  *
81  * In general, ABI version changes follow the rule that minor version increments
82  * are backward compatible. Major revision changes in ABI may not be
83  * backward compatible.
84  *
85  * Response to request TI_SCI_MSG_VERSION
86  */
87 struct ti_sci_msg_resp_version {
88 	struct ti_sci_msg_hdr hdr;
89 #define FIRMWARE_DESCRIPTION_LENGTH 32
90 	char firmware_description[FIRMWARE_DESCRIPTION_LENGTH];
91 	uint16_t firmware_revision;
92 	uint8_t abi_major;
93 	uint8_t abi_minor;
94 	uint8_t sub_version;
95 	uint8_t patch_version;
96 } __packed;
97 
98 /**
99  * struct ti_sci_msg_req_set_device_state - Set the desired state of the device
100  * @hdr:	Generic header
101  * @id:		Indicates which device to modify
102  * @reserved:	Reserved space in message, must be 0 for backward compatibility
103  * @state:	The desired state of the device.
104  *
105  * Certain flags can also be set to alter the device state:
106  * + MSG_FLAG_DEVICE_WAKE_ENABLED - Configure the device to be a wake source.
107  * The meaning of this flag will vary slightly from device to device and from
108  * SoC to SoC but it generally allows the device to wake the SoC out of deep
109  * suspend states.
110  * + MSG_FLAG_DEVICE_RESET_ISO - Enable reset isolation for this device.
111  * + MSG_FLAG_DEVICE_EXCLUSIVE - Claim this device exclusively. When passed
112  * with STATE_RETENTION or STATE_ON, it will claim the device exclusively.
113  * If another host already has this device set to STATE_RETENTION or STATE_ON,
114  * the message will fail. Once successful, other hosts attempting to set
115  * STATE_RETENTION or STATE_ON will fail.
116  *
117  * Request type is TI_SCI_MSG_SET_DEVICE_STATE, responded with a generic
118  * ACK/NACK message.
119  */
120 struct ti_sci_msg_req_set_device_state {
121 	/* Additional hdr->flags options */
122 #define MSG_FLAG_DEVICE_WAKE_ENABLED	TI_SCI_MSG_FLAG(8)
123 #define MSG_FLAG_DEVICE_RESET_ISO	TI_SCI_MSG_FLAG(9)
124 #define MSG_FLAG_DEVICE_EXCLUSIVE	TI_SCI_MSG_FLAG(10)
125 	struct ti_sci_msg_hdr hdr;
126 	uint32_t id;
127 	uint32_t reserved;
128 
129 #define MSG_DEVICE_SW_STATE_AUTO_OFF	0
130 #define MSG_DEVICE_SW_STATE_RETENTION	1
131 #define MSG_DEVICE_SW_STATE_ON		2
132 	uint8_t state;
133 } __packed;
134 
135 /**
136  * struct ti_sci_msg_resp_set_device_state - Response for set device state
137  * @hdr:	Generic header
138  *
139  * Response to request TI_SCI_MSG_SET_DEVICE_STATE
140  */
141 struct ti_sci_msg_resp_set_device_state {
142 	struct ti_sci_msg_hdr hdr;
143 } __packed;
144 
145 #define FWL_MAX_PRIVID_SLOTS 3U
146 
147 /**
148  * struct ti_sci_msg_req_fwl_set_firewall_region - Set firewall permissions
149  * @hdr:		Generic Header
150  * @fwl_id:		Firewall ID
151  * @region:		Region or channel number to set config info.
152  *			This field is unused in case of a simple firewall and
153  *			must be initialized to zero.  In case of a region based
154  *			firewall, this field indicates the region (index
155  *			starting from 0). In case of a channel based firewall,
156  *			this field indicates the channel (index starting
157  *			from 0).
158  * @n_permission_regs:	Number of permission registers to set
159  * @control:		Contents of the firewall CONTROL register to set
160  * @permissions:	Contents of the firewall PERMISSION register to set
161  * @start_address:	Contents of the firewall START_ADDRESS register to set
162  * @end_address:	Contents of the firewall END_ADDRESS register to set
163  */
164 struct ti_sci_msg_req_fwl_set_firewall_region {
165 	struct ti_sci_msg_hdr hdr;
166 	uint16_t fwl_id;
167 	uint16_t region;
168 	uint32_t n_permission_regs;
169 	uint32_t control;
170 	uint32_t permissions[FWL_MAX_PRIVID_SLOTS];
171 	uint64_t start_address;
172 	uint64_t end_address;
173 } __packed;
174 
175 struct ti_sci_msg_resp_fwl_set_firewall_region {
176 	struct ti_sci_msg_hdr hdr;
177 } __packed;
178 
179 /**
180  * struct ti_sci_msg_req_fwl_get_firewall_region - Retrieve firewall permissions
181  * @hdr:		Generic Header
182  * @fwl_id:		Firewall ID in question
183  * @region:		Region or channel number to set config info.
184  *			This field is unused in case of a simple firewall and
185  *			must be initialized to zero.  In case of a region based
186  *			firewall, this field indicates the region (index
187  *			starting from 0). In case of a channel based firewall,
188  *			this field indicates the channel (index starting
189  *			from 0).
190  * @n_permission_regs:	Number of permission registers to retrieve
191  */
192 struct ti_sci_msg_req_fwl_get_firewall_region {
193 	struct ti_sci_msg_hdr hdr;
194 	uint16_t fwl_id;
195 	uint16_t region;
196 	uint32_t n_permission_regs;
197 } __packed;
198 
199 /**
200  * struct ti_sci_msg_resp_fwl_get_firewall_region - Response for retrieving the
201  *						    firewall permissions
202  *
203  * @hdr:		Generic Header
204  *
205  * @fwl_id:		Firewall ID in question
206  * @region:		Region or channel number to set config info.
207  *			This field is unused in case of a simple firewall and
208  *			must be initialized to zero.  In case of a region based
209  *			firewall, this field indicates the region (index
210  *			starting from 0). In case of a channel based firewall,
211  *			this field indicates the channel (index starting
212  *			from 0).
213  * @n_permission_regs:	Number of permission registers retrieved
214  * @control:		Contents of the firewall CONTROL register
215  * @permissions:	Contents of the firewall PERMISSION registers
216  * @start_address:	Contents of the firewall START_ADDRESS register
217  * @end_address:	Contents of the firewall END_ADDRESS register
218  */
219 struct ti_sci_msg_resp_fwl_get_firewall_region {
220 	struct ti_sci_msg_hdr hdr;
221 	uint16_t fwl_id;
222 	uint16_t region;
223 	uint32_t n_permission_regs;
224 	uint32_t control;
225 	uint32_t permissions[FWL_MAX_PRIVID_SLOTS];
226 	uint64_t start_address;
227 	uint64_t end_address;
228 } __packed;
229 
230 /**
231  * struct ti_sci_msg_req_fwl_change_owner_info - Request change firewall owner
232  *
233  * @hdr:		Generic Header
234  *
235  * @fwl_id:		Firewall ID in question
236  * @region:		Region or channel number if applicable
237  * @owner_index:	New owner index to transfer ownership to
238  */
239 struct ti_sci_msg_req_fwl_change_owner_info {
240 	struct ti_sci_msg_hdr hdr;
241 	uint16_t fwl_id;
242 	uint16_t region;
243 	uint8_t owner_index;
244 } __packed;
245 
246 /**
247  * struct ti_sci_msg_resp_fwl_change_owner_info - Response for change
248  *						  firewall owner
249  *
250  * @hdr:		Generic Header
251  *
252  * @fwl_id:		Firewall ID specified in request
253  * @region:		Region or channel number specified in request
254  * @owner_index:	Owner index specified in request
255  * @owner_privid:	New owner priv-ID returned by DMSC.
256  * @owner_permission_bits:	New owner permission bits returned by DMSC.
257  */
258 struct ti_sci_msg_resp_fwl_change_owner_info {
259 	struct ti_sci_msg_hdr hdr;
260 	uint16_t fwl_id;
261 	uint16_t region;
262 	uint8_t owner_index;
263 	uint8_t owner_privid;
264 	uint16_t owner_permission_bits;
265 } __packed;
266 
267 /**
268  * struct ti_sci_msg_sa2ul_get_dkek_req - Request for DKEK value
269  * @hdr:			Generic header
270  * @sa2ul_instance:		SA2UL instance number - set to 0
271  * @kdf_label_len:		Length of "Label" input to KDF
272  * @kdf_context_len:		Length of "Context" input to KDF
273  * @kdf_label_and_context:	"Label" and "Context" bytes
274  *
275  * Request for TI_SCI_MSG_SA2UL_GET_DKEK
276  */
277 struct ti_sci_msg_req_sa2ul_get_dkek {
278 	struct ti_sci_msg_hdr hdr;
279 	uint8_t sa2ul_instance;
280 	uint8_t kdf_label_len;
281 	uint8_t kdf_context_len;
282 #define KDF_LABEL_AND_CONTEXT_LEN_MAX 41
283 	uint8_t kdf_label_and_context[KDF_LABEL_AND_CONTEXT_LEN_MAX];
284 } __packed;
285 
286 /**
287  * struct ti_sci_msg_sa2ul_get_dkek_req - Response for DKEK value
288  * @hdr:	Generic header
289  * @dkek:	Array containing Derived KEK
290  *
291  * Response to request TI_SCI_MSG_SA2UL_GET_DKEK
292  */
293 struct ti_sci_msg_resp_sa2ul_get_dkek {
294 	struct ti_sci_msg_hdr hdr;
295 #define SA2UL_DKEK_KEY_LEN 32
296 	uint8_t dkek[SA2UL_DKEK_KEY_LEN];
297 } __packed;
298 
299 #endif
300