mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-21 04:34:27 +02:00
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
This commit is contained in:
parent
9a9dd4e839
commit
b4e53e389d
@ -1,6 +1,6 @@
|
|||||||
/** @file
|
/** @file
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012, ARM Limited. All rights reserved.
|
* Copyright (c) 2012-2014, ARM Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials
|
* This program and the accompanying materials
|
||||||
* are licensed and made available under the terms and conditions of the BSD License
|
* are licensed and made available under the terms and conditions of the BSD License
|
||||||
@ -15,30 +15,32 @@
|
|||||||
#ifndef __ARM_SMC_LIB__
|
#ifndef __ARM_SMC_LIB__
|
||||||
#define __ARM_SMC_LIB__
|
#define __ARM_SMC_LIB__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Trigger an SMC call
|
||||||
|
|
||||||
|
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
|
VOID
|
||||||
ArmCallSmc (
|
ArmCallSmc (
|
||||||
IN OUT UINTN *Rx
|
IN OUT ARM_SMC_ARGS *Args
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
ArmCallSmcArg1 (
|
|
||||||
IN OUT UINTN *Rx,
|
|
||||||
IN OUT UINTN *Arg1
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
ArmCallSmcArg2 (
|
|
||||||
IN OUT UINTN *Rx,
|
|
||||||
IN OUT UINTN *Arg1,
|
|
||||||
IN OUT UINTN *Arg2
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
ArmCallSmcArg3 (
|
|
||||||
IN OUT UINTN *Rx,
|
|
||||||
IN OUT UINTN *Arg1,
|
|
||||||
IN OUT UINTN *Arg2,
|
|
||||||
IN OUT UINTN *Arg3
|
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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
|
// This program and the accompanying materials
|
||||||
// are licensed and made available under the terms and conditions of the BSD License
|
// are licensed and made available under the terms and conditions of the BSD License
|
||||||
@ -15,64 +15,27 @@
|
|||||||
.align 3
|
.align 3
|
||||||
|
|
||||||
GCC_ASM_EXPORT(ArmCallSmc)
|
GCC_ASM_EXPORT(ArmCallSmc)
|
||||||
GCC_ASM_EXPORT(ArmCallSmcArg1)
|
|
||||||
GCC_ASM_EXPORT(ArmCallSmcArg2)
|
|
||||||
GCC_ASM_EXPORT(ArmCallSmcArg3)
|
|
||||||
|
|
||||||
ASM_PFX(ArmCallSmc):
|
ASM_PFX(ArmCallSmc):
|
||||||
str x1, [sp, #-0x10]!
|
// Push x0 on the stack
|
||||||
mov x1, x0
|
str x0, [sp, #-8]!
|
||||||
ldr x0,[x1]
|
|
||||||
smc #0
|
|
||||||
str x0,[x1]
|
|
||||||
ldr x1, [sp], #0x10
|
|
||||||
ret
|
|
||||||
|
|
||||||
ASM_PFX(ArmCallSmcArg1):
|
// Load the SMC arguments values into the appropriate registers
|
||||||
stp x2, x3, [sp, #-0x10]!
|
ldp x6, x7, [x0, #48]
|
||||||
mov x2, x0
|
ldp x4, x5, [x0, #32]
|
||||||
mov x3, x1
|
ldp x2, x3, [x0, #16]
|
||||||
ldr x0,[x2]
|
ldp x0, x1, [x0, #0]
|
||||||
ldr x1,[x3]
|
|
||||||
smc #0
|
|
||||||
str x0,[x2]
|
|
||||||
str x1,[x3]
|
|
||||||
ldp x2, x3, [sp], #0x10
|
|
||||||
ret
|
|
||||||
|
|
||||||
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
|
smc #0
|
||||||
str x0,[x3]
|
|
||||||
str x1,[x4]
|
|
||||||
str x2,[x5]
|
|
||||||
ldr x5, [sp], #8
|
|
||||||
ldp x3, x4, [sp], #0x10
|
|
||||||
ret
|
|
||||||
|
|
||||||
ASM_PFX(ArmCallSmcArg3):
|
// Pop the ARM_SMC_ARGS structure address from the stack into x9
|
||||||
stp x4, x5, [sp, #-0x10]!
|
ldr x9, [sp], #8
|
||||||
stp x6, x7, [sp, #-0x10]!
|
|
||||||
mov x4, x0
|
// Store the SMC returned values into the appropriate registers
|
||||||
mov x5, x1
|
// A SMC call can return up to 4 values - we do not need to store back x4-x7.
|
||||||
mov x6, x2
|
stp x2, x3, [x9, #16]
|
||||||
mov x7, x3
|
stp x0, x1, [x9, #0]
|
||||||
ldr x0,[x4]
|
|
||||||
ldr x1,[x5]
|
mov x0, x9
|
||||||
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
|
|
||||||
ret
|
ret
|
||||||
|
@ -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
|
// This program and the accompanying materials
|
||||||
// are licensed and made available under the terms and conditions of the BSD License
|
// are licensed and made available under the terms and conditions of the BSD License
|
||||||
@ -16,60 +16,37 @@
|
|||||||
.arch_extension sec
|
.arch_extension sec
|
||||||
|
|
||||||
GCC_ASM_EXPORT(ArmCallSmc)
|
GCC_ASM_EXPORT(ArmCallSmc)
|
||||||
GCC_ASM_EXPORT(ArmCallSmcArg1)
|
|
||||||
GCC_ASM_EXPORT(ArmCallSmcArg2)
|
|
||||||
GCC_ASM_EXPORT(ArmCallSmcArg3)
|
|
||||||
|
|
||||||
ASM_PFX(ArmCallSmc):
|
ASM_PFX(ArmCallSmc):
|
||||||
push {r1}
|
push {r4-r8}
|
||||||
mov r1, r0
|
// r0 will be popped just after the SMC call
|
||||||
ldr r0,[r1]
|
push {r0}
|
||||||
smc #0
|
|
||||||
str r0,[r1]
|
|
||||||
pop {r1}
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
ASM_PFX(ArmCallSmcArg1):
|
// Load the SMC arguments values into the appropriate registers
|
||||||
push {r2-r3}
|
ldr r7, [r0, #28]
|
||||||
mov r2, r0
|
ldr r6, [r0, #24]
|
||||||
mov r3, r1
|
ldr r5, [r0, #20]
|
||||||
ldr r0,[r2]
|
ldr r4, [r0, #16]
|
||||||
ldr r1,[r3]
|
ldr r3, [r0, #12]
|
||||||
smc #0
|
ldr r2, [r0, #8]
|
||||||
str r0,[r2]
|
ldr r1, [r0, #4]
|
||||||
str r1,[r3]
|
ldr r0, [r0, #0]
|
||||||
pop {r2-r3}
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
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
|
smc #0
|
||||||
str r0,[r3]
|
|
||||||
str r1,[r4]
|
|
||||||
str r2,[r5]
|
|
||||||
pop {r3-r5}
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
ASM_PFX(ArmCallSmcArg3):
|
// Pop the ARM_SMC_ARGS structure address from the stack into r8
|
||||||
push {r4-r7}
|
pop {r8}
|
||||||
mov r4, r0
|
|
||||||
mov r5, r1
|
// Load the SMC returned values into the appropriate registers
|
||||||
mov r6, r2
|
// A SMC call can return up to 4 values - we do not need to store back r4-r7.
|
||||||
mov r7, r3
|
str r3, [r8, #12]
|
||||||
ldr r0,[r4]
|
str r2, [r8, #8]
|
||||||
ldr r1,[r5]
|
str r1, [r8, #4]
|
||||||
ldr r2,[r6]
|
str r0, [r8, #0]
|
||||||
ldr r3,[r7]
|
|
||||||
smc #0
|
mov r0, r8
|
||||||
str r0,[r4]
|
|
||||||
str r1,[r5]
|
// Restore the registers r4-r8
|
||||||
str r2,[r6]
|
pop {r4-r8}
|
||||||
str r3,[r7]
|
|
||||||
pop {r4-r7}
|
|
||||||
bx lr
|
bx lr
|
||||||
|
@ -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
|
// This program and the accompanying materials
|
||||||
// are licensed and made available under the terms and conditions of the BSD License
|
// are licensed and made available under the terms and conditions of the BSD License
|
||||||
@ -12,64 +12,41 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
EXPORT ArmCallSmc
|
EXPORT ArmCallSmc
|
||||||
EXPORT ArmCallSmcArg1
|
|
||||||
EXPORT ArmCallSmcArg2
|
|
||||||
EXPORT ArmCallSmcArg3
|
|
||||||
|
|
||||||
AREA ArmSmc, CODE, READONLY
|
AREA ArmSmc, CODE, READONLY
|
||||||
|
|
||||||
ArmCallSmc
|
ArmCallSmc
|
||||||
push {r1}
|
push {r4-r8}
|
||||||
mov r1, r0
|
// r0 will be popped just after the SMC call
|
||||||
ldr r0,[r1]
|
pop {r0}
|
||||||
smc #0
|
|
||||||
str r0,[r1]
|
|
||||||
pop {r1}
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
ArmCallSmcArg1
|
// Load the SMC arguments values into the appropriate registers
|
||||||
push {r2-r3}
|
ldr r7, [r0, #28]
|
||||||
mov r2, r0
|
ldr r6, [r0, #24]
|
||||||
mov r3, r1
|
ldr r5, [r0, #20]
|
||||||
ldr r0,[r2]
|
ldr r4, [r0, #16]
|
||||||
ldr r1,[r3]
|
ldr r3, [r0, #12]
|
||||||
smc #0
|
ldr r2, [r0, #8]
|
||||||
str r0,[r2]
|
ldr r1, [r0, #4]
|
||||||
str r1,[r3]
|
ldr r0, [r0, #0]
|
||||||
pop {r2-r3}
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
ArmCallSmcArg2
|
|
||||||
push {r3-r5}
|
|
||||||
mov r3, r0
|
|
||||||
mov r4, r1
|
|
||||||
mov r5, r2
|
|
||||||
ldr r0,[r3]
|
|
||||||
ldr r1,[r4]
|
|
||||||
ldr r2,[r5]
|
|
||||||
smc #0
|
smc #0
|
||||||
str r0,[r3]
|
|
||||||
str r1,[r4]
|
|
||||||
str r2,[r5]
|
|
||||||
pop {r3-r5}
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
ArmCallSmcArg3
|
// Pop the ARM_SMC_ARGS structure address from the stack into r8
|
||||||
push {r4-r7}
|
pop {r8}
|
||||||
mov r4, r0
|
|
||||||
mov r5, r1
|
// Load the SMC returned values into the appropriate registers
|
||||||
mov r6, r2
|
// A SMC call can return up to 4 values - we do not need to store back r4-r7.
|
||||||
mov r7, r3
|
str r3, [r8, #12]
|
||||||
ldr r0,[r4]
|
str r2, [r8, #8]
|
||||||
ldr r1,[r5]
|
str r1, [r8, #4]
|
||||||
ldr r2,[r6]
|
str r0, [r8, #0]
|
||||||
ldr r3,[r7]
|
|
||||||
smc #0
|
mov r0, r8
|
||||||
str r0,[r4]
|
|
||||||
str r1,[r5]
|
// Restore the registers r4-r8
|
||||||
str r2,[r6]
|
pop {r4-r8}
|
||||||
str r3,[r7]
|
|
||||||
pop {r4-r7}
|
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
END
|
END
|
||||||
|
@ -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
|
// This program and the accompanying materials
|
||||||
// are licensed and made available under the terms and conditions of the BSD License
|
// are licensed and made available under the terms and conditions of the BSD License
|
||||||
@ -15,18 +15,6 @@
|
|||||||
.align 3
|
.align 3
|
||||||
|
|
||||||
GCC_ASM_EXPORT(ArmCallSmc)
|
GCC_ASM_EXPORT(ArmCallSmc)
|
||||||
GCC_ASM_EXPORT(ArmCallSmcArg1)
|
|
||||||
GCC_ASM_EXPORT(ArmCallSmcArg2)
|
|
||||||
GCC_ASM_EXPORT(ArmCallSmcArg3)
|
|
||||||
|
|
||||||
ASM_PFX(ArmCallSmc):
|
ASM_PFX(ArmCallSmc):
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ASM_PFX(ArmCallSmcArg1):
|
|
||||||
ret
|
|
||||||
|
|
||||||
ASM_PFX(ArmCallSmcArg2):
|
|
||||||
ret
|
|
||||||
|
|
||||||
ASM_PFX(ArmCallSmcArg3):
|
|
||||||
ret
|
|
||||||
|
@ -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
|
// This program and the accompanying materials
|
||||||
// are licensed and made available under the terms and conditions of the BSD License
|
// are licensed and made available under the terms and conditions of the BSD License
|
||||||
@ -15,19 +15,6 @@
|
|||||||
.align 3
|
.align 3
|
||||||
|
|
||||||
GCC_ASM_EXPORT(ArmCallSmc)
|
GCC_ASM_EXPORT(ArmCallSmc)
|
||||||
GCC_ASM_EXPORT(ArmCallSmcArg1)
|
|
||||||
GCC_ASM_EXPORT(ArmCallSmcArg2)
|
|
||||||
GCC_ASM_EXPORT(ArmCallSmcArg3)
|
|
||||||
|
|
||||||
ASM_PFX(ArmCallSmc):
|
ASM_PFX(ArmCallSmc):
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
// Arg1 in R1
|
|
||||||
ASM_PFX(ArmCallSmcArg1):
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
ASM_PFX(ArmCallSmcArg2):
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
ASM_PFX(ArmCallSmcArg3):
|
|
||||||
bx lr
|
|
||||||
|
@ -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
|
// This program and the accompanying materials
|
||||||
// are licensed and made available under the terms and conditions of the BSD License
|
// are licensed and made available under the terms and conditions of the BSD License
|
||||||
@ -12,23 +12,10 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
EXPORT ArmCallSmc
|
EXPORT ArmCallSmc
|
||||||
EXPORT ArmCallSmcArg1
|
|
||||||
EXPORT ArmCallSmcArg2
|
|
||||||
EXPORT ArmCallSmcArg3
|
|
||||||
|
|
||||||
AREA ArmSmc, CODE, READONLY
|
AREA ArmSmc, CODE, READONLY
|
||||||
|
|
||||||
ArmCallSmc
|
ArmCallSmc
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
// Arg1 in R1
|
|
||||||
ArmCallSmcArg1
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
ArmCallSmcArg2
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
ArmCallSmcArg3
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
END
|
END
|
||||||
|
Loading…
x
Reference in New Issue
Block a user