summaryrefslogtreecommitdiff
path: root/ArmPkg/Library
diff options
context:
space:
mode:
authorOlivier Martin <olivier.martin@arm.com>2014-08-04 14:18:13 +0000
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>2014-08-04 14:18:13 +0000
commitb4e53e389d2a04678fb28bc445cd5b554bb175e0 (patch)
tree02f998bd9cc6b4be7b903943872c0c5a5cbeda6f /ArmPkg/Library
parent9a9dd4e8393177a48e5d8a773ce8aa42566045b9 (diff)
downloadedk2-platforms-b4e53e389d2a04678fb28bc445cd5b554bb175e0.tar.xz
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 <olivier.martin@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15748 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ArmPkg/Library')
-rw-r--r--ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S73
-rw-r--r--ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S79
-rw-r--r--ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.asm79
-rw-r--r--ArmPkg/Library/ArmSmcLibNull/AArch64/ArmSmcNull.S14
-rw-r--r--ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.S15
-rw-r--r--ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.asm15
6 files changed, 77 insertions, 198 deletions
diff --git a/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S b/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S
index 579a73e96c..f73c98cfc3 100644
--- a/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S
+++ b/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S
@@ -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
diff --git a/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S b/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S
index c9c0740feb..260fb10fe8 100644
--- a/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S
+++ b/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S
@@ -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
diff --git a/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.asm b/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.asm
index f46bd7ecd4..ad55ae7752 100644
--- a/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.asm
+++ b/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.asm
@@ -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
diff --git a/ArmPkg/Library/ArmSmcLibNull/AArch64/ArmSmcNull.S b/ArmPkg/Library/ArmSmcLibNull/AArch64/ArmSmcNull.S
index ec6e067ac3..a6ef0e04da 100644
--- a/ArmPkg/Library/ArmSmcLibNull/AArch64/ArmSmcNull.S
+++ b/ArmPkg/Library/ArmSmcLibNull/AArch64/ArmSmcNull.S
@@ -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
diff --git a/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.S b/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.S
index 4896dd0c9b..9eaefd30cf 100644
--- a/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.S
+++ b/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.S
@@ -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
diff --git a/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.asm b/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.asm
index 24c20752e3..3d3f554554 100644
--- a/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.asm
+++ b/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.asm
@@ -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