19
19
#ifdef CONFIG_ARM64
20
20
#include <linux/arm-smccc.h>
21
21
#endif
22
+ #include "tpm_crb_ffa.h"
22
23
#include "tpm.h"
23
24
24
25
#define ACPI_SIG_TPM2 "TPM2"
@@ -100,6 +101,8 @@ struct crb_priv {
100
101
u32 smc_func_id ;
101
102
u32 __iomem * pluton_start_addr ;
102
103
u32 __iomem * pluton_reply_addr ;
104
+ u8 ffa_flags ;
105
+ u8 ffa_attributes ;
103
106
};
104
107
105
108
struct tpm2_crb_smc {
@@ -110,6 +113,14 @@ struct tpm2_crb_smc {
110
113
u32 smc_func_id ;
111
114
};
112
115
116
+ /* CRB over FFA start method parameters in TCG2 ACPI table */
117
+ struct tpm2_crb_ffa {
118
+ u8 flags ;
119
+ u8 attributes ;
120
+ u16 partition_id ;
121
+ u8 reserved [8 ];
122
+ };
123
+
113
124
struct tpm2_crb_pluton {
114
125
u64 start_addr ;
115
126
u64 reply_addr ;
@@ -122,7 +133,8 @@ static inline bool tpm_crb_has_idle(u32 start_method)
122
133
{
123
134
return !(start_method == ACPI_TPM2_START_METHOD ||
124
135
start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD ||
125
- start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC );
136
+ start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC ||
137
+ start_method == ACPI_TPM2_CRB_WITH_ARM_FFA );
126
138
}
127
139
128
140
static bool crb_wait_for_reg_32 (u32 __iomem * reg , u32 mask , u32 value ,
@@ -261,13 +273,20 @@ static int crb_cmd_ready(struct tpm_chip *chip)
261
273
static int __crb_request_locality (struct device * dev ,
262
274
struct crb_priv * priv , int loc )
263
275
{
264
- u32 value = CRB_LOC_STATE_LOC_ASSIGNED |
265
- CRB_LOC_STATE_TPM_REG_VALID_STS ;
276
+ u32 value = CRB_LOC_STATE_LOC_ASSIGNED | CRB_LOC_STATE_TPM_REG_VALID_STS ;
277
+ int rc ;
266
278
267
279
if (!priv -> regs_h )
268
280
return 0 ;
269
281
270
282
iowrite32 (CRB_LOC_CTRL_REQUEST_ACCESS , & priv -> regs_h -> loc_ctrl );
283
+
284
+ if (priv -> sm == ACPI_TPM2_CRB_WITH_ARM_FFA ) {
285
+ rc = tpm_crb_ffa_start (CRB_FFA_START_TYPE_LOCALITY_REQUEST , loc );
286
+ if (rc )
287
+ return rc ;
288
+ }
289
+
271
290
if (!crb_wait_for_reg_32 (& priv -> regs_h -> loc_state , value , value ,
272
291
TPM2_TIMEOUT_C )) {
273
292
dev_warn (dev , "TPM_LOC_STATE_x.requestAccess timed out\n" );
@@ -287,14 +306,21 @@ static int crb_request_locality(struct tpm_chip *chip, int loc)
287
306
static int __crb_relinquish_locality (struct device * dev ,
288
307
struct crb_priv * priv , int loc )
289
308
{
290
- u32 mask = CRB_LOC_STATE_LOC_ASSIGNED |
291
- CRB_LOC_STATE_TPM_REG_VALID_STS ;
309
+ u32 mask = CRB_LOC_STATE_LOC_ASSIGNED | CRB_LOC_STATE_TPM_REG_VALID_STS ;
292
310
u32 value = CRB_LOC_STATE_TPM_REG_VALID_STS ;
311
+ int rc ;
293
312
294
313
if (!priv -> regs_h )
295
314
return 0 ;
296
315
297
316
iowrite32 (CRB_LOC_CTRL_RELINQUISH , & priv -> regs_h -> loc_ctrl );
317
+
318
+ if (priv -> sm == ACPI_TPM2_CRB_WITH_ARM_FFA ) {
319
+ rc = tpm_crb_ffa_start (CRB_FFA_START_TYPE_LOCALITY_REQUEST , loc );
320
+ if (rc )
321
+ return rc ;
322
+ }
323
+
298
324
if (!crb_wait_for_reg_32 (& priv -> regs_h -> loc_state , mask , value ,
299
325
TPM2_TIMEOUT_C )) {
300
326
dev_warn (dev , "TPM_LOC_STATE_x.Relinquish timed out\n" );
@@ -443,6 +469,11 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len)
443
469
rc = tpm_crb_smc_start (& chip -> dev , priv -> smc_func_id );
444
470
}
445
471
472
+ if (priv -> sm == ACPI_TPM2_CRB_WITH_ARM_FFA ) {
473
+ iowrite32 (CRB_START_INVOKE , & priv -> regs_t -> ctrl_start );
474
+ rc = tpm_crb_ffa_start (CRB_FFA_START_TYPE_COMMAND , chip -> locality );
475
+ }
476
+
446
477
if (rc )
447
478
return rc ;
448
479
@@ -452,13 +483,20 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len)
452
483
static void crb_cancel (struct tpm_chip * chip )
453
484
{
454
485
struct crb_priv * priv = dev_get_drvdata (& chip -> dev );
486
+ int rc ;
455
487
456
488
iowrite32 (CRB_CANCEL_INVOKE , & priv -> regs_t -> ctrl_cancel );
457
489
458
490
if ((priv -> sm == ACPI_TPM2_START_METHOD ||
459
491
priv -> sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD ) &&
460
492
crb_do_acpi_start (chip ))
461
493
dev_err (& chip -> dev , "ACPI Start failed\n" );
494
+
495
+ if (priv -> sm == ACPI_TPM2_CRB_WITH_ARM_FFA ) {
496
+ rc = tpm_crb_ffa_start (CRB_FFA_START_TYPE_COMMAND , chip -> locality );
497
+ if (rc )
498
+ dev_err (& chip -> dev , "FF-A Start failed\n" );
499
+ }
462
500
}
463
501
464
502
static bool crb_req_canceled (struct tpm_chip * chip , u8 status )
@@ -616,6 +654,7 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
616
654
* stuff that puts the control area outside the ACPI IO region.
617
655
*/
618
656
if (priv -> sm == ACPI_TPM2_COMMAND_BUFFER ||
657
+ priv -> sm == ACPI_TPM2_CRB_WITH_ARM_FFA ||
619
658
priv -> sm == ACPI_TPM2_MEMORY_MAPPED ) {
620
659
if (iores &&
621
660
buf -> control_address == iores -> start +
@@ -737,6 +776,7 @@ static int crb_acpi_add(struct acpi_device *device)
737
776
struct tpm_chip * chip ;
738
777
struct device * dev = & device -> dev ;
739
778
struct tpm2_crb_smc * crb_smc ;
779
+ struct tpm2_crb_ffa * crb_ffa ;
740
780
struct tpm2_crb_pluton * crb_pluton ;
741
781
acpi_status status ;
742
782
u32 sm ;
@@ -775,6 +815,27 @@ static int crb_acpi_add(struct acpi_device *device)
775
815
priv -> smc_func_id = crb_smc -> smc_func_id ;
776
816
}
777
817
818
+ if (sm == ACPI_TPM2_CRB_WITH_ARM_FFA ) {
819
+ if (buf -> header .length < (sizeof (* buf ) + sizeof (* crb_ffa ))) {
820
+ dev_err (dev ,
821
+ FW_BUG "TPM2 ACPI table has wrong size %u for start method type %d\n" ,
822
+ buf -> header .length ,
823
+ ACPI_TPM2_CRB_WITH_ARM_FFA );
824
+ rc = - EINVAL ;
825
+ goto out ;
826
+ }
827
+ crb_ffa = ACPI_ADD_PTR (struct tpm2_crb_ffa , buf , sizeof (* buf ));
828
+ priv -> ffa_flags = crb_ffa -> flags ;
829
+ priv -> ffa_attributes = crb_ffa -> attributes ;
830
+ rc = tpm_crb_ffa_init ();
831
+ if (rc ) {
832
+ /* If FF-A driver is not available yet, request probe retry */
833
+ if (rc == - ENOENT )
834
+ rc = - EPROBE_DEFER ;
835
+ goto out ;
836
+ }
837
+ }
838
+
778
839
if (sm == ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON ) {
779
840
if (buf -> header .length < (sizeof (* buf ) + sizeof (* crb_pluton ))) {
780
841
dev_err (dev ,
0 commit comments