1 /*
2  * Copyright 2024 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 <stdint.h>
10 
11 #include "hf/ffa.h"
12 
13 #include "vmapi/hf/call.h"
14 
15 #include "primary_with_secondary.h"
16 #include "test/hftest.h"
17 #include "test/vmapi/ffa.h"
18 
19 /**
20  * An FFA_MSG_SEND_DIRECT_REQ call is emitted at the Secure virtual
21  * FF-A instance from a v1.2 FF-A endpoint targeting a v1.1 endpoint.
22  *
23  * The service does not require results in registers beyond x7, hence per
24  * SMCCCv1.2 ensure GP registers beyond x7 are preserved by callee.
25  */
TEST_PRECONDITION(arch,smccc_direct_message_services_echo_sender_v1_2,service1_and_service2_are_secure)26 TEST_PRECONDITION(arch, smccc_direct_message_services_echo_sender_v1_2,
27 		  service1_and_service2_are_secure)
28 {
29 	struct mailbox_buffers mb = set_up_mailbox();
30 	struct ffa_partition_info *service1_info =
31 		service1(mb.recv); /* FF-A >= v1.2 sender */
32 	struct ffa_partition_info *service4_info =
33 		service4(mb.recv); /* FF-A <= v1.1 receiver */
34 	ffa_id_t own_id = hf_vm_get_id();
35 	struct ffa_value ret;
36 
37 	/* Run service4 for it to wait for a request from service1. */
38 	SERVICE_SELECT(service4_info->vm_id,
39 		       "smccc_ffa_msg_wait_and_response_callee_preserved",
40 		       mb.send);
41 	ffa_run(service4_info->vm_id, 0);
42 
43 	/* Service1 requests echo from service4. */
44 	SERVICE_SELECT(service1_info->vm_id,
45 		       "smccc_ffa_direct_request_callee_preserved", mb.send);
46 
47 	/* Send to service1 the FF-A id of the target for its message. */
48 	ret = send_indirect_message(own_id, service1_info->vm_id, mb.send,
49 				    &service4_info->vm_id,
50 				    sizeof(service4_info->vm_id), 0);
51 	ASSERT_EQ(ret.func, FFA_SUCCESS_32);
52 	ffa_run(service1_info->vm_id, 0);
53 }
54 
55 /**
56  * An FFA_MSG_SEND_DIRECT_REQ call is emitted at the Secure virtual
57  * FF-A instance from a v1.1 FF-A endpoint targeting a v1.2 endpoint.
58  *
59  * The service does not require results in registers beyond x7, hence per
60  * SMCCCv1.2 ensure GP registers beyond x7 are preserved by callee.
61  */
TEST_PRECONDITION(arch,smccc_direct_message_services_echo_sender_v1_1,service1_and_service2_are_secure)62 TEST_PRECONDITION(arch, smccc_direct_message_services_echo_sender_v1_1,
63 		  service1_and_service2_are_secure)
64 {
65 	struct mailbox_buffers mb = set_up_mailbox();
66 	struct ffa_partition_info *service1_info =
67 		service1(mb.recv); /* FF-A >= v1.2 receiver */
68 	struct ffa_partition_info *service4_info =
69 		service4(mb.recv); /* FF-A <= v1.1 sender */
70 	ffa_id_t own_id = hf_vm_get_id();
71 	struct ffa_value ret;
72 
73 	/* Run service1 for it to wait for a request from service4. */
74 	SERVICE_SELECT(service1_info->vm_id,
75 		       "smccc_ffa_msg_wait_and_response_callee_preserved",
76 		       mb.send);
77 	ffa_run(service1_info->vm_id, 0);
78 
79 	/* Service4 requests echo from service1. */
80 	SERVICE_SELECT(service4_info->vm_id,
81 		       "smccc_ffa_direct_request_callee_preserved", mb.send);
82 
83 	/* Send to service4 the FF-A id of the target for its message. */
84 	ret = send_indirect_message(own_id, service4_info->vm_id, mb.send,
85 				    &service1_info->vm_id,
86 				    sizeof(service1_info->vm_id), 0);
87 	ASSERT_EQ(ret.func, FFA_SUCCESS_32);
88 	ffa_run(service4_info->vm_id, 0);
89 }
90