1 /*
2  * Copyright 2021 The Hafnium Authors.
3  *
4  * Use of this source code is governed by a BSD-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/BSD-3-Clause.
7  */
8 
9 #include "hf/arch/plat/ffa.h"
10 
11 #include "hf/check.h"
12 #include "hf/ffa.h"
13 #include "hf/panic.h"
14 #include "hf/vm_ids.h"
15 
16 #include "smc.h"
17 
18 static ffa_vm_id_t spmc_id = HF_INVALID_VM_ID;
19 
20 /**
21  * Returns information for features with arch specific implementation.
22  */
arch_ffa_features(uint32_t function_feature_id)23 struct ffa_value arch_ffa_features(uint32_t function_feature_id)
24 {
25 	return plat_ffa_features(function_feature_id);
26 }
27 
28 /**
29  * Returns the SPMC ID returned from the SPMD.
30  */
arch_ffa_spmc_id_get(void)31 ffa_vm_id_t arch_ffa_spmc_id_get(void)
32 {
33 	return spmc_id;
34 }
35 
36 /**
37  * Initialize the platform FF-A module in the context of running the SPMC.
38  * In particular it fetches the SPMC ID to prevent SMC calls everytime
39  * FFA_SPM_ID_GET is invoked.
40  */
arch_ffa_init(void)41 void arch_ffa_init(void)
42 {
43 	struct ffa_value ret = plat_ffa_spmc_id_get();
44 
45 	if (ret.func == FFA_SUCCESS_32) {
46 		spmc_id = ret.arg2;
47 	} else if (ret.func == SMCCC_ERROR_UNKNOWN ||
48 		   (ret.func == FFA_ERROR_32 &&
49 		    ffa_error_code(ret) == FFA_NOT_SUPPORTED)) {
50 		spmc_id = HF_SPMC_VM_ID;
51 	} else {
52 		panic("Failed to get SPMC ID\n");
53 	}
54 
55 	/*
56 	 * Check that spmc_id is equal to HF_SPMC_VM_ID.
57 	 */
58 	CHECK(spmc_id == HF_SPMC_VM_ID);
59 }
60