Message ID | 1409918214-29584-4-git-send-email-ard.biesheuvel@linaro.org |
---|---|
State | New |
Headers | show |
two notes: (1) a great many ARM libraries don't use EFIAPI, so I'll assume that EFIAPI is a no-op on ARM. This library is certainly not an exception; under ArmPkg/Include/Library, there are 7 library headers without the word EFIAPI in them. Okay. On 09/05/14 13:56, Ard Biesheuvel wrote: > This is a utility library closely modeled after ArmSmcLib, that allows > hypervisor call (HVC) instructions to be issued from C code. > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> > --- > ArmPkg/Include/Library/ArmHvcLib.h | 42 ++++++++++++++++++++++++++++++ > ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S | 38 +++++++++++++++++++++++++++ > ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S | 43 +++++++++++++++++++++++++++++++ > ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm | 43 +++++++++++++++++++++++++++++++ > ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf | 32 +++++++++++++++++++++++ > 5 files changed, 198 insertions(+) > create mode 100644 ArmPkg/Include/Library/ArmHvcLib.h > create mode 100644 ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S > create mode 100644 ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S > create mode 100644 ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm > create mode 100644 ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf > > diff --git a/ArmPkg/Include/Library/ArmHvcLib.h b/ArmPkg/Include/Library/ArmHvcLib.h > new file mode 100644 > index 000000000000..b5c3d81cdf3d > --- /dev/null > +++ b/ArmPkg/Include/Library/ArmHvcLib.h > @@ -0,0 +1,42 @@ > +/** @file > +* > +* 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 > +* which accompanies this distribution. The full text of the license may be found at > +* http://opensource.org/licenses/bsd-license.php > +* > +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > +* > +**/ > + > +#ifndef __ARM_HVC_LIB__ > +#define __ARM_HVC_LIB__ > + > +/** > + * The size of the HVC 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; > +} ARM_HVC_ARGS; > + > +/** > + Trigger an HVC call > + > + HVC calls can take up to 4 arguments and return up to 4 return values. > + Therefore, the 4 first fields in the ARM_HVC_ARGS structure are used > + for both input and output values. > + > +**/ > +VOID > +ArmCallHvc ( > + IN OUT ARM_HVC_ARGS *Args > + ); > + > +#endif > diff --git a/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S b/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S > new file mode 100644 > index 000000000000..156e5554cf5b > --- /dev/null > +++ b/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S > @@ -0,0 +1,38 @@ > +// > +// Copyright (c) 2012-2014, ARM Limited. All rights reserved. > +// Copyright (c) 2014, Linaro Limited. All rights reserved. > +// > +// This program and the accompanying materials > +// are licensed and made available under the terms and conditions of the BSD License > +// which accompanies this distribution. The full text of the license may be found at > +// http://opensource.org/licenses/bsd-license.php > +// > +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > +// > +// > + > +.text > +.align 3 > + > +GCC_ASM_EXPORT(ArmCallHvc) > + > +ASM_PFX(ArmCallHvc): > + // Push x0 on the stack > + str x0, [sp, #-8]! > + > + // Load the HVC arguments values into the appropriate registers > + ldp x2, x3, [x0, #16] > + ldp x0, x1, [x0, #0] > + > + hvc #0 > + > + // Pop the ARM_HVC_ARGS structure address from the stack into x9 > + ldr x9, [sp], #8 > + > + // Store the HVC returned values into the appropriate registers > + // A HVC call can return up to 4 values > + stp x2, x3, [x9, #16] > + stp x0, x1, [x9, #0] > + > + ret > diff --git a/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S > new file mode 100644 > index 000000000000..e48f2ebc2032 > --- /dev/null > +++ b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S > @@ -0,0 +1,43 @@ > +// > +// Copyright (c) 2012-2014, ARM Limited. All rights reserved. > +// Copyright (c) 2014, Linaro Limited. All rights reserved. > +// > +// This program and the accompanying materials > +// are licensed and made available under the terms and conditions of the BSD License > +// which accompanies this distribution. The full text of the license may be found at > +// http://opensource.org/licenses/bsd-license.php > +// > +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > +// > +// > + > +.text > +.align 3 > +.arch_extension virt > + > +GCC_ASM_EXPORT(ArmCallHvc) > + > +ASM_PFX(ArmCallHvc): > + // r0 will be popped just after the HVC call > + push {r0} > + > + // Load the HVC arguments values into the appropriate registers > + ldr r3, [r0, #12] > + ldr r2, [r0, #8] > + ldr r1, [r0, #4] > + ldr r0, [r0, #0] > + > + hvc #0 > + > + // Pop the ARM_HVC_ARGS structure address from the stack into ip > + pop {ip} > + > + // Load the HVC returned values into the appropriate registers > + // A HVC call can return up to 4 values > + str r3, [ip, #12] > + str r2, [ip, #8] > + str r1, [ip, #4] > + str r0, [ip, #0] > + > + bx lr > diff --git a/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm > new file mode 100644 > index 000000000000..1275f590c8aa > --- /dev/null > +++ b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm > @@ -0,0 +1,43 @@ > +// > +// Copyright (c) 2012-2014, ARM Limited. All rights reserved. > +// Copyright (c) 2014, Linaro Limited. All rights reserved. > +// > +// This program and the accompanying materials > +// are licensed and made available under the terms and conditions of the BSD License > +// which accompanies this distribution. The full text of the license may be found at > +// http://opensource.org/licenses/bsd-license.php > +// > +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > +// > +// > + > + EXPORT ArmCallHvc > + > + AREA ArmHvc, CODE, READONLY > + > +ArmCallHvc > + // r0 will be popped just after the HVC call > + pop {r0} (2) Shouldn't this be a push then? (Consistently with the GCC source?) (/me high-fives himself for catching this :)) I guess you didn't test a 32-bit build with RVCT; it would have blown up pretty quickly I guess. Please do not repost though, fix it in a followup series (as far as I'm concerned). ... FILE_GUID below is unique; good. And, this lib will be put to use in ArmPsciResetSystemLib (the next patch). Acked-by: Laszlo Ersek <lersek@redhat.com> Thanks, Laszlo > + > + // Load the HVC arguments values into the appropriate registers > + ldr r3, [r0, #12] > + ldr r2, [r0, #8] > + ldr r1, [r0, #4] > + ldr r0, [r0, #0] > + > + hvc #0 > + > + // Pop the ARM_HVC_ARGS structure address from the stack into ip > + pop {ip} > + > + // Load the HVC returned values into the appropriate registers > + // A HVC call can return up to 4 values > + str r3, [ip, #12] > + str r2, [ip, #8] > + str r1, [ip, #4] > + str r0, [ip, #0] > + > + bx lr > + > + END > diff --git a/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf b/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf > new file mode 100644 > index 000000000000..92efac5741c8 > --- /dev/null > +++ b/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf > @@ -0,0 +1,32 @@ > +#/** @file > +# > +# Copyright (c) 2012-2013, ARM Ltd. All rights reserved.<BR> > +# Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR> > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the BSD License > +# which accompanies this distribution. The full text of the license may be found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > +# > +#**/ > + > +[Defines] > + INF_VERSION = 0x00010005 > + BASE_NAME = ArmHvcLib > + FILE_GUID = E594959A-D150-44D3-963B-BA90329D3D9A > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = ArmHvcLib > + > +[Sources.ARM] > + Arm/ArmHvc.asm | RVCT > + Arm/ArmHvc.S | GCC > + > +[Sources.AARCH64] > + AArch64/ArmHvc.S > + > +[Packages] > + MdePkg/MdePkg.dec > + ArmPkg/ArmPkg.dec > ------------------------------------------------------------------------------ Slashdot TV. Video for Nerds. Stuff that matters. http://tv.slashdot.org/
On 6 September 2014 19:11, Laszlo Ersek <lersek@redhat.com> wrote: > two notes: > > (1) a great many ARM libraries don't use EFIAPI, so I'll assume that > EFIAPI is a no-op on ARM. This library is certainly not an exception; > under ArmPkg/Include/Library, there are 7 library headers without the > word EFIAPI in them. Okay. > I haven't given this any thought, to be honest. In this case especially, I just cloned ArmSmcLib and fixed it up. > On 09/05/14 13:56, Ard Biesheuvel wrote: >> This is a utility library closely modeled after ArmSmcLib, that allows >> hypervisor call (HVC) instructions to be issued from C code. >> >> Contributed-under: TianoCore Contribution Agreement 1.0 >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> >> --- >> ArmPkg/Include/Library/ArmHvcLib.h | 42 ++++++++++++++++++++++++++++++ >> ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S | 38 +++++++++++++++++++++++++++ >> ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S | 43 +++++++++++++++++++++++++++++++ >> ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm | 43 +++++++++++++++++++++++++++++++ >> ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf | 32 +++++++++++++++++++++++ >> 5 files changed, 198 insertions(+) >> create mode 100644 ArmPkg/Include/Library/ArmHvcLib.h >> create mode 100644 ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S >> create mode 100644 ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S >> create mode 100644 ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm >> create mode 100644 ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf >> >> diff --git a/ArmPkg/Include/Library/ArmHvcLib.h b/ArmPkg/Include/Library/ArmHvcLib.h >> new file mode 100644 >> index 000000000000..b5c3d81cdf3d >> --- /dev/null >> +++ b/ArmPkg/Include/Library/ArmHvcLib.h >> @@ -0,0 +1,42 @@ >> +/** @file >> +* >> +* 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 >> +* which accompanies this distribution. The full text of the license may be found at >> +* http://opensource.org/licenses/bsd-license.php >> +* >> +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, >> +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. >> +* >> +**/ >> + >> +#ifndef __ARM_HVC_LIB__ >> +#define __ARM_HVC_LIB__ >> + >> +/** >> + * The size of the HVC 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; >> +} ARM_HVC_ARGS; >> + >> +/** >> + Trigger an HVC call >> + >> + HVC calls can take up to 4 arguments and return up to 4 return values. >> + Therefore, the 4 first fields in the ARM_HVC_ARGS structure are used >> + for both input and output values. >> + >> +**/ >> +VOID >> +ArmCallHvc ( >> + IN OUT ARM_HVC_ARGS *Args >> + ); >> + >> +#endif >> diff --git a/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S b/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S >> new file mode 100644 >> index 000000000000..156e5554cf5b >> --- /dev/null >> +++ b/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S >> @@ -0,0 +1,38 @@ >> +// >> +// Copyright (c) 2012-2014, ARM Limited. All rights reserved. >> +// Copyright (c) 2014, Linaro Limited. All rights reserved. >> +// >> +// This program and the accompanying materials >> +// are licensed and made available under the terms and conditions of the BSD License >> +// which accompanies this distribution. The full text of the license may be found at >> +// http://opensource.org/licenses/bsd-license.php >> +// >> +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, >> +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. >> +// >> +// >> + >> +.text >> +.align 3 >> + >> +GCC_ASM_EXPORT(ArmCallHvc) >> + >> +ASM_PFX(ArmCallHvc): >> + // Push x0 on the stack >> + str x0, [sp, #-8]! >> + >> + // Load the HVC arguments values into the appropriate registers >> + ldp x2, x3, [x0, #16] >> + ldp x0, x1, [x0, #0] >> + >> + hvc #0 >> + >> + // Pop the ARM_HVC_ARGS structure address from the stack into x9 >> + ldr x9, [sp], #8 >> + >> + // Store the HVC returned values into the appropriate registers >> + // A HVC call can return up to 4 values >> + stp x2, x3, [x9, #16] >> + stp x0, x1, [x9, #0] >> + >> + ret >> diff --git a/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S >> new file mode 100644 >> index 000000000000..e48f2ebc2032 >> --- /dev/null >> +++ b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S >> @@ -0,0 +1,43 @@ >> +// >> +// Copyright (c) 2012-2014, ARM Limited. All rights reserved. >> +// Copyright (c) 2014, Linaro Limited. All rights reserved. >> +// >> +// This program and the accompanying materials >> +// are licensed and made available under the terms and conditions of the BSD License >> +// which accompanies this distribution. The full text of the license may be found at >> +// http://opensource.org/licenses/bsd-license.php >> +// >> +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, >> +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. >> +// >> +// >> + >> +.text >> +.align 3 >> +.arch_extension virt >> + >> +GCC_ASM_EXPORT(ArmCallHvc) >> + >> +ASM_PFX(ArmCallHvc): >> + // r0 will be popped just after the HVC call >> + push {r0} >> + >> + // Load the HVC arguments values into the appropriate registers >> + ldr r3, [r0, #12] >> + ldr r2, [r0, #8] >> + ldr r1, [r0, #4] >> + ldr r0, [r0, #0] >> + >> + hvc #0 >> + >> + // Pop the ARM_HVC_ARGS structure address from the stack into ip >> + pop {ip} >> + >> + // Load the HVC returned values into the appropriate registers >> + // A HVC call can return up to 4 values >> + str r3, [ip, #12] >> + str r2, [ip, #8] >> + str r1, [ip, #4] >> + str r0, [ip, #0] >> + >> + bx lr >> diff --git a/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm >> new file mode 100644 >> index 000000000000..1275f590c8aa >> --- /dev/null >> +++ b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm >> @@ -0,0 +1,43 @@ >> +// >> +// Copyright (c) 2012-2014, ARM Limited. All rights reserved. >> +// Copyright (c) 2014, Linaro Limited. All rights reserved. >> +// >> +// This program and the accompanying materials >> +// are licensed and made available under the terms and conditions of the BSD License >> +// which accompanies this distribution. The full text of the license may be found at >> +// http://opensource.org/licenses/bsd-license.php >> +// >> +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, >> +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. >> +// >> +// >> + >> + EXPORT ArmCallHvc >> + >> + AREA ArmHvc, CODE, READONLY >> + >> +ArmCallHvc >> + // r0 will be popped just after the HVC call >> + pop {r0} > > (2) Shouldn't this be a push then? (Consistently with the GCC source?) > > (/me high-fives himself for catching this :)) > Well spotted! And it gets better: the original ArmSmcLib has the same bug :-) > I guess you didn't test a 32-bit build with RVCT; it would have blown up > pretty quickly I guess. > No, RVCT is a proprietary toolchain which I don't have a license for, nor am I particularly interested in obtaining one. > Please do not repost though, fix it in a followup series (as far as I'm > concerned). > > ... FILE_GUID below is unique; good. And, this lib will be put to use in > ArmPsciResetSystemLib (the next patch). > > Acked-by: Laszlo Ersek <lersek@redhat.com> > Thanks. Would you like to propose a patch for ArmSmcLib? Otherwise, i will go ahead and do it.
On 09/06/14 19:21, Ard Biesheuvel wrote: > On 6 September 2014 19:11, Laszlo Ersek <lersek@redhat.com> wrote: >> On 09/05/14 13:56, Ard Biesheuvel wrote: >>> +ArmCallHvc >>> + // r0 will be popped just after the HVC call >>> + pop {r0} >> >> (2) Shouldn't this be a push then? (Consistently with the GCC source?) >> >> (/me high-fives himself for catching this :)) >> > > Well spotted! And it gets better: the original ArmSmcLib has the same bug :-) > > >> I guess you didn't test a 32-bit build with RVCT; it would have blown up >> pretty quickly I guess. >> > > No, RVCT is a proprietary toolchain which I don't have a license for, > nor am I particularly interested in obtaining one. > >> Please do not repost though, fix it in a followup series (as far as I'm >> concerned). >> >> ... FILE_GUID below is unique; good. And, this lib will be put to use in >> ArmPsciResetSystemLib (the next patch). >> >> Acked-by: Laszlo Ersek <lersek@redhat.com> >> > > Thanks. > > Would you like to propose a patch for ArmSmcLib? Otherwise, i will go > ahead and do it. I'll pass this time, thanks :) Laszlo ------------------------------------------------------------------------------ Slashdot TV. Video for Nerds. Stuff that matters. http://tv.slashdot.org/
Any reason why you moved from the 8 arguments used by ArmSmcLib to 4 arguments for ArmHvcLib? I thought I read somewhere the HVC calling convention was the same as the SMC calling convention. But I cannot find this document again :-/ > -----Original Message----- > From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org] > Sent: 05 September 2014 12:57 > To: edk2-devel@lists.sourceforge.net; lersek@redhat.com; Olivier Martin > Cc: peter.maydell@linaro.org; christoffer.dall@linaro.org; > ilias.biris@linaro.org; leif.lindholm@linaro.org; Ard Biesheuvel > Subject: [PATCH v7 03/24] ArmPkg: add ArmHvcLib > > This is a utility library closely modeled after ArmSmcLib, that allows > hypervisor call (HVC) instructions to be issued from C code. > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> > --- > ArmPkg/Include/Library/ArmHvcLib.h | 42 > ++++++++++++++++++++++++++++++ > ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S | 38 > +++++++++++++++++++++++++++ > ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S | 43 > +++++++++++++++++++++++++++++++ > ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm | 43 > +++++++++++++++++++++++++++++++ > ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf | 32 +++++++++++++++++++++++ > 5 files changed, 198 insertions(+) > create mode 100644 ArmPkg/Include/Library/ArmHvcLib.h > create mode 100644 ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S > create mode 100644 ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S > create mode 100644 ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm > create mode 100644 ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf > > diff --git a/ArmPkg/Include/Library/ArmHvcLib.h > b/ArmPkg/Include/Library/ArmHvcLib.h > new file mode 100644 > index 000000000000..b5c3d81cdf3d > --- /dev/null > +++ b/ArmPkg/Include/Library/ArmHvcLib.h > @@ -0,0 +1,42 @@ > +/** @file > +* > +* 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 > +* which accompanies this distribution. The full text of the license > may be found at > +* http://opensource.org/licenses/bsd-license.php > +* > +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS > OR IMPLIED. > +* > +**/ > + > +#ifndef __ARM_HVC_LIB__ > +#define __ARM_HVC_LIB__ > + > +/** > + * The size of the HVC 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; > +} ARM_HVC_ARGS; > + > +/** > + Trigger an HVC call > + > + HVC calls can take up to 4 arguments and return up to 4 return > values. > + Therefore, the 4 first fields in the ARM_HVC_ARGS structure are used > + for both input and output values. > + > +**/ > +VOID > +ArmCallHvc ( > + IN OUT ARM_HVC_ARGS *Args > + ); > + > +#endif > diff --git a/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S > b/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S > new file mode 100644 > index 000000000000..156e5554cf5b > --- /dev/null > +++ b/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S > @@ -0,0 +1,38 @@ > +// > +// Copyright (c) 2012-2014, ARM Limited. All rights reserved. > +// Copyright (c) 2014, Linaro Limited. All rights reserved. > +// > +// This program and the accompanying materials > +// are licensed and made available under the terms and conditions of > the BSD License > +// which accompanies this distribution. The full text of the license > may be found at > +// http://opensource.org/licenses/bsd-license.php > +// > +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS > OR IMPLIED. > +// > +// > + > +.text > +.align 3 > + > +GCC_ASM_EXPORT(ArmCallHvc) > + > +ASM_PFX(ArmCallHvc): > + // Push x0 on the stack > + str x0, [sp, #-8]! > + > + // Load the HVC arguments values into the appropriate registers > + ldp x2, x3, [x0, #16] > + ldp x0, x1, [x0, #0] > + > + hvc #0 > + > + // Pop the ARM_HVC_ARGS structure address from the stack into x9 > + ldr x9, [sp], #8 > + > + // Store the HVC returned values into the appropriate registers > + // A HVC call can return up to 4 values > + stp x2, x3, [x9, #16] > + stp x0, x1, [x9, #0] > + > + ret > diff --git a/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S > b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S > new file mode 100644 > index 000000000000..e48f2ebc2032 > --- /dev/null > +++ b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S > @@ -0,0 +1,43 @@ > +// > +// Copyright (c) 2012-2014, ARM Limited. All rights reserved. > +// Copyright (c) 2014, Linaro Limited. All rights reserved. > +// > +// This program and the accompanying materials > +// are licensed and made available under the terms and conditions of > the BSD License > +// which accompanies this distribution. The full text of the license > may be found at > +// http://opensource.org/licenses/bsd-license.php > +// > +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS > OR IMPLIED. > +// > +// > + > +.text > +.align 3 > +.arch_extension virt > + > +GCC_ASM_EXPORT(ArmCallHvc) > + > +ASM_PFX(ArmCallHvc): > + // r0 will be popped just after the HVC call > + push {r0} > + > + // Load the HVC arguments values into the appropriate registers > + ldr r3, [r0, #12] > + ldr r2, [r0, #8] > + ldr r1, [r0, #4] > + ldr r0, [r0, #0] > + > + hvc #0 > + > + // Pop the ARM_HVC_ARGS structure address from the stack into ip > + pop {ip} > + > + // Load the HVC returned values into the appropriate registers > + // A HVC call can return up to 4 values > + str r3, [ip, #12] > + str r2, [ip, #8] > + str r1, [ip, #4] > + str r0, [ip, #0] > + > + bx lr > diff --git a/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm > b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm > new file mode 100644 > index 000000000000..1275f590c8aa > --- /dev/null > +++ b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm > @@ -0,0 +1,43 @@ > +// > +// Copyright (c) 2012-2014, ARM Limited. All rights reserved. > +// Copyright (c) 2014, Linaro Limited. All rights reserved. > +// > +// This program and the accompanying materials > +// are licensed and made available under the terms and conditions of > the BSD License > +// which accompanies this distribution. The full text of the license > may be found at > +// http://opensource.org/licenses/bsd-license.php > +// > +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS > OR IMPLIED. > +// > +// > + > + EXPORT ArmCallHvc > + > + AREA ArmHvc, CODE, READONLY > + > +ArmCallHvc > + // r0 will be popped just after the HVC call > + pop {r0} > + > + // Load the HVC arguments values into the appropriate registers > + ldr r3, [r0, #12] > + ldr r2, [r0, #8] > + ldr r1, [r0, #4] > + ldr r0, [r0, #0] > + > + hvc #0 > + > + // Pop the ARM_HVC_ARGS structure address from the stack into ip > + pop {ip} > + > + // Load the HVC returned values into the appropriate registers > + // A HVC call can return up to 4 values > + str r3, [ip, #12] > + str r2, [ip, #8] > + str r1, [ip, #4] > + str r0, [ip, #0] > + > + bx lr > + > + END > diff --git a/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf > b/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf > new file mode 100644 > index 000000000000..92efac5741c8 > --- /dev/null > +++ b/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf > @@ -0,0 +1,32 @@ > +#/** @file > +# > +# Copyright (c) 2012-2013, ARM Ltd. All rights reserved.<BR> > +# Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR> > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of > the BSD License > +# which accompanies this distribution. The full text of the license > may be found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS > OR IMPLIED. > +# > +#**/ > + > +[Defines] > + INF_VERSION = 0x00010005 > + BASE_NAME = ArmHvcLib > + FILE_GUID = E594959A-D150-44D3-963B- > BA90329D3D9A > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = ArmHvcLib > + > +[Sources.ARM] > + Arm/ArmHvc.asm | RVCT > + Arm/ArmHvc.S | GCC > + > +[Sources.AARCH64] > + AArch64/ArmHvc.S > + > +[Packages] > + MdePkg/MdePkg.dec > + ArmPkg/ArmPkg.dec > -- > 1.8.3.2 > ------------------------------------------------------------------------------ Want excitement? Manually upgrade your production database. When you want reliability, choose Perforce. Perforce version control. Predictably reliable. http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
On 9 September 2014 12:58, Olivier Martin <olivier.martin@arm.com> wrote: > Any reason why you moved from the 8 arguments used by ArmSmcLib to 4 > arguments for ArmHvcLib? > I thought I read somewhere the HVC calling convention was the same as the > SMC calling convention. But I cannot find this document again :-/ > I consulted the HVC calling convention document (ARM DEN 0022B.b), which states only 4 registers are used.
On 9 September 2014 13:10, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > On 9 September 2014 12:58, Olivier Martin <olivier.martin@arm.com> wrote: >> Any reason why you moved from the 8 arguments used by ArmSmcLib to 4 >> arguments for ArmHvcLib? >> I thought I read somewhere the HVC calling convention was the same as the >> SMC calling convention. But I cannot find this document again :-/ >> > > I consulted the HVC calling convention document (ARM DEN 0022B.b), > which states only 4 registers are used. > My apologies, I pasted the wrong number : ARM DEN 0020 >>> -----Original Message----- >>> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org] >>> Sent: 05 September 2014 12:57 >>> To: edk2-devel@lists.sourceforge.net; lersek@redhat.com; Olivier Martin >>> Cc: peter.maydell@linaro.org; christoffer.dall@linaro.org; >>> ilias.biris@linaro.org; leif.lindholm@linaro.org; Ard Biesheuvel >>> Subject: [PATCH v7 03/24] ArmPkg: add ArmHvcLib >>> >>> This is a utility library closely modeled after ArmSmcLib, that allows >>> hypervisor call (HVC) instructions to be issued from C code. >>> >>> Contributed-under: TianoCore Contribution Agreement 1.0 >>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> >>> --- >>> ArmPkg/Include/Library/ArmHvcLib.h | 42 >>> ++++++++++++++++++++++++++++++ >>> ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S | 38 >>> +++++++++++++++++++++++++++ >>> ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S | 43 >>> +++++++++++++++++++++++++++++++ >>> ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm | 43 >>> +++++++++++++++++++++++++++++++ >>> ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf | 32 +++++++++++++++++++++++ >>> 5 files changed, 198 insertions(+) >>> create mode 100644 ArmPkg/Include/Library/ArmHvcLib.h >>> create mode 100644 ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S >>> create mode 100644 ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S >>> create mode 100644 ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm >>> create mode 100644 ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf >>> >>> diff --git a/ArmPkg/Include/Library/ArmHvcLib.h >>> b/ArmPkg/Include/Library/ArmHvcLib.h >>> new file mode 100644 >>> index 000000000000..b5c3d81cdf3d >>> --- /dev/null >>> +++ b/ArmPkg/Include/Library/ArmHvcLib.h >>> @@ -0,0 +1,42 @@ >>> +/** @file >>> +* >>> +* 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 >>> +* which accompanies this distribution. The full text of the license >>> may be found at >>> +* http://opensource.org/licenses/bsd-license.php >>> +* >>> +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >>> BASIS, >>> +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS >>> OR IMPLIED. >>> +* >>> +**/ >>> + >>> +#ifndef __ARM_HVC_LIB__ >>> +#define __ARM_HVC_LIB__ >>> + >>> +/** >>> + * The size of the HVC 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; >>> +} ARM_HVC_ARGS; >>> + >>> +/** >>> + Trigger an HVC call >>> + >>> + HVC calls can take up to 4 arguments and return up to 4 return >>> values. >>> + Therefore, the 4 first fields in the ARM_HVC_ARGS structure are used >>> + for both input and output values. >>> + >>> +**/ >>> +VOID >>> +ArmCallHvc ( >>> + IN OUT ARM_HVC_ARGS *Args >>> + ); >>> + >>> +#endif >>> diff --git a/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S >>> b/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S >>> new file mode 100644 >>> index 000000000000..156e5554cf5b >>> --- /dev/null >>> +++ b/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S >>> @@ -0,0 +1,38 @@ >>> +// >>> +// Copyright (c) 2012-2014, ARM Limited. All rights reserved. >>> +// Copyright (c) 2014, Linaro Limited. All rights reserved. >>> +// >>> +// This program and the accompanying materials >>> +// are licensed and made available under the terms and conditions of >>> the BSD License >>> +// which accompanies this distribution. The full text of the license >>> may be found at >>> +// http://opensource.org/licenses/bsd-license.php >>> +// >>> +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >>> BASIS, >>> +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS >>> OR IMPLIED. >>> +// >>> +// >>> + >>> +.text >>> +.align 3 >>> + >>> +GCC_ASM_EXPORT(ArmCallHvc) >>> + >>> +ASM_PFX(ArmCallHvc): >>> + // Push x0 on the stack >>> + str x0, [sp, #-8]! >>> + >>> + // Load the HVC arguments values into the appropriate registers >>> + ldp x2, x3, [x0, #16] >>> + ldp x0, x1, [x0, #0] >>> + >>> + hvc #0 >>> + >>> + // Pop the ARM_HVC_ARGS structure address from the stack into x9 >>> + ldr x9, [sp], #8 >>> + >>> + // Store the HVC returned values into the appropriate registers >>> + // A HVC call can return up to 4 values >>> + stp x2, x3, [x9, #16] >>> + stp x0, x1, [x9, #0] >>> + >>> + ret >>> diff --git a/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S >>> b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S >>> new file mode 100644 >>> index 000000000000..e48f2ebc2032 >>> --- /dev/null >>> +++ b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S >>> @@ -0,0 +1,43 @@ >>> +// >>> +// Copyright (c) 2012-2014, ARM Limited. All rights reserved. >>> +// Copyright (c) 2014, Linaro Limited. All rights reserved. >>> +// >>> +// This program and the accompanying materials >>> +// are licensed and made available under the terms and conditions of >>> the BSD License >>> +// which accompanies this distribution. The full text of the license >>> may be found at >>> +// http://opensource.org/licenses/bsd-license.php >>> +// >>> +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >>> BASIS, >>> +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS >>> OR IMPLIED. >>> +// >>> +// >>> + >>> +.text >>> +.align 3 >>> +.arch_extension virt >>> + >>> +GCC_ASM_EXPORT(ArmCallHvc) >>> + >>> +ASM_PFX(ArmCallHvc): >>> + // r0 will be popped just after the HVC call >>> + push {r0} >>> + >>> + // Load the HVC arguments values into the appropriate registers >>> + ldr r3, [r0, #12] >>> + ldr r2, [r0, #8] >>> + ldr r1, [r0, #4] >>> + ldr r0, [r0, #0] >>> + >>> + hvc #0 >>> + >>> + // Pop the ARM_HVC_ARGS structure address from the stack into ip >>> + pop {ip} >>> + >>> + // Load the HVC returned values into the appropriate registers >>> + // A HVC call can return up to 4 values >>> + str r3, [ip, #12] >>> + str r2, [ip, #8] >>> + str r1, [ip, #4] >>> + str r0, [ip, #0] >>> + >>> + bx lr >>> diff --git a/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm >>> b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm >>> new file mode 100644 >>> index 000000000000..1275f590c8aa >>> --- /dev/null >>> +++ b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm >>> @@ -0,0 +1,43 @@ >>> +// >>> +// Copyright (c) 2012-2014, ARM Limited. All rights reserved. >>> +// Copyright (c) 2014, Linaro Limited. All rights reserved. >>> +// >>> +// This program and the accompanying materials >>> +// are licensed and made available under the terms and conditions of >>> the BSD License >>> +// which accompanies this distribution. The full text of the license >>> may be found at >>> +// http://opensource.org/licenses/bsd-license.php >>> +// >>> +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >>> BASIS, >>> +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS >>> OR IMPLIED. >>> +// >>> +// >>> + >>> + EXPORT ArmCallHvc >>> + >>> + AREA ArmHvc, CODE, READONLY >>> + >>> +ArmCallHvc >>> + // r0 will be popped just after the HVC call >>> + pop {r0} >>> + >>> + // Load the HVC arguments values into the appropriate registers >>> + ldr r3, [r0, #12] >>> + ldr r2, [r0, #8] >>> + ldr r1, [r0, #4] >>> + ldr r0, [r0, #0] >>> + >>> + hvc #0 >>> + >>> + // Pop the ARM_HVC_ARGS structure address from the stack into ip >>> + pop {ip} >>> + >>> + // Load the HVC returned values into the appropriate registers >>> + // A HVC call can return up to 4 values >>> + str r3, [ip, #12] >>> + str r2, [ip, #8] >>> + str r1, [ip, #4] >>> + str r0, [ip, #0] >>> + >>> + bx lr >>> + >>> + END >>> diff --git a/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf >>> b/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf >>> new file mode 100644 >>> index 000000000000..92efac5741c8 >>> --- /dev/null >>> +++ b/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf >>> @@ -0,0 +1,32 @@ >>> +#/** @file >>> +# >>> +# Copyright (c) 2012-2013, ARM Ltd. All rights reserved.<BR> >>> +# Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR> >>> +# This program and the accompanying materials >>> +# are licensed and made available under the terms and conditions of >>> the BSD License >>> +# which accompanies this distribution. The full text of the license >>> may be found at >>> +# http://opensource.org/licenses/bsd-license.php >>> +# >>> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >>> BASIS, >>> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS >>> OR IMPLIED. >>> +# >>> +#**/ >>> + >>> +[Defines] >>> + INF_VERSION = 0x00010005 >>> + BASE_NAME = ArmHvcLib >>> + FILE_GUID = E594959A-D150-44D3-963B- >>> BA90329D3D9A >>> + MODULE_TYPE = BASE >>> + VERSION_STRING = 1.0 >>> + LIBRARY_CLASS = ArmHvcLib >>> + >>> +[Sources.ARM] >>> + Arm/ArmHvc.asm | RVCT >>> + Arm/ArmHvc.S | GCC >>> + >>> +[Sources.AARCH64] >>> + AArch64/ArmHvc.S >>> + >>> +[Packages] >>> + MdePkg/MdePkg.dec >>> + ArmPkg/ArmPkg.dec >>> -- >>> 1.8.3.2 >>> >> >> >> >> ------------------------------------------------------------------------------ Want excitement? Manually upgrade your production database. When you want reliability, choose Perforce. Perforce version control. Predictably reliable. http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
On 9 September 2014 12:10, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > On 9 September 2014 12:58, Olivier Martin <olivier.martin@arm.com> wrote: >> Any reason why you moved from the 8 arguments used by ArmSmcLib to 4 >> arguments for ArmHvcLib? >> I thought I read somewhere the HVC calling convention was the same as the >> SMC calling convention. But I cannot find this document again :-/ >> > > I consulted the HVC calling convention document (ARM DEN 0022B.b), > which states only 4 registers are used. That's the PSCI spec, which defers to DEN0028A "SMC Calling Convention" for the specifics of the calling convention. The latter allows up to 7 input values and 4 return values. It happens that no PSCI function uses more than 4 inputs or more than 1 return value, but it doesn't seem completely out of the question that a future PSCI spec might want to pass more than 4 arguments to something. (The PSCI spec doesn't refer to the HVC calling convention document you mention, so I think it is not relevant in this context.) -- PMM ------------------------------------------------------------------------------ Want excitement? Manually upgrade your production database. When you want reliability, choose Perforce. Perforce version control. Predictably reliable. http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
On 9 September 2014 13:31, Peter Maydell <peter.maydell@linaro.org> wrote: > On 9 September 2014 12:10, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: >> On 9 September 2014 12:58, Olivier Martin <olivier.martin@arm.com> wrote: >>> Any reason why you moved from the 8 arguments used by ArmSmcLib to 4 >>> arguments for ArmHvcLib? >>> I thought I read somewhere the HVC calling convention was the same as the >>> SMC calling convention. But I cannot find this document again :-/ >>> >> >> I consulted the HVC calling convention document (ARM DEN 0022B.b), >> which states only 4 registers are used. > > That's the PSCI spec, which defers to DEN0028A "SMC Calling Convention" > for the specifics of the calling convention. The latter allows up to > 7 input values and 4 return values. It happens that no PSCI > function uses more than 4 inputs or more than 1 return value, > but it doesn't seem completely out of the question that > a future PSCI spec might want to pass more than 4 arguments > to something. > > (The PSCI spec doesn't refer to the HVC calling convention > document you mention, so I think it is not relevant in this > context.) > OK, so this document (DEN 0020) is the most detailed description I could find of a HVC calling convention, and even if the PSCI spec does not mention it, we can still adhere to both by using only four registers, so i think we can stick with this implementation for now. (The only user is the one introduced in the next patch, which only uses a single argument, i.e., either PSCI_RESET or PSCI_POWEROFF passed in register 0, and no return value) ------------------------------------------------------------------------------ Want excitement? Manually upgrade your production database. When you want reliability, choose Perforce. Perforce version control. Predictably reliable. http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
diff --git a/ArmPkg/Include/Library/ArmHvcLib.h b/ArmPkg/Include/Library/ArmHvcLib.h new file mode 100644 index 000000000000..b5c3d81cdf3d --- /dev/null +++ b/ArmPkg/Include/Library/ArmHvcLib.h @@ -0,0 +1,42 @@ +/** @file +* +* 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 +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#ifndef __ARM_HVC_LIB__ +#define __ARM_HVC_LIB__ + +/** + * The size of the HVC 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; +} ARM_HVC_ARGS; + +/** + Trigger an HVC call + + HVC calls can take up to 4 arguments and return up to 4 return values. + Therefore, the 4 first fields in the ARM_HVC_ARGS structure are used + for both input and output values. + +**/ +VOID +ArmCallHvc ( + IN OUT ARM_HVC_ARGS *Args + ); + +#endif diff --git a/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S b/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S new file mode 100644 index 000000000000..156e5554cf5b --- /dev/null +++ b/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S @@ -0,0 +1,38 @@ +// +// Copyright (c) 2012-2014, ARM Limited. All rights reserved. +// Copyright (c) 2014, Linaro Limited. All rights reserved. +// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// + +.text +.align 3 + +GCC_ASM_EXPORT(ArmCallHvc) + +ASM_PFX(ArmCallHvc): + // Push x0 on the stack + str x0, [sp, #-8]! + + // Load the HVC arguments values into the appropriate registers + ldp x2, x3, [x0, #16] + ldp x0, x1, [x0, #0] + + hvc #0 + + // Pop the ARM_HVC_ARGS structure address from the stack into x9 + ldr x9, [sp], #8 + + // Store the HVC returned values into the appropriate registers + // A HVC call can return up to 4 values + stp x2, x3, [x9, #16] + stp x0, x1, [x9, #0] + + ret diff --git a/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S new file mode 100644 index 000000000000..e48f2ebc2032 --- /dev/null +++ b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S @@ -0,0 +1,43 @@ +// +// Copyright (c) 2012-2014, ARM Limited. All rights reserved. +// Copyright (c) 2014, Linaro Limited. All rights reserved. +// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// + +.text +.align 3 +.arch_extension virt + +GCC_ASM_EXPORT(ArmCallHvc) + +ASM_PFX(ArmCallHvc): + // r0 will be popped just after the HVC call + push {r0} + + // Load the HVC arguments values into the appropriate registers + ldr r3, [r0, #12] + ldr r2, [r0, #8] + ldr r1, [r0, #4] + ldr r0, [r0, #0] + + hvc #0 + + // Pop the ARM_HVC_ARGS structure address from the stack into ip + pop {ip} + + // Load the HVC returned values into the appropriate registers + // A HVC call can return up to 4 values + str r3, [ip, #12] + str r2, [ip, #8] + str r1, [ip, #4] + str r0, [ip, #0] + + bx lr diff --git a/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm new file mode 100644 index 000000000000..1275f590c8aa --- /dev/null +++ b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm @@ -0,0 +1,43 @@ +// +// Copyright (c) 2012-2014, ARM Limited. All rights reserved. +// Copyright (c) 2014, Linaro Limited. All rights reserved. +// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// + + EXPORT ArmCallHvc + + AREA ArmHvc, CODE, READONLY + +ArmCallHvc + // r0 will be popped just after the HVC call + pop {r0} + + // Load the HVC arguments values into the appropriate registers + ldr r3, [r0, #12] + ldr r2, [r0, #8] + ldr r1, [r0, #4] + ldr r0, [r0, #0] + + hvc #0 + + // Pop the ARM_HVC_ARGS structure address from the stack into ip + pop {ip} + + // Load the HVC returned values into the appropriate registers + // A HVC call can return up to 4 values + str r3, [ip, #12] + str r2, [ip, #8] + str r1, [ip, #4] + str r0, [ip, #0] + + bx lr + + END diff --git a/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf b/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf new file mode 100644 index 000000000000..92efac5741c8 --- /dev/null +++ b/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf @@ -0,0 +1,32 @@ +#/** @file +# +# Copyright (c) 2012-2013, ARM Ltd. All rights reserved.<BR> +# Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR> +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ArmHvcLib + FILE_GUID = E594959A-D150-44D3-963B-BA90329D3D9A + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmHvcLib + +[Sources.ARM] + Arm/ArmHvc.asm | RVCT + Arm/ArmHvc.S | GCC + +[Sources.AARCH64] + AArch64/ArmHvc.S + +[Packages] + MdePkg/MdePkg.dec + ArmPkg/ArmPkg.dec
This is a utility library closely modeled after ArmSmcLib, that allows hypervisor call (HVC) instructions to be issued from C code. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> --- ArmPkg/Include/Library/ArmHvcLib.h | 42 ++++++++++++++++++++++++++++++ ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S | 38 +++++++++++++++++++++++++++ ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S | 43 +++++++++++++++++++++++++++++++ ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm | 43 +++++++++++++++++++++++++++++++ ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf | 32 +++++++++++++++++++++++ 5 files changed, 198 insertions(+) create mode 100644 ArmPkg/Include/Library/ArmHvcLib.h create mode 100644 ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S create mode 100644 ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S create mode 100644 ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm create mode 100644 ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf