lib: smc: Add smc18/hvc18

These routines transmit and receive registers x8-x17 as
required by some FF-A ABIs.

Bug: 343280291
Test: Use SMC_FC64_FFA_CONSOLE_LOG with these registers

Change-Id: Id62f84edaa5094e171f0eba902dee3558178e50a
diff --git a/lib/smc/arch/arm64/smc.S b/lib/smc/arch/arm64/smc.S
index 76c0cc7..7749e67 100644
--- a/lib/smc/arch/arm64/smc.S
+++ b/lib/smc/arch/arm64/smc.S
@@ -48,3 +48,36 @@
 
 FUNCTION(hvc8)
     smc8_hvc8 hvc
+
+.macro smc18_hvc18, instr
+    push x19, lr
+    mov  x19, x8
+
+    ldp x8,  x9,  [sp, #16]
+    ldp x10, x11, [sp, #32]
+    ldp x12, x13, [sp, #48]
+    ldp x14, x15, [sp, #64]
+    ldp x16, x17, [sp, #80]
+
+    \instr  #0
+
+    stp     x0,  x1,  [x19], #16
+    stp     x2,  x3,  [x19], #16
+    stp     x4,  x5,  [x19], #16
+    stp     x6,  x7,  [x19], #16
+    stp     x8,  x9,  [x19], #16
+    stp     x10, x11, [x19], #16
+    stp     x12, x13, [x19], #16
+    stp     x14, x15, [x19], #16
+    stp     x16, x17, [x19], #16
+
+    pop     x19, lr
+
+    ret
+.endm
+
+FUNCTION(smc18)
+    smc18_hvc18 smc
+
+FUNCTION(hvc18)
+    smc18_hvc18 hvc
diff --git a/lib/smc/include/lib/smc/smc.h b/lib/smc/include/lib/smc/smc.h
index 44999e6..d73f8f2 100644
--- a/lib/smc/include/lib/smc/smc.h
+++ b/lib/smc/include/lib/smc/smc.h
@@ -23,6 +23,7 @@
 
 #pragma once
 
+#include <shared/lk/compiler.h>
 #include <sys/types.h>
 
 /* Unknown SMC (defined by ARM DEN 0028A(0.9.0) */
@@ -39,6 +40,36 @@
     ulong r7;
 };
 
+#define REQ2_OTHER_PARAM_REGS 14
+
+struct smc_ret18 {
+    ulong r0;
+    ulong r1;
+    ulong r2;
+    ulong r3;
+    union {
+        struct {
+            ulong r4;
+            ulong r5;
+            ulong r6;
+            ulong r7;
+            ulong r8;
+            ulong r9;
+            ulong r10;
+            ulong r11;
+            ulong r12;
+            ulong r13;
+            ulong r14;
+            ulong r15;
+            ulong r16;
+            ulong r17;
+        };
+        ulong req2_params[REQ2_OTHER_PARAM_REGS];
+    };
+};
+
+STATIC_ASSERT(sizeof(struct smc_ret18) == sizeof(ulong) * 18);
+
 struct smc_ret8 smc8(ulong r0,
                      ulong r1,
                      ulong r2,
@@ -56,3 +87,41 @@
                      ulong r5,
                      ulong r6,
                      ulong r7);
+
+struct smc_ret18 smc18(ulong r0,
+                       ulong r1,
+                       ulong r2,
+                       ulong r3,
+                       ulong r4,
+                       ulong r5,
+                       ulong r6,
+                       ulong r7,
+                       ulong r8,
+                       ulong r9,
+                       ulong r10,
+                       ulong r11,
+                       ulong r12,
+                       ulong r13,
+                       ulong r14,
+                       ulong r15,
+                       ulong r16,
+                       ulong r17);
+
+struct smc_ret18 hvc18(ulong r0,
+                       ulong r1,
+                       ulong r2,
+                       ulong r3,
+                       ulong r4,
+                       ulong r5,
+                       ulong r6,
+                       ulong r7,
+                       ulong r8,
+                       ulong r9,
+                       ulong r10,
+                       ulong r11,
+                       ulong r12,
+                       ulong r13,
+                       ulong r14,
+                       ulong r15,
+                       ulong r16,
+                       ulong r17);