Revision: 15748
          http://sourceforge.net/p/edk2/code/15748
Author:   oliviermartin
Date:     2014-08-04 14:18:13 +0000 (Mon, 04 Aug 2014)
Log Message:
-----------
ArmPkg/ArmSmcLib: Fixed SMC helper functions

The SMC helper functions were buggy as they were assuming that
the values in x1-x7 registers were preserved across an SMC call,
which is not the case.  This patch fixes this issue.

It also simplifies the code by providing only 1 version of the SMC
helper function.  We used to have 4 versions depending on the number
of arguments.  The problem with this approach was that the number of
arguments also dictated the number of return values, which is
completely unrelated.  E.g. you can have an SMC call that takes
1 argument but returns 4 values.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <[email protected]>

Modified Paths:
--------------
    trunk/edk2/ArmPkg/Include/Library/ArmSmcLib.h
    trunk/edk2/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S
    trunk/edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S
    trunk/edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.asm
    trunk/edk2/ArmPkg/Library/ArmSmcLibNull/AArch64/ArmSmcNull.S
    trunk/edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.S
    trunk/edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.asm

Modified: trunk/edk2/ArmPkg/Include/Library/ArmSmcLib.h
===================================================================
--- trunk/edk2/ArmPkg/Include/Library/ArmSmcLib.h       2014-08-04 14:12:57 UTC 
(rev 15747)
+++ trunk/edk2/ArmPkg/Include/Library/ArmSmcLib.h       2014-08-04 14:18:13 UTC 
(rev 15748)
@@ -1,6 +1,6 @@
 /** @file
 *
-*  Copyright (c) 2012, ARM Limited. All rights reserved.
+*  Copyright (c) 2012-2014, ARM Limited. All rights reserved.
 *
 *  This program and the accompanying materials
 *  are licensed and made available under the terms and conditions of the BSD 
License
@@ -15,30 +15,32 @@
 #ifndef __ARM_SMC_LIB__
 #define __ARM_SMC_LIB__
 
-VOID
-ArmCallSmc (
-  IN OUT UINTN *Rx
-  );
+/**
+ * The size of the SMC arguments are different between AArch64 and AArch32.
+ * The native size is used for the arguments.
+ */
+typedef struct {
+  UINTN  Arg0;
+  UINTN  Arg1;
+  UINTN  Arg2;
+  UINTN  Arg3;
+  UINTN  Arg4;
+  UINTN  Arg5;
+  UINTN  Arg6;
+  UINTN  Arg7;
+} ARM_SMC_ARGS;
 
-VOID
-ArmCallSmcArg1 (
-  IN OUT UINTN *Rx,
-  IN OUT UINTN *Arg1
-  );
+/**
+  Trigger an SMC call
 
-VOID
-ArmCallSmcArg2 (
-  IN OUT UINTN *Rx,
-  IN OUT UINTN *Arg1,
-  IN OUT UINTN *Arg2
-  );
+  SMC calls can take up to 7 arguments and return up to 4 return values.
+  Therefore, the 4 first fields in the ARM_SMC_ARGS structure are used
+  for both input and output values.
 
+**/
 VOID
