diff mbox

[edk2,v7,03/24] ArmPkg: add ArmHvcLib

Message ID 1409918214-29584-4-git-send-email-ard.biesheuvel@linaro.org
State New
Headers show

Commit Message

Ard Biesheuvel Sept. 5, 2014, 11:56 a.m. UTC
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

Comments

Laszlo Ersek Sept. 6, 2014, 5:11 p.m. UTC | #1
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/
Ard Biesheuvel Sept. 6, 2014, 5:21 p.m. UTC | #2
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.
Laszlo Ersek Sept. 6, 2014, 6:03 p.m. UTC | #3
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/
Olivier Martin Sept. 9, 2014, 10:58 a.m. UTC | #4
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
Ard Biesheuvel Sept. 9, 2014, 11:10 a.m. UTC | #5
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.
Ard Biesheuvel Sept. 9, 2014, 11:24 a.m. UTC | #6
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
Peter Maydell Sept. 9, 2014, 11:31 a.m. UTC | #7
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
Ard Biesheuvel Sept. 9, 2014, 11:40 a.m. UTC | #8
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 mbox

Patch

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