3838 * messages.
3939 *
4040 * 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
4446 * w1: Source/Destination IDs
4547 * w2: Reserved (MBZ)
4648 * w3-w7: Implementation defined, free to be used below
6870#define CRB_FFA_GET_INTERFACE_VERSION 0x0f000001
6971
7072/*
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.
7275 * Call register usage:
7376 * w3: Not used (MBZ)
7477 * w4: TPM service function ID, CRB_FFA_START
@@ -105,7 +108,10 @@ struct tpm_crb_ffa {
105108 u16 minor_version ;
106109 /* lock to protect sending of FF-A messages: */
107110 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+ };
109115};
110116
111117static struct tpm_crb_ffa * tpm_crb_ffa ;
@@ -185,18 +191,34 @@ static int __tpm_crb_ffa_send_recieve(unsigned long func_id,
185191
186192 msg_ops = tpm_crb_ffa -> ffa_dev -> ops -> msg_ops ;
187193
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+ }
195221
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 );
200222
201223 return ret ;
202224}
@@ -231,8 +253,13 @@ int tpm_crb_ffa_get_interface_version(u16 *major, u16 *minor)
231253
232254 rc = __tpm_crb_ffa_send_recieve (CRB_FFA_GET_INTERFACE_VERSION , 0x00 , 0x00 , 0x00 );
233255 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+ }
236263 }
237264
238265 return rc ;
@@ -277,8 +304,9 @@ static int tpm_crb_ffa_probe(struct ffa_device *ffa_dev)
277304
278305 tpm_crb_ffa = ERR_PTR (- ENODEV ); // set tpm_crb_ffa so we can detect probe failure
279306
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" );
282310 return - EINVAL ;
283311 }
284312
@@ -299,17 +327,17 @@ static int tpm_crb_ffa_probe(struct ffa_device *ffa_dev)
299327 rc = tpm_crb_ffa_get_interface_version (& tpm_crb_ffa -> major_version ,
300328 & tpm_crb_ffa -> minor_version );
301329 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 );
303331 goto out ;
304332 }
305333
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 ,
307335 tpm_crb_ffa -> minor_version );
308336
309337 if (tpm_crb_ffa -> major_version != CRB_FFA_VERSION_MAJOR ||
310338 (tpm_crb_ffa -> minor_version > 0 &&
311339 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 " );
313341 goto out ;
314342 }
315343
0 commit comments