-ArmCallSmcArg3 (
-  IN OUT UINTN *Rx,
-  IN OUT UINTN *Arg1,
-  IN OUT UINTN *Arg2,
-  IN OUT UINTN *Arg3
+ArmCallSmc (
+  IN OUT ARM_SMC_ARGS *Args
   );
 
 #endif

Modified: trunk/edk2/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S
===================================================================
--- trunk/edk2/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S        2014-08-04 
14:12:57 UTC (rev 15747)
+++ trunk/edk2/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S        2014-08-04 
14:18:13 UTC (rev 15748)
@@ -1,5 +1,5 @@
 //
-//  Copyright (c) 2012-2013, ARM Limited. All rights reserved.
+//  Copyright (c) 2012-2014, ARM Limited. All rights reserved.
 //
 //  This program and the accompanying materials
 //  are licensed and made available under the terms and conditions of the BSD 
License
@@ -15,64 +15,27 @@
 .align 3
 
 GCC_ASM_EXPORT(ArmCallSmc)
-GCC_ASM_EXPORT(ArmCallSmcArg1)
-GCC_ASM_EXPORT(ArmCallSmcArg2)
-GCC_ASM_EXPORT(ArmCallSmcArg3)
 
 ASM_PFX(ArmCallSmc):
-  str   x1, [sp, #-0x10]!
-  mov   x1, x0
-  ldr   x0,[x1]
-  smc   #0
-  str   x0,[x1]
-  ldr   x1, [sp], #0x10
-  ret
+  // Push x0 on the stack
+  str   x0, [sp, #-8]!
 
-ASM_PFX(ArmCallSmcArg1):
-  stp   x2, x3, [sp, #-0x10]!
-  mov   x2, x0
-  mov   x3, x1
-  ldr   x0,[x2]
-  ldr   x1,[x3]
-  smc   #0
-  str   x0,[x2]
-  str   x1,[x3]
-  ldp   x2, x3, [sp], #0x10
-  ret
+  // Load the SMC arguments values into the appropriate registers
+  ldp   x6, x7, [x0, #48]
+  ldp   x4, x5, [x0, #32]
+  ldp   x2, x3, [x0, #16]
+  ldp   x0, x1, [x0, #0]
 
-ASM_PFX(ArmCallSmcArg2):
-  stp   x3, x4, [sp, #-0x10]!
-  str   x5, [sp, #-8]!
-  mov   x3, x0
-  mov   x4, x1
-  mov   x5, x2
-  ldr   x0,[x3]
-  ldr   x1,[x4]
-  ldr   x2,[x5]
   smc   #0
-  str   x0,[x3]
-  str   x1,[x4]
-  str   x2,[x5]
-  ldr   x5, [sp], #8
-  ldp   x3, x4, [sp], #0x10
-  ret
 
-ASM_PFX(ArmCallSmcArg3):
-  stp   x4, x5, [sp, #-0x10]!
-  stp   x6, x7, [sp, #-0x10]!
-  mov   x4, x0
-  mov   x5, x1
-  mov   x6, x2
-  mov   x7, x3
-  ldr   x0,[x4]
-  ldr   x1,[x5]
-  ldr   x2,[x6]
-  ldr   x3,[x7]
-  smc   #0
-  str   x0,[x4]
-  str   x1,[x5]
-  str   x2,[x6]
-  str   x3,[x7]
-  ldp   x4, x5, [sp], #0x10
-  ldp   x6, x7, [sp], #0x10
+  // Pop the ARM_SMC_ARGS structure address from the stack into x9
+  ldr   x9, [sp], #8
+
+  // Store the SMC returned values into the appropriate registers
+  // A SMC call can return up to 4 values - we do not need to store back x4-x7.
+  stp   x2, x3, [x9, #16]
+  stp   x0, x1, [x9, #0]
+
+  mov   x0, x9
+
   ret

Modified: trunk/edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S
===================================================================
--- trunk/edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S    2014-08-04 14:12:57 UTC 
(rev 15747)
+++ trunk/edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S    2014-08-04 14:18:13 UTC 
(rev 15748)
@@ -1,5 +1,5 @@
 //
-//  Copyright (c) 2012, ARM Limited. All rights reserved.
+//  Copyright (c) 2012-2014, ARM Limited. All rights reserved.
 //
 //  This program and the accompanying materials
 //  are licensed and made available under the terms and conditions of the BSD 
License
@@ -16,60 +16,37 @@
 .arch_extension sec
 
 GCC_ASM_EXPORT(ArmCallSmc)
-GCC_ASM_EXPORT(ArmCallSmcArg1)
-GCC_ASM_EXPORT(ArmCallSmcArg2)
-GCC_ASM_EXPORT(ArmCallSmcArg3)
 
 ASM_PFX(ArmCallSmc):
-    push    {r1}
-    mov     r1, r0
-    ldr     r0,[r1]
-    smc     #0
-    str     r0,[r1]
-    pop     {r1}
-    bx      lr
+    push    {r4-r8}
+    // r0 will be popped just after the SMC call
+    push    {r0}
 
-ASM_PFX(ArmCallSmcArg1):
-    push    {r2-r3}
-    mov     r2, r0
-    mov     r3, r1
-    ldr     r0,[r2]
-    ldr     r1,[r3]
-    smc     #0
-    str     r0,[r2]
-    str     r1,[r3]
-    pop     {r2-r3}
-    bx      lr
+    // Load the SMC arguments values into the appropriate registers
+    ldr     r7, [r0, #28]
+    ldr     r6, [r0, #24]
+    ldr     r5, [r0, #20]
+    ldr     r4, [r0, #16]
+    ldr     r3, [r0, #12]
+    ldr     r2, [r0, #8]
+    ldr     r1, [r0, #4]
+    ldr     r0, [r0, #0]
 
-ASM_PFX(ArmCallSmcArg2):
-    push    {r3-r5}
-    mov     r3, r0
-    mov     r4, r1
-    mov     r5, r2
-    ldr     r0,[r3]
-    ldr     r1,[r4]
-    ldr     r2,[r5]
     smc     #0
-    str     r0,[r3]
-    str     r1,[r4]
-    str     r2,[r5]
-    pop     {r3-r5}
-    bx      lr
 
-ASM_PFX(ArmCallSmcArg3):
-    push    {r4-r7}
-    mov     r4, r0
-    mov     r5, r1
-    mov     r6, r2
-    mov     r7, r3
-    ldr     r0,[r4]
-    ldr     r1,[r5]
-    ldr     r2,[r6]
-    ldr     r3,[r7]
-    smc     #0
-    str     r0,[r4]
-    str     r1,[r5]
-    str     r2,[r6]
-    str     r3,[r7]
-    pop     {r4-r7}
+    // Pop the ARM_SMC_ARGS structure address from the stack into r8
+    pop     {r8}
+
+    // Load the SMC returned values into the appropriate registers
+    // A SMC call can return up to 4 values - we do not need to store back 
r4-r7.
+    str     r3, [r8, #12]
+    str     r2, [r8, #8]
+    str     r1, [r8, #4]
+    str     r0, [r8, #0]
+
+    mov     r0, r8
+
+    // Restore the registers r4-r8
+    pop     {r4-r8}
+
     bx      lr

Modified: trunk/edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.asm
===================================================================
--- trunk/edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.asm  2014-08-04 14:12:57 UTC 
(rev 15747)
+++ trunk/edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.asm  2014-08-04 14:18:13 UTC 
(rev 15748)
@@ -1,5 +1,5 @@
 //
-//  Copyright (c) 2012, ARM Limited. All rights reserved.
+//  Copyright (c) 2012-2014, ARM Limited. All rights reserved.
 //
 //  This program and the accompanying materials
 //  are licensed and made available under the terms and conditions of the BSD 
License
@@ -12,64 +12,41 @@
 //
 
     EXPORT ArmCallSmc
-    EXPORT ArmCallSmcArg1
-    EXPORT ArmCallSmcArg2
-    EXPORT ArmCallSmcArg3
 
     AREA   ArmSmc, CODE, READONLY
 
 ArmCallSmc
-    push    {r1}
-    mov     r1, r0
-    ldr     r0,[r1]
-    smc     #0
-    str     r0,[r1]
-    pop     {r1}
-    bx      lr
+    push    {r4-r8}
+    // r0 will be popped just after the SMC call
+    pop     {r0}
 
-ArmCallSmcArg1
-    push    {r2-r3}
-    mov     r2, r0
-    mov     r3, r1
-    ldr     r0,[r2]
-    ldr     r1,[r3]
-    smc     #0
-    str     r0,[r2]
-    str     r1,[r3]
-    pop     {r2-r3}
-    bx      lr
+    // Load the SMC arguments values into the appropriate registers
+    ldr     r7, [r0, #28]
+    ldr     r6, [r0, #24]
+    ldr     r5, [r0, #20]
+    ldr     r4, [r0, #16]
+    ldr     r3, [r0, #12]
+    ldr     r2, [r0, #8]
+    ldr     r1, [r0, #4]
+    ldr     r0, [r0, #0]
 
-ArmCallSmcArg2
-    push    {r3-r5}
-    mov     r3, r0
-    mov     r4, r1
-    mov     r5, r2
-    ldr     r0,[r3]
-    ldr     r1,[r4]
-    ldr     r2,[r5]
     smc     #0
-    str     r0,[r3]
-    str     r1,[r4]
-    str     r2,[r5]
-    pop     {r3-r5}
-    bx      lr
 
-ArmCallSmcArg3
-    push    {r4-r7}
-    mov     r4, r0
-    mov     r5, r1
-    mov     r6, r2
-    mov     r7, r3
-    ldr     r0,[r4]
-    ldr     r1,[r5]
-    ldr     r2,[r6]
-    ldr     r3,[r7]
-    smc     #0
-    str     r0,[r4]
-    str     r1,[r5]
-    str     r2,[r6]
-    str     r3,[r7]
-    pop     {r4-r7}
+    // Pop the ARM_SMC_ARGS structure address from the stack into r8
+    pop     {r8}
+
+    // Load the SMC returned values into the appropriate registers
+    // A SMC call can return up to 4 values - we do not need to store back 
r4-r7.
+    str     r3, [r8, #12]
+    str     r2, [r8, #8]
+    str     r1, [r8, #4]
+    str     r0, [r8, #0]
+
+    mov     r0, r8
+
+    // Restore the registers r4-r8
+    pop     {r4-r8}
+
     bx      lr
 
     END

Modified: trunk/edk2/ArmPkg/Library/ArmSmcLibNull/AArch64/ArmSmcNull.S
===================================================================
--- trunk/edk2/ArmPkg/Library/ArmSmcLibNull/AArch64/ArmSmcNull.S        
2014-08-04 14:12:57 UTC (rev 15747)
+++ trunk/edk2/ArmPkg/Library/ArmSmcLibNull/AArch64/ArmSmcNull.S        
2014-08-04 14:18:13 UTC (rev 15748)
@@ -1,5 +1,5 @@
 //
-//  Copyright (c) 2012-2013, ARM Limited. All rights reserved.
+//  Copyright (c) 2012-2014, ARM Limited. All rights reserved.
 //
 //  This program and the accompanying materials
 //  are licensed and made available under the terms and conditions of the BSD 
License
@@ -15,18 +15,6 @@
 .align 3
 
 GCC_ASM_EXPORT(ArmCallSmc)
-GCC_ASM_EXPORT(ArmCallSmcArg1)
-GCC_ASM_EXPORT(ArmCallSmcArg2)
-GCC_ASM_EXPORT(ArmCallSmcArg3)
 
 ASM_PFX(ArmCallSmc):
   ret
-
-ASM_PFX(ArmCallSmcArg1):
-  ret
-
-ASM_PFX(ArmCallSmcArg2):
-  ret
-
-ASM_PFX(ArmCallSmcArg3):
-  ret

Modified: trunk/edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.S
===================================================================
--- trunk/edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.S    2014-08-04 
14:12:57 UTC (rev 15747)
+++ trunk/edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.S    2014-08-04 
14:18:13 UTC (rev 15748)
@@ -1,5 +1,5 @@
 //
-//  Copyright (c) 2012-2013, ARM Limited. All rights reserved.
+//  Copyright (c) 2012-2014, ARM Limited. All rights reserved.
 //
 //  This program and the accompanying materials
 //  are licensed and made available under the terms and conditions of the BSD 
License
@@ -15,19 +15,6 @@
 .align 3
 
 GCC_ASM_EXPORT(ArmCallSmc)
-GCC_ASM_EXPORT(ArmCallSmcArg1)
-GCC_ASM_EXPORT(ArmCallSmcArg2)
-GCC_ASM_EXPORT(ArmCallSmcArg3)
 
 ASM_PFX(ArmCallSmc):
   bx     lr
-
-// Arg1 in R1
-ASM_PFX(ArmCallSmcArg1):
-  bx     lr
-
-ASM_PFX(ArmCallSmcArg2):
-  bx     lr
-
-ASM_PFX(ArmCallSmcArg3):
-  bx     lr

Modified: trunk/edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.asm
===================================================================
--- trunk/edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.asm  2014-08-04 
14:12:57 UTC (rev 15747)
+++ trunk/edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.asm  2014-08-04 
14:18:13 UTC (rev 15748)
@@ -1,5 +1,5 @@
 //
-//  Copyright (c) 2012-2013, ARM Limited. All rights reserved.
+//  Copyright (c) 2012-2014, ARM Limited. All rights reserved.
 //
 //  This program and the accompanying materials
 //  are licensed and made available under the terms and conditions of the BSD 
License
@@ -12,23 +12,10 @@
 //
 
     EXPORT ArmCallSmc
-    EXPORT ArmCallSmcArg1
-    EXPORT ArmCallSmcArg2
-    EXPORT ArmCallSmcArg3
 
     AREA   ArmSmc, CODE, READONLY
 
 ArmCallSmc
   bx     lr
 
-// Arg1 in R1
-ArmCallSmcArg1
-  bx     lr
-
-ArmCallSmcArg2
-  bx     lr
-
-ArmCallSmcArg3
-  bx     lr
-
   END

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Infragistics Professional
Build stunning WinForms apps today!
Reboot your WinForms applications with our WinForms controls. 
Build a bridge from your legacy apps to the future.
http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to