[FOSS_TLK]arm: monitor: pass SMC arguments using CPU regs (r0-r7)
Varun Wadekar [Wed, 1 Apr 2015 12:37:41 +0000 (17:37 +0530)]
This patch removes the need for a shared buffer between the EL3 and S-EL1
to pass SMC args/results. We use r0-r7 registers to pass data between the
64-bit EL3 binary and the 32-bit S-EL1 binary.

Change-Id: I54c45f33259a88f5285efdabea97b79720e47267
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Reviewed-on: http://git-master/r/752883
Reviewed-by: Automatic_Commit_Validation_User

arch/arm/arm/monitor_interface.S

index dbdfe2e..7e8c22d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved
+ * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files
 #include <asm.h>
 #include <lib/monitor/monitor_vector.h>
 
-/* registers in a struct tz_monitor_frame: (r0-r12, pc, spsr) */
-#define TZ_MONITOR_FRAME_REG_COUNT     (13 + 2)
-
-.macro copy_frame, dst, src, tmp_low, tmp_high
-       .rept   TZ_MONITOR_FRAME_REG_COUNT
-       ldmia   \src!, {\tmp_low, \tmp_high}
-       stmia   \dst!, {\tmp_low, \tmp_high}
-       .endr
-.endm
-
-/* corrupts r0-r3 */
-.macro send_shared_smc_addr
-       adr     r2, mon_smc_args_res
-       ldr     r3, =__load_phys_offset
-       ldr     r3, [r3]
-
-       ldr     r0, =SMC_TOS_INIT_SHARED_ADDR
-       sub     r1, r2, r3      /* r1: phys mon_smc_args_res */
-       smc     #0
-
-       /* update flag */
-       mov     r2, #1
-       str     r2, sent_shared_smc_addr
-.endm
-
 /* takes smc_type and frame ptr */
 FUNCTION(monitor_send_receive)
-       push    {r4-r5}
-
-       /* save smc_type and frame ptr */
-       mov     r4, r0
-       mov     r5, r1
-
-       /* if needed, send shared mon_smc_args */
-       ldr     r2, sent_shared_smc_addr
-       cmp     r2, #0
-       bne     1f
-
-       /* send phys address of buffer (corrupts r0-r3) */
-       send_shared_smc_addr
-
-       mov     r0, r4
-       mov     r1, r5
-
-1:
-       /* copy from frame to mon_smc_args_res */
-       adr     r0, mon_smc_args_res
-       copy_frame r0, r1, r2, r3
-       mov     r0, r4
-
+       push    { r1, r4-r7, r12 }
+       ldmia   r1, { r1-r6 }
        smc     #0
-
-       /* copy from mon_smc_args_res to frame */
-       adr     r0, mon_smc_args_res
-       mov     r1, r5
-       copy_frame r1, r0, r2, r3
-       mov     r0, r4
-
-       /*
-        * On return from SMC_TOS_COMPLETION or SMC_TOS_INITIAL_NS_RETURN,
-        * a new SMC is incoming. For compatibility, set the return value
-        * to the frame.
-        *
-        * For all other types (e.g. CALLBACK), the return value comes from
-        * the monitor filled in frame.
-        */
-       ldr     r3, =SMC_TOS_COMPLETION
-       cmp     r0, r3
-       ldrne   r3, =SMC_TOS_INITIAL_NS_RETURN
-       cmpne   r0, r3
-
-       moveq   r0, r5                  /* return frame ptr in r0 */
-       adrne   r1, mon_smc_args_res
-       ldrne   r0, [r1]                /* otherwise, r0 from the frame */
-
-       pop     {r4-r5}
+       pop     { r12 }                 /* frame ptr */
+       stmia   r12, { r0-r7 }
+       mov     r0, r12                 /* return frame ptr in r0 */
+       pop     { r4-r7, r12 }
        mov     pc, lr                  /* return */
-
-.align 3
-mon_smc_args_res:
-       .rept   TZ_MONITOR_FRAME_REG_COUNT
-       .quad   0
-       .endr
-
-sent_shared_smc_addr:
-       .int 0