38
38
* messages.
39
39
*
40
40
* All requests with FFA_MSG_SEND_DIRECT_REQ and FFA_MSG_SEND_DIRECT_RESP
41
- * are using the AArch32 SMC calling convention with register usage as
42
- * defined in FF-A specification:
43
- * w0: Function ID (0x8400006F or 0x84000070)
41
+ * are using the AArch32 or AArch64 SMC calling convention with register usage
42
+ * as defined in FF-A specification:
43
+ * w0: Function ID
44
+ * -for 32-bit: 0x8400006F or 0x84000070
45
+ * -for 64-bit: 0xC400006F or 0xC4000070
44
46
* w1: Source/Destination IDs
45
47
* w2: Reserved (MBZ)
46
48
* w3-w7: Implementation defined, free to be used below
68
70
#define CRB_FFA_GET_INTERFACE_VERSION 0x0f000001
69
71
70
72
/*
71
- * Return information on a given feature of the TPM service
73
+ * Notifies the TPM service that a TPM command or TPM locality request is
74
+ * ready to be processed, and allows the TPM service to process it.
72
75
* Call register usage:
73
76
* w3: Not used (MBZ)
74
77
* w4: TPM service function ID, CRB_FFA_START
@@ -105,7 +108,10 @@ struct tpm_crb_ffa {
105
108
u16 minor_version ;
106
109
/* lock to protect sending of FF-A messages: */
107
110
struct mutex msg_data_lock ;
108
- struct ffa_send_direct_data direct_msg_data ;
111
+ union {
112
+ struct ffa_send_direct_data direct_msg_data ;
113
+ struct ffa_send_direct_data2 direct_msg_data2 ;
114
+ };
109
115
};
110
116
111
117
static struct tpm_crb_ffa * tpm_crb_ffa ;
@@ -185,18 +191,34 @@ static int __tpm_crb_ffa_send_recieve(unsigned long func_id,
185
191
186
192
msg_ops = tpm_crb_ffa -> ffa_dev -> ops -> msg_ops ;
187
193
188
- memset (& tpm_crb_ffa -> direct_msg_data , 0x00 ,
189
- sizeof (struct ffa_send_direct_data ));
190
-
191
- tpm_crb_ffa -> direct_msg_data .data1 = func_id ;
192
- tpm_crb_ffa -> direct_msg_data .data2 = a0 ;
193
- tpm_crb_ffa -> direct_msg_data .data3 = a1 ;
194
- tpm_crb_ffa -> direct_msg_data .data4 = a2 ;
194
+ if (ffa_partition_supports_direct_req2_recv (tpm_crb_ffa -> ffa_dev )) {
195
+ memset (& tpm_crb_ffa -> direct_msg_data2 , 0x00 ,
196
+ sizeof (struct ffa_send_direct_data2 ));
197
+
198
+ tpm_crb_ffa -> direct_msg_data2 .data [0 ] = func_id ;
199
+ tpm_crb_ffa -> direct_msg_data2 .data [1 ] = a0 ;
200
+ tpm_crb_ffa -> direct_msg_data2 .data [2 ] = a1 ;
201
+ tpm_crb_ffa -> direct_msg_data2 .data [3 ] = a2 ;
202
+
203
+ ret = msg_ops -> sync_send_receive2 (tpm_crb_ffa -> ffa_dev ,
204
+ & tpm_crb_ffa -> direct_msg_data2 );
205
+ if (!ret )
206
+ ret = tpm_crb_ffa_to_linux_errno (tpm_crb_ffa -> direct_msg_data2 .data [0 ]);
207
+ } else {
208
+ memset (& tpm_crb_ffa -> direct_msg_data , 0x00 ,
209
+ sizeof (struct ffa_send_direct_data ));
210
+
211
+ tpm_crb_ffa -> direct_msg_data .data1 = func_id ;
212
+ tpm_crb_ffa -> direct_msg_data .data2 = a0 ;
213
+ tpm_crb_ffa -> direct_msg_data .data3 = a1 ;
214
+ tpm_crb_ffa -> direct_msg_data .data4 = a2 ;
215
+
216
+ ret = msg_ops -> sync_send_receive (tpm_crb_ffa -> ffa_dev ,
217
+ & tpm_crb_ffa -> direct_msg_data );
218
+ if (!ret )
219
+ ret = tpm_crb_ffa_to_linux_errno (tpm_crb_ffa -> direct_msg_data .data1 );
220
+ }
195
221
196
- ret = msg_ops -> sync_send_receive (tpm_crb_ffa -> ffa_dev ,
197
- & tpm_crb_ffa -> direct_msg_data );
198
- if (!ret )
199
- ret = tpm_crb_ffa_to_linux_errno (tpm_crb_ffa -> direct_msg_data .data1 );
200
222
201
223
return ret ;
202
224
}
@@ -231,8 +253,13 @@ int tpm_crb_ffa_get_interface_version(u16 *major, u16 *minor)
231
253
232
254
rc = __tpm_crb_ffa_send_recieve (CRB_FFA_GET_INTERFACE_VERSION , 0x00 , 0x00 , 0x00 );
233
255
if (!rc ) {
234
- * major = CRB_FFA_MAJOR_VERSION (tpm_crb_ffa -> direct_msg_data .data2 );
235
- * minor = CRB_FFA_MINOR_VERSION (tpm_crb_ffa -> direct_msg_data .data2 );
256
+ if (ffa_partition_supports_direct_req2_recv (tpm_crb_ffa -> ffa_dev )) {
257
+ * major = CRB_FFA_MAJOR_VERSION (tpm_crb_ffa -> direct_msg_data2 .data [1 ]);
258
+ * minor = CRB_FFA_MINOR_VERSION (tpm_crb_ffa -> direct_msg_data2 .data [1 ]);
259
+ } else {
260
+ * major = CRB_FFA_MAJOR_VERSION (tpm_crb_ffa -> direct_msg_data .data2 );
261
+ * minor = CRB_FFA_MINOR_VERSION (tpm_crb_ffa -> direct_msg_data .data2 );
262
+ }
236
263
}
237
264
238
265
return rc ;
@@ -277,8 +304,9 @@ static int tpm_crb_ffa_probe(struct ffa_device *ffa_dev)
277
304
278
305
tpm_crb_ffa = ERR_PTR (- ENODEV ); // set tpm_crb_ffa so we can detect probe failure
279
306
280
- if (!ffa_partition_supports_direct_recv (ffa_dev )) {
281
- pr_err ("TPM partition doesn't support direct message receive.\n" );
307
+ if (!ffa_partition_supports_direct_recv (ffa_dev ) &&
308
+ !ffa_partition_supports_direct_req2_recv (ffa_dev )) {
309
+ dev_warn (& ffa_dev -> dev , "partition doesn't support direct message receive.\n" );
282
310
return - EINVAL ;
283
311
}
284
312
@@ -299,17 +327,17 @@ static int tpm_crb_ffa_probe(struct ffa_device *ffa_dev)
299
327
rc = tpm_crb_ffa_get_interface_version (& tpm_crb_ffa -> major_version ,
300
328
& tpm_crb_ffa -> minor_version );
301
329
if (rc ) {
302
- pr_err ( "failed to get crb interface version. rc:%d" , rc );
330
+ dev_err ( & ffa_dev -> dev , "failed to get crb interface version. rc:%d\n " , rc );
303
331
goto out ;
304
332
}
305
333
306
- pr_info ( "ABI version %u.%u" , tpm_crb_ffa -> major_version ,
334
+ dev_info ( & ffa_dev -> dev , "ABI version %u.%u\n " , tpm_crb_ffa -> major_version ,
307
335
tpm_crb_ffa -> minor_version );
308
336
309
337
if (tpm_crb_ffa -> major_version != CRB_FFA_VERSION_MAJOR ||
310
338
(tpm_crb_ffa -> minor_version > 0 &&
311
339
tpm_crb_ffa -> minor_version < CRB_FFA_VERSION_MINOR )) {
312
- pr_err ( "Incompatible ABI version" );
340
+ dev_warn ( & ffa_dev -> dev , "Incompatible ABI version\n " );
313
341
goto out ;
314
342
}
315
343
0 commit comments