1 /*
2  * Copyright 2023 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/ffa.h"
10 
11 #include "test/hftest.h"
12 
test_ffa_smc(uint32_t func,uint64_t arg0,uint64_t arg1,uint64_t arg2,uint64_t arg3,uint64_t arg4,uint64_t arg5,uint64_t arg6)13 static struct ffa_value test_ffa_smc(uint32_t func, uint64_t arg0,
14 				     uint64_t arg1, uint64_t arg2,
15 				     uint64_t arg3, uint64_t arg4,
16 				     uint64_t arg5, uint64_t arg6)
17 {
18 	register uint64_t r0 __asm__("x0") = func;
19 	register uint64_t r1 __asm__("x1") = arg0;
20 	register uint64_t r2 __asm__("x2") = arg1;
21 	register uint64_t r3 __asm__("x3") = arg2;
22 	register uint64_t r4 __asm__("x4") = arg3;
23 	register uint64_t r5 __asm__("x5") = arg4;
24 	register uint64_t r6 __asm__("x6") = arg5;
25 	register uint64_t r7 __asm__("x7") = arg6;
26 	register uint64_t r8 __asm__("x8") = 0xa8;
27 	register uint64_t r9 __asm__("x9") = 0xa9;
28 	register uint64_t r10 __asm__("x10") = 0xa10;
29 	register uint64_t r11 __asm__("x11") = 0xa11;
30 	register uint64_t r12 __asm__("x12") = 0xa12;
31 	register uint64_t r13 __asm__("x13") = 0xa13;
32 	register uint64_t r14 __asm__("x14") = 0xa14;
33 	register uint64_t r15 __asm__("x15") = 0xa15;
34 	register uint64_t r16 __asm__("x16") = 0xa16;
35 	register uint64_t r17 __asm__("x17") = 0xa17;
36 	register uint64_t r18 __asm__("x18") = 0xa18;
37 	register uint64_t r19 __asm__("x19") = 0xa19;
38 	register uint64_t r20 __asm__("x20") = 0xa20;
39 	register uint64_t r21 __asm__("x21") = 0xa21;
40 	register uint64_t r22 __asm__("x22") = 0xa22;
41 	register uint64_t r23 __asm__("x23") = 0xa23;
42 	register uint64_t r24 __asm__("x24") = 0xa24;
43 	register uint64_t r25 __asm__("x25") = 0xa25;
44 	register uint64_t r26 __asm__("x26") = 0xa26;
45 	register uint64_t r27 __asm__("x27") = 0xa27;
46 	register uint64_t r28 __asm__("x28") = 0xa28;
47 
48 	__asm__ volatile(
49 		"smc #0"
50 		: /* Output registers, also used as inputs ('+' constraint). */
51 		"+r"(r0), "+r"(r1), "+r"(r2), "+r"(r3), "+r"(r4), "+r"(r5),
52 		"+r"(r6), "+r"(r7), "+r"(r8), "+r"(r9), "+r"(r10), "+r"(r11),
53 		"+r"(r12), "+r"(r13), "+r"(r14), "+r"(r15), "+r"(r16),
54 		"+r"(r17), "+r"(r18), "+r"(r19), "+r"(r20), "+r"(r21),
55 		"+r"(r22), "+r"(r23), "+r"(r24), "+r"(r25), "+r"(r26),
56 		"+r"(r27), "+r"(r28));
57 
58 	EXPECT_EQ(r8, 0xa8);
59 	EXPECT_EQ(r9, 0xa9);
60 	EXPECT_EQ(r10, 0xa10);
61 	EXPECT_EQ(r11, 0xa11);
62 	EXPECT_EQ(r12, 0xa12);
63 	EXPECT_EQ(r13, 0xa13);
64 	EXPECT_EQ(r14, 0xa14);
65 	EXPECT_EQ(r15, 0xa15);
66 	EXPECT_EQ(r16, 0xa16);
67 	EXPECT_EQ(r17, 0xa17);
68 	EXPECT_EQ(r18, 0xa18);
69 	EXPECT_EQ(r19, 0xa19);
70 	EXPECT_EQ(r20, 0xa20);
71 	EXPECT_EQ(r21, 0xa21);
72 	EXPECT_EQ(r22, 0xa22);
73 	EXPECT_EQ(r23, 0xa23);
74 	EXPECT_EQ(r24, 0xa24);
75 	EXPECT_EQ(r25, 0xa25);
76 	EXPECT_EQ(r26, 0xa26);
77 	EXPECT_EQ(r27, 0xa27);
78 	EXPECT_EQ(r28, 0xa28);
79 
80 	return (struct ffa_value){.func = r0,
81 				  .arg1 = r1,
82 				  .arg2 = r2,
83 				  .arg3 = r3,
84 				  .arg4 = r4,
85 				  .arg5 = r5,
86 				  .arg6 = r6,
87 				  .arg7 = r7};
88 }
89 
90 /**
91  * An FF-A service call is emitted at the NS virtual FF-A instance.
92  * The service does not require results in registers beyond x7, hence per
93  * SMCCCv1.2 ensure GP registers beyond x7 are preserved by callee.
94  */
TEST(arch,smccc_nwd_regs_callee_preserved)95 TEST(arch, smccc_nwd_regs_callee_preserved)
96 {
97 	struct ffa_value ret;
98 
99 	ret = test_ffa_smc(FFA_VERSION_32, 0x10001, 0, 0, 0, 0, 0, 0);
100 	EXPECT_GE(ret.func, 0x10001);
101 	EXPECT_EQ(ret.arg1, 0x0);
102 	EXPECT_EQ(ret.arg2, 0x0);
103 	EXPECT_EQ(ret.arg3, 0x0);
104 	EXPECT_EQ(ret.arg4, 0x0);
105 	EXPECT_EQ(ret.arg5, 0x0);
106 	EXPECT_EQ(ret.arg6, 0x0);
107 	EXPECT_EQ(ret.arg7, 0x0);
108 
109 	ret = test_ffa_smc(FFA_ID_GET_32, 0, 0, 0, 0, 0, 0, 0);
110 	EXPECT_EQ(ret.func, FFA_SUCCESS_32);
111 	EXPECT_EQ(ret.arg1, 0x0);
112 	EXPECT_EQ(ret.arg2, 0x1);
113 	EXPECT_EQ(ret.arg3, 0x0);
114 	EXPECT_EQ(ret.arg4, 0x0);
115 	EXPECT_EQ(ret.arg5, 0x0);
116 	EXPECT_EQ(ret.arg6, 0x0);
117 	EXPECT_EQ(ret.arg7, 0x0);
118 }
119