From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mateusz Kulikowski Date: Wed, 6 Jan 2016 14:04:37 +0100 Subject: [U-Boot] [PATCH v7 3/9] armv8: Add Secure Monitor/Hypervisor Call (SMC/HVC) infrastructure In-Reply-To: <1444841757-28043-4-git-send-email-s.temerkhanov@gmail.com> References: <1444841757-28043-1-git-send-email-s.temerkhanov@gmail.com> <1444841757-28043-4-git-send-email-s.temerkhanov@gmail.com> Message-ID: <568D10E5.4060005@gmail.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 On 14.10.2015 18:55, Sergey Temerkhanov wrote: > This commit adds functions issuing calls to secure monitor or > hypervisore. This allows using services such as Power State > Coordination Interface (PSCI) provided by firmware, e.g. ARM > Trusted Firmware (ATF) > > 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 > Signed-off-by: Corey Minyard > Signed-off-by: Radha Mohan Chintakuntla > Reviewed-by: Simon Glass +1 (I may need it as well) Tested-by: Mateusz Kulikowski Tested on: Hikey Methodology: Hacked smc handler in arm trusted firmware (x0=x0+x1, x1=x2+x3, x2=x4+x5, x3=x6+2) +new u-boot command (smc/hvc) using functions from this patch; I didn't tested hvc code (would need to make some fake hypervisor), but it's basically the same. Idea: perhaps after this series is merged we can add 2 new commands to u-boot (SMC/HVC) to play with hypervisors/secure monitors (and perhaps use some simple functionality if needed). @Sergey - you probably need to rebase the patch as it doesn't apply to master cleanly Regards, Mateusz > > --- > > Changes in v7: None > Changes in v6: None > Changes in v5: None > Changes in v4: > - Document FW calls > > 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 | 75 +++++++++++++++++++++++++++++++++++++++++++ > arch/arm/include/asm/system.h | 21 ++++++++++++ > 3 files changed, 97 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 adb11b3..7579ea7 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..9efcc5a > --- /dev/null > +++ b/arch/arm/cpu/armv8/fwcall.c > @@ -0,0 +1,75 @@ > +/** > + * (C) Copyright 2014, Cavium Inc. > + * > + * SPDX-License-Identifier: GPL-2.0+ > +**/ > + > +#include > +#include > +#include > +#include > +#include > + > +/* > + * Issue the hypervisor call > + * > + * x0~x7: input arguments > + * x0~x3: output arguments > + */ > +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: input arguments > + * x0~x3: output arguments > + */ > + > +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 9288541..f3e2d1b 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 > +#include > + > #ifdef CONFIG_ARM64 > > /* > @@ -104,6 +107,24 @@ void smp_kick_all_cpus(void); > > void flush_l3_cache(void); > > +/* > + *Issue a hypervisor call in accordance with ARM "SMC Calling convention", > + * DEN0028A > + * > + * @args: input and output arguments > + * > + */ > +void hvc_call(struct pt_regs *args); > + > +/* > + *Issue a secure monitor call in accordance with ARM "SMC Calling convention", > + * DEN0028A > + * > + * @args: input and output arguments > + * > + */ > +void smc_call(struct pt_regs *args); > + > #endif /* __ASSEMBLY__ */ > > #else /* CONFIG_ARM64 */ > -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQEcBAEBCAAGBQJWjRDgAAoJELvtohmVtQzBD/4IAJBh4uT99P/qRZtXr2SJhnIE 45wp3vuQw22IhwUiV0D/8V7dtElYLy8C3Ct4xbZF15oibSdto8k9tJjuuLw/DOdV aYvNwCSc0eyckHAfwjUwMlW4rMFVYD4ik+kvDBb9Rr9b8rpJIPWWA0mBY95rHTq/ 0uq2KsxHvbMCmmuNWksb6lk7s7fcrR3j2uavvtrFtMT255dKqw/kinWxXHDVKrWa MBngc1rsa23u07oN9MyDpE0knCLB01l3pkmu4FB5CybJvJ7FPLxMPZNaataFo4Z/ 6KM02h6RYhGntiveQ+2/vIm4BHK7XSkX9CBsi9SpV+opN8MSwhC3RKNFem72hBk= =2qqk -----END PGP SIGNATURE-----