[U-Boot] [PATCH v3 2/7] armv8: Add SMC calls infrastructure

Sergei Temerkhanov s.temerkhanov at gmail.com
Sat Aug 15 03:45:12 CEST 2015


On Fri, Aug 14, 2015 at 9:56 PM, Simon Glass <sjg at chromium.org> wrote:
> Hi,
>
> On 13 August 2015 at 09:14, Sergey Temerkhanov <s.temerkhanov at gmail.com> wrote:
>> This commit adds functions issuing calls to firmware. This allows
>> to use services such as PSCI provided by firmware, e.g. ATF
>
> What is PSCI? ATF? SMC? What firmware? Please try to make your commit
> message more helpful to people trying to understand the code you are
> adding.
>

These abbreviations have been introduced by ARM and are used in their
docs. These
functions basically issue calls to the secure monitor (SMC) or
hypervisor (HVC). PSCI
is the Power State Coordination Interface and ATF is ARM Trusted Firmware. SMC/
HVC calls conform to the Calling Convention specification. I'll add
the comments to the
next version of this patch
>>
>> The SMC call can destroy all registers declared temporary by the
>> calling conventions. The clobber list is "x0..x17" because of
>> this
>>
>> Signed-off-by: Sergey Temerkhanov <s.temerkhanov at gmail.com>
>> Signed-off-by: Corey Minyard <cminyard at mvista.com>
>> Signed-off-by: Radha Mohan Chintakuntla <rchintakuntla at cavium.com>
>>
>> ---
>>
>> Changes in v3:
>> - Fixed clobber lists (thanks to Corey)
>>
>> Changes in v2: None
>>
>>  arch/arm/cpu/armv8/Makefile   |  1 +
>>  arch/arm/cpu/armv8/fwcall.c   | 77 +++++++++++++++++++++++++++++++++++++++++++
>>  arch/arm/include/asm/system.h |  8 +++++
>>  3 files changed, 86 insertions(+)
>>  create mode 100644 arch/arm/cpu/armv8/fwcall.c
>>
>> diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
>> index 6466ebb..39a6ce7 100644
>> --- a/arch/arm/cpu/armv8/Makefile
>> +++ b/arch/arm/cpu/armv8/Makefile
>> @@ -14,6 +14,7 @@ obj-y += exceptions.o
>>  obj-y  += cache.o
>>  obj-y  += tlb.o
>>  obj-y  += transition.o
>> +obj-y  += fwcall.o
>>
>>  obj-$(CONFIG_FSL_LSCH3) += fsl-lsch3/
>>  obj-$(CONFIG_ARCH_ZYNQMP) += zynqmp/
>> diff --git a/arch/arm/cpu/armv8/fwcall.c b/arch/arm/cpu/armv8/fwcall.c
>> new file mode 100644
>> index 0000000..ff0caba
>> --- /dev/null
>> +++ b/arch/arm/cpu/armv8/fwcall.c
>> @@ -0,0 +1,77 @@
>> +/**
>> + * (C) Copyright 2014, Cavium Inc.
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> +**/
>> +
>> +#include <asm-offsets.h>
>> +#include <config.h>
>> +#include <version.h>
>> +#include <asm/macro.h>
>> +#include <asm/system.h>
>> +
>> +#define __asmeq(x, y)  ".ifnc " x "," y " ; .err ; .endif\n\t"
>> +
>> +/*
>> + * void hvc_call(arg0, arg1...arg7)
>> + *
>> + * issue the hypervisor call
>> + *
>> + * x0~x7: argument list
>> + */
>> +void hvc_call(struct pt_regs *args)
>> +{
>> +       asm volatile(
>> +               "ldr x0, %0\n"
>> +               "ldr x1, %1\n"
>> +               "ldr x2, %2\n"
>> +               "ldr x3, %3\n"
>> +               "ldr x4, %4\n"
>> +               "ldr x5, %5\n"
>> +               "ldr x6, %6\n"
>> +               "ldr x7, %7\n"
>> +               "hvc    #0\n"
>> +               "str x0, %0\n"
>> +               "str x1, %1\n"
>> +               "str x2, %2\n"
>> +               "str x3, %3\n"
>> +               : "+m" (args->regs[0]), "+m" (args->regs[1]),
>> +                 "+m" (args->regs[2]), "+m" (args->regs[3])
>> +               : "m" (args->regs[4]), "m" (args->regs[5]),
>> +                 "m" (args->regs[6]), "m" (args->regs[7])
>> +               : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
>> +                 "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
>> +                 "x16", "x17");
>> +}
>> +
>> +/*
>> + * void smc_call(arg0, arg1...arg7)
>> + *
>> + * issue the secure monitor call
>> + *
>> + * x0~x7: argument list
>> + */
>> +
>> +void smc_call(struct pt_regs *args)
>> +{
>> +       asm volatile(
>> +               "ldr x0, %0\n"
>> +               "ldr x1, %1\n"
>> +               "ldr x2, %2\n"
>> +               "ldr x3, %3\n"
>> +               "ldr x4, %4\n"
>> +               "ldr x5, %5\n"
>> +               "ldr x6, %6\n"
>> +               "smc    #0\n"
>> +               "str x0, %0\n"
>> +               "str x1, %1\n"
>> +               "str x2, %2\n"
>> +               "str x3, %3\n"
>> +               : "+m" (args->regs[0]), "+m" (args->regs[1]),
>> +                 "+m" (args->regs[2]), "+m" (args->regs[3])
>> +               : "m" (args->regs[4]), "m" (args->regs[5]),
>> +                 "m" (args->regs[6])
>> +               : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
>> +                 "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
>> +                 "x16", "x17");
>> +}
>> diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
>> index 9803686..6b21d90 100644
>> --- a/arch/arm/include/asm/system.h
>> +++ b/arch/arm/include/asm/system.h
>> @@ -1,6 +1,9 @@
>>  #ifndef __ASM_ARM_SYSTEM_H
>>  #define __ASM_ARM_SYSTEM_H
>>
>> +#include <common.h>
>> +#include <linux/compiler.h>
>> +
>>  #ifdef CONFIG_ARM64
>>
>>  /*
>> @@ -93,6 +96,11 @@ void smp_kick_all_cpus(void);
>>
>>  void flush_l3_cache(void);
>>
>> +#define __asmeq(x, y)  ".ifnc " x "," y " ; .err ; .endif\n\t"
>> +
>> +void hvc_call(struct pt_regs *args);
>> +void smc_call(struct pt_regs *args);
>
> Please add comments here. What do these functions do? What does hvc
> stand for. You can use something like:
>
> /**
>  * hvc_call() - do a hypervisor call
>  *
>  * hvc is ...
>  *
>  * @args: Contains register values to pass in (and pass out??)
>  *
>  */
>
>> +
>>  #endif /* __ASSEMBLY__ */
>>
>>  #else /* CONFIG_ARM64 */
>> --
>> 2.2.0
>>
>
> Regards,
> Simon


More information about the U-Boot mailing list