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