All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 0/3] ARM: support System Reset via PSCI
@ 2017-04-13  2:39 Masahiro Yamada
  2017-04-13  2:39 ` [U-Boot] [PATCH v2 1/3] ARM: import arm-smccc code from Linux 4.11-rc6 Masahiro Yamada
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Masahiro Yamada @ 2017-04-13  2:39 UTC (permalink / raw)
  To: u-boot

For ARMv8, the secure firmware (ex. ARM Trusted Firmware BL31) is
often implemented, making U-Boot a non-secure world boot loader.

The secure firmware generally includes PSCI.  The power management
operations, including System Reset, are supposed to be handled by
PSCI.  In this case, U-Boot should not touch the system reset directly.
Instead, U-Boot should call PSCI service to reset the system.

In order to implement this, arm-smccc code is needed.  The code
has been copied from Linux. (1/3)

They have been adjusted for use in U-Boot (2/3).

3/3 implements a generic sysreset driver based on the PSCI
specification.


Masahiro Yamada (3):
  ARM: import arm-smccc code from Linux 4.11-rc6
  ARM: adjust arm-smccc code for use in U-Boot
  sysreset: psci: support system reset in a generic way with PSCI

 arch/arm/Kconfig                    |   9 ++
 arch/arm/cpu/armv7/Makefile         |   1 +
 arch/arm/cpu/armv7/smccc-call.S     |  56 +++++++++
 arch/arm/cpu/armv8/Makefile         |   2 +
 arch/arm/cpu/armv8/smccc-call.S     |  44 +++++++
 arch/arm/include/asm/opcodes-sec.h  |  17 +++
 arch/arm/include/asm/opcodes-virt.h |  27 +++++
 arch/arm/include/asm/opcodes.h      | 229 ++++++++++++++++++++++++++++++++++++
 arch/arm/lib/asm-offsets.c          |   8 ++
 drivers/Kconfig                     |   2 +
 drivers/Makefile                    |   5 +-
 drivers/firmware/Kconfig            |   6 +
 drivers/firmware/Makefile           |   2 +
 drivers/firmware/firmware-uclass.c  |  11 ++
 drivers/firmware/psci.c             |  94 +++++++++++++++
 drivers/sysreset/Kconfig            |  10 ++
 drivers/sysreset/Makefile           |   1 +
 drivers/sysreset/sysreset_psci.c    |  41 +++++++
 include/dm/uclass-id.h              |   1 +
 include/linux/arm-smccc.h           | 126 ++++++++++++++++++++
 include/linux/psci.h                |  13 ++
 21 files changed, 703 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/smccc-call.S
 create mode 100644 arch/arm/cpu/armv8/smccc-call.S
 create mode 100644 arch/arm/include/asm/opcodes-sec.h
 create mode 100644 arch/arm/include/asm/opcodes-virt.h
 create mode 100644 arch/arm/include/asm/opcodes.h
 create mode 100644 drivers/firmware/Kconfig
 create mode 100644 drivers/firmware/Makefile
 create mode 100644 drivers/firmware/firmware-uclass.c
 create mode 100644 drivers/firmware/psci.c
 create mode 100644 drivers/sysreset/sysreset_psci.c
 create mode 100644 include/linux/arm-smccc.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH v2 1/3] ARM: import arm-smccc code from Linux 4.11-rc6
  2017-04-13  2:39 [U-Boot] [PATCH v2 0/3] ARM: support System Reset via PSCI Masahiro Yamada
@ 2017-04-13  2:39 ` Masahiro Yamada
  2017-04-13  2:39 ` [U-Boot] [PATCH v2 2/3] ARM: adjust arm-smccc code for use in U-Boot Masahiro Yamada
  2017-04-13  2:39 ` [U-Boot] [PATCH v2 3/3] sysreset: psci: support system reset in a generic way with PSCI Masahiro Yamada
  2 siblings, 0 replies; 7+ messages in thread
From: Masahiro Yamada @ 2017-04-13  2:39 UTC (permalink / raw)
  To: u-boot

Imports ARM SMC Calling Convention code from Linux 4.11-rc6.
The files have been copied as follows:

[Linux]                           [U-Boot]
arch/arm/kernel/smccc-call.S   -> arch/arm/cpu/armv7/smccc-call.S
arch/arm64/kernel/smccc-call.S -> arch/arm/cpu/armv8/smccc-call.S
arch/arm/include/asm/opcodes*  -> arch/arm/include/asm/opcodes*
include/linux/arm-smccc.h      -> include/linux/arm-smccc.h

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v2:
  - split into separate patches "import" and "adjust"

 arch/arm/cpu/armv7/smccc-call.S     |  64 ++++++++++
 arch/arm/cpu/armv8/smccc-call.S     |  52 ++++++++
 arch/arm/include/asm/opcodes-sec.h  |  24 ++++
 arch/arm/include/asm/opcodes-virt.h |  39 ++++++
 arch/arm/include/asm/opcodes.h      | 231 ++++++++++++++++++++++++++++++++++++
 include/linux/arm-smccc.h           | 134 +++++++++++++++++++++
 6 files changed, 544 insertions(+)
 create mode 100644 arch/arm/cpu/armv7/smccc-call.S
 create mode 100644 arch/arm/cpu/armv8/smccc-call.S
 create mode 100644 arch/arm/include/asm/opcodes-sec.h
 create mode 100644 arch/arm/include/asm/opcodes-virt.h
 create mode 100644 arch/arm/include/asm/opcodes.h
 create mode 100644 include/linux/arm-smccc.h

diff --git a/arch/arm/cpu/armv7/smccc-call.S b/arch/arm/cpu/armv7/smccc-call.S
new file mode 100644
index 0000000..e5d4306
--- /dev/null
+++ b/arch/arm/cpu/armv7/smccc-call.S
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/linkage.h>
+
+#include <asm/opcodes-sec.h>
+#include <asm/opcodes-virt.h>
+#include <asm/unwind.h>
+
+	/*
+	 * Wrap c macros in asm macros to delay expansion until after the
+	 * SMCCC asm macro is expanded.
+	 */
+	.macro SMCCC_SMC
+	__SMC(0)
+	.endm
+
+	.macro SMCCC_HVC
+	__HVC(0)
+	.endm
+
+	.macro SMCCC instr
+UNWIND(	.fnstart)
+	mov	r12, sp
+	push	{r4-r7}
+UNWIND(	.save	{r4-r7})
+	ldm	r12, {r4-r7}
+	\instr
+	pop	{r4-r7}
+	ldr	r12, [sp, #(4 * 4)]
+	stm	r12, {r0-r3}
+	bx	lr
+UNWIND(	.fnend)
+	.endm
+
+/*
+ * void smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
+ *		  unsigned long a3, unsigned long a4, unsigned long a5,
+ *		  unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
+ *		  struct arm_smccc_quirk *quirk)
+ */
+ENTRY(__arm_smccc_smc)
+	SMCCC SMCCC_SMC
+ENDPROC(__arm_smccc_smc)
+
+/*
+ * void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
+ *		  unsigned long a3, unsigned long a4, unsigned long a5,
+ *		  unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
+ *		  struct arm_smccc_quirk *quirk)
+ */
+ENTRY(__arm_smccc_hvc)
+	SMCCC SMCCC_HVC
+ENDPROC(__arm_smccc_hvc)
diff --git a/arch/arm/cpu/armv8/smccc-call.S b/arch/arm/cpu/armv8/smccc-call.S
new file mode 100644
index 0000000..6252234
--- /dev/null
+++ b/arch/arm/cpu/armv8/smccc-call.S
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/linkage.h>
+#include <linux/arm-smccc.h>
+#include <asm/asm-offsets.h>
+
+	.macro SMCCC instr
+	.cfi_startproc
+	\instr	#0
+	ldr	x4, [sp]
+	stp	x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS]
+	stp	x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS]
+	ldr	x4, [sp, #8]
+	cbz	x4, 1f /* no quirk structure */
+	ldr	x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS]
+	cmp	x9, #ARM_SMCCC_QUIRK_QCOM_A6
+	b.ne	1f
+	str	x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS]
+1:	ret
+	.cfi_endproc
+	.endm
+
+/*
+ * void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
+ *		  unsigned long a3, unsigned long a4, unsigned long a5,
+ *		  unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
+ *		  struct arm_smccc_quirk *quirk)
+ */
+ENTRY(__arm_smccc_smc)
+	SMCCC	smc
+ENDPROC(__arm_smccc_smc)
+
+/*
+ * void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
+ *		  unsigned long a3, unsigned long a4, unsigned long a5,
+ *		  unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
+ *		  struct arm_smccc_quirk *quirk)
+ */
+ENTRY(__arm_smccc_hvc)
+	SMCCC	hvc
+ENDPROC(__arm_smccc_hvc)
diff --git a/arch/arm/include/asm/opcodes-sec.h b/arch/arm/include/asm/opcodes-sec.h
new file mode 100644
index 0000000..bc3a917
--- /dev/null
+++ b/arch/arm/include/asm/opcodes-sec.h
@@ -0,0 +1,24 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#ifndef __ASM_ARM_OPCODES_SEC_H
+#define __ASM_ARM_OPCODES_SEC_H
+
+#include <asm/opcodes.h>
+
+#define __SMC(imm4) __inst_arm_thumb32(					\
+	0xE1600070 | (((imm4) & 0xF) << 0),				\
+	0xF7F08000 | (((imm4) & 0xF) << 16)				\
+)
+
+#endif /* __ASM_ARM_OPCODES_SEC_H */
diff --git a/arch/arm/include/asm/opcodes-virt.h b/arch/arm/include/asm/opcodes-virt.h
new file mode 100644
index 0000000..efcfdf9
--- /dev/null
+++ b/arch/arm/include/asm/opcodes-virt.h
@@ -0,0 +1,39 @@
+/*
+ * opcodes-virt.h: Opcode definitions for the ARM virtualization extensions
+ * Copyright (C) 2012  Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef __ASM_ARM_OPCODES_VIRT_H
+#define __ASM_ARM_OPCODES_VIRT_H
+
+#include <asm/opcodes.h>
+
+#define __HVC(imm16) __inst_arm_thumb32(				\
+	0xE1400070 | (((imm16) & 0xFFF0) << 4) | ((imm16) & 0x000F),	\
+	0xF7E08000 | (((imm16) & 0xF000) << 4) | ((imm16) & 0x0FFF)	\
+)
+
+#define __ERET	__inst_arm_thumb32(					\
+	0xE160006E,							\
+	0xF3DE8F00							\
+)
+
+#define __MSR_ELR_HYP(regnum)	__inst_arm_thumb32(			\
+	0xE12EF300 | regnum,						\
+	0xF3808E30 | (regnum << 16)					\
+)
+
+#endif /* ! __ASM_ARM_OPCODES_VIRT_H */
diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h
new file mode 100644
index 0000000..e796c59
--- /dev/null
+++ b/arch/arm/include/asm/opcodes.h
@@ -0,0 +1,231 @@
+/*
+ *  arch/arm/include/asm/opcodes.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_OPCODES_H
+#define __ASM_ARM_OPCODES_H
+
+#ifndef __ASSEMBLY__
+#include <linux/linkage.h>
+extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr);
+#endif
+
+#define ARM_OPCODE_CONDTEST_FAIL   0
+#define ARM_OPCODE_CONDTEST_PASS   1
+#define ARM_OPCODE_CONDTEST_UNCOND 2
+
+
+/*
+ * Assembler opcode byteswap helpers.
+ * These are only intended for use by this header: don't use them directly,
+ * because they will be suboptimal in most cases.
+ */
+#define ___asm_opcode_swab32(x) (	\
+	  (((x) << 24) & 0xFF000000)	\
+	| (((x) <<  8) & 0x00FF0000)	\
+	| (((x) >>  8) & 0x0000FF00)	\
+	| (((x) >> 24) & 0x000000FF)	\
+)
+#define ___asm_opcode_swab16(x) (	\
+	  (((x) << 8) & 0xFF00)		\
+	| (((x) >> 8) & 0x00FF)		\
+)
+#define ___asm_opcode_swahb32(x) (	\
+	  (((x) << 8) & 0xFF00FF00)	\
+	| (((x) >> 8) & 0x00FF00FF)	\
+)
+#define ___asm_opcode_swahw32(x) (	\
+	  (((x) << 16) & 0xFFFF0000)	\
+	| (((x) >> 16) & 0x0000FFFF)	\
+)
+#define ___asm_opcode_identity32(x) ((x) & 0xFFFFFFFF)
+#define ___asm_opcode_identity16(x) ((x) & 0xFFFF)
+
+
+/*
+ * Opcode byteswap helpers
+ *
+ * These macros help with converting instructions between a canonical integer
+ * format and in-memory representation, in an endianness-agnostic manner.
+ *
+ * __mem_to_opcode_*() convert from in-memory representation to canonical form.
+ * __opcode_to_mem_*() convert from canonical form to in-memory representation.
+ *
+ *
+ * Canonical instruction representation:
+ *
+ *	ARM:		0xKKLLMMNN
+ *	Thumb 16-bit:	0x0000KKLL, where KK < 0xE8
+ *	Thumb 32-bit:	0xKKLLMMNN, where KK >= 0xE8
+ *
+ * There is no way to distinguish an ARM instruction in canonical representation
+ * from a Thumb instruction (just as these cannot be distinguished in memory).
+ * Where this distinction is important, it needs to be tracked separately.
+ *
+ * Note that values in the range 0x0000E800..0xE7FFFFFF intentionally do not
+ * represent any valid Thumb-2 instruction.  For this range,
+ * __opcode_is_thumb32() and __opcode_is_thumb16() will both be false.
+ *
+ * The ___asm variants are intended only for use by this header, in situations
+ * involving inline assembler.  For .S files, the normal __opcode_*() macros
+ * should do the right thing.
+ */
+#ifdef __ASSEMBLY__
+
+#define ___opcode_swab32(x) ___asm_opcode_swab32(x)
+#define ___opcode_swab16(x) ___asm_opcode_swab16(x)
+#define ___opcode_swahb32(x) ___asm_opcode_swahb32(x)
+#define ___opcode_swahw32(x) ___asm_opcode_swahw32(x)
+#define ___opcode_identity32(x) ___asm_opcode_identity32(x)
+#define ___opcode_identity16(x) ___asm_opcode_identity16(x)
+
+#else /* ! __ASSEMBLY__ */
+
+#include <linux/types.h>
+#include <linux/swab.h>
+
+#define ___opcode_swab32(x) swab32(x)
+#define ___opcode_swab16(x) swab16(x)
+#define ___opcode_swahb32(x) swahb32(x)
+#define ___opcode_swahw32(x) swahw32(x)
+#define ___opcode_identity32(x) ((u32)(x))
+#define ___opcode_identity16(x) ((u16)(x))
+
+#endif /* ! __ASSEMBLY__ */
+
+
+#ifdef CONFIG_CPU_ENDIAN_BE8
+
+#define __opcode_to_mem_arm(x) ___opcode_swab32(x)
+#define __opcode_to_mem_thumb16(x) ___opcode_swab16(x)
+#define __opcode_to_mem_thumb32(x) ___opcode_swahb32(x)
+#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_swab32(x)
+#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_swab16(x)
+#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahb32(x)
+
+#else /* ! CONFIG_CPU_ENDIAN_BE8 */
+
+#define __opcode_to_mem_arm(x) ___opcode_identity32(x)
+#define __opcode_to_mem_thumb16(x) ___opcode_identity16(x)
+#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_identity32(x)
+#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_identity16(x)
+#ifndef CONFIG_CPU_ENDIAN_BE32
+/*
+ * On BE32 systems, using 32-bit accesses to store Thumb instructions will not
+ * work in all cases, due to alignment constraints.  For now, a correct
+ * version is not provided for BE32.
+ */
+#define __opcode_to_mem_thumb32(x) ___opcode_swahw32(x)
+#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahw32(x)
+#endif
+
+#endif /* ! CONFIG_CPU_ENDIAN_BE8 */
+
+#define __mem_to_opcode_arm(x) __opcode_to_mem_arm(x)
+#define __mem_to_opcode_thumb16(x) __opcode_to_mem_thumb16(x)
+#ifndef CONFIG_CPU_ENDIAN_BE32
+#define __mem_to_opcode_thumb32(x) __opcode_to_mem_thumb32(x)
+#endif
+
+/* Operations specific to Thumb opcodes */
+
+/* Instruction size checks: */
+#define __opcode_is_thumb32(x) (		\
+	   ((x) & 0xF8000000) == 0xE8000000	\
+	|| ((x) & 0xF0000000) == 0xF0000000	\
+)
+#define __opcode_is_thumb16(x) (					\
+	   ((x) & 0xFFFF0000) == 0					\
+	&& !(((x) & 0xF800) == 0xE800 || ((x) & 0xF000) == 0xF000)	\
+)
+
+/* Operations to construct or split 32-bit Thumb instructions: */
+#define __opcode_thumb32_first(x) (___opcode_identity16((x) >> 16))
+#define __opcode_thumb32_second(x) (___opcode_identity16(x))
+#define __opcode_thumb32_compose(first, second) (			\
+	  (___opcode_identity32(___opcode_identity16(first)) << 16)	\
+	| ___opcode_identity32(___opcode_identity16(second))		\
+)
+#define ___asm_opcode_thumb32_first(x) (___asm_opcode_identity16((x) >> 16))
+#define ___asm_opcode_thumb32_second(x) (___asm_opcode_identity16(x))
+#define ___asm_opcode_thumb32_compose(first, second) (			    \
+	  (___asm_opcode_identity32(___asm_opcode_identity16(first)) << 16) \
+	| ___asm_opcode_identity32(___asm_opcode_identity16(second))	    \
+)
+
+/*
+ * Opcode injection helpers
+ *
+ * In rare cases it is necessary to assemble an opcode which the
+ * assembler does not support directly, or which would normally be
+ * rejected because of the CFLAGS or AFLAGS used to build the affected
+ * file.
+ *
+ * Before using these macros, consider carefully whether it is feasible
+ * instead to change the build flags for your file, or whether it really
+ * makes sense to support old assembler versions when building that
+ * particular kernel feature.
+ *
+ * The macros defined here should only be used where there is no viable
+ * alternative.
+ *
+ *
+ * __inst_arm(x): emit the specified ARM opcode
+ * __inst_thumb16(x): emit the specified 16-bit Thumb opcode
+ * __inst_thumb32(x): emit the specified 32-bit Thumb opcode
+ *
+ * __inst_arm_thumb16(arm, thumb): emit either the specified arm or
+ *	16-bit Thumb opcode, depending on whether an ARM or Thumb-2
+ *	kernel is being built
+ *
+ * __inst_arm_thumb32(arm, thumb): emit either the specified arm or
+ *	32-bit Thumb opcode, depending on whether an ARM or Thumb-2
+ *	kernel is being built
+ *
+ *
+ * Note that using these macros directly is poor practice.  Instead, you
+ * should use them to define human-readable wrapper macros to encode the
+ * instructions that you care about.  In code which might run on ARMv7 or
+ * above, you can usually use the __inst_arm_thumb{16,32} macros to
+ * specify the ARM and Thumb alternatives at the same time.  This ensures
+ * that the correct opcode gets emitted depending on the instruction set
+ * used for the kernel build.
+ *
+ * Look@opcodes-virt.h for an example of how to use these macros.
+ */
+#include <linux/stringify.h>
+
+#define __inst_arm(x) ___inst_arm(___asm_opcode_to_mem_arm(x))
+#define __inst_thumb32(x) ___inst_thumb32(				\
+	___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_first(x)),	\
+	___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_second(x))	\
+)
+#define __inst_thumb16(x) ___inst_thumb16(___asm_opcode_to_mem_thumb16(x))
+
+#ifdef CONFIG_THUMB2_KERNEL
+#define __inst_arm_thumb16(arm_opcode, thumb_opcode) \
+	__inst_thumb16(thumb_opcode)
+#define __inst_arm_thumb32(arm_opcode, thumb_opcode) \
+	__inst_thumb32(thumb_opcode)
+#else
+#define __inst_arm_thumb16(arm_opcode, thumb_opcode) __inst_arm(arm_opcode)
+#define __inst_arm_thumb32(arm_opcode, thumb_opcode) __inst_arm(arm_opcode)
+#endif
+
+/* Helpers for the helpers.  Don't use these directly. */
+#ifdef __ASSEMBLY__
+#define ___inst_arm(x) .long x
+#define ___inst_thumb16(x) .short x
+#define ___inst_thumb32(first, second) .short first, second
+#else
+#define ___inst_arm(x) ".long " __stringify(x) "\n\t"
+#define ___inst_thumb16(x) ".short " __stringify(x) "\n\t"
+#define ___inst_thumb32(first, second) \
+	".short " __stringify(first) ", " __stringify(second) "\n\t"
+#endif
+
+#endif /* __ASM_ARM_OPCODES_H */
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
new file mode 100644
index 0000000..4c5bca3
--- /dev/null
+++ b/include/linux/arm-smccc.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __LINUX_ARM_SMCCC_H
+#define __LINUX_ARM_SMCCC_H
+
+/*
+ * This file provides common defines for ARM SMC Calling Convention as
+ * specified in
+ * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
+ */
+
+#define ARM_SMCCC_STD_CALL		0
+#define ARM_SMCCC_FAST_CALL		1
+#define ARM_SMCCC_TYPE_SHIFT		31
+
+#define ARM_SMCCC_SMC_32		0
+#define ARM_SMCCC_SMC_64		1
+#define ARM_SMCCC_CALL_CONV_SHIFT	30
+
+#define ARM_SMCCC_OWNER_MASK		0x3F
+#define ARM_SMCCC_OWNER_SHIFT		24
+
+#define ARM_SMCCC_FUNC_MASK		0xFFFF
+
+#define ARM_SMCCC_IS_FAST_CALL(smc_val)	\
+	((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
+#define ARM_SMCCC_IS_64(smc_val) \
+	((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
+#define ARM_SMCCC_FUNC_NUM(smc_val)	((smc_val) & ARM_SMCCC_FUNC_MASK)
+#define ARM_SMCCC_OWNER_NUM(smc_val) \
+	(((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
+
+#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
+	(((type) << ARM_SMCCC_TYPE_SHIFT) | \
+	((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
+	(((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
+	((func_num) & ARM_SMCCC_FUNC_MASK))
+
+#define ARM_SMCCC_OWNER_ARCH		0
+#define ARM_SMCCC_OWNER_CPU		1
+#define ARM_SMCCC_OWNER_SIP		2
+#define ARM_SMCCC_OWNER_OEM		3
+#define ARM_SMCCC_OWNER_STANDARD	4
+#define ARM_SMCCC_OWNER_TRUSTED_APP	48
+#define ARM_SMCCC_OWNER_TRUSTED_APP_END	49
+#define ARM_SMCCC_OWNER_TRUSTED_OS	50
+#define ARM_SMCCC_OWNER_TRUSTED_OS_END	63
+
+#define ARM_SMCCC_QUIRK_NONE		0
+#define ARM_SMCCC_QUIRK_QCOM_A6		1 /* Save/restore register a6 */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/linkage.h>
+#include <linux/types.h>
+/**
+ * struct arm_smccc_res - Result from SMC/HVC call
+ * @a0-a3 result values from registers 0 to 3
+ */
+struct arm_smccc_res {
+	unsigned long a0;
+	unsigned long a1;
+	unsigned long a2;
+	unsigned long a3;
+};
+
+/**
+ * struct arm_smccc_quirk - Contains quirk information
+ * @id: quirk identification
+ * @state: quirk specific information
+ * @a6: Qualcomm quirk entry for returning post-smc call contents of a6
+ */
+struct arm_smccc_quirk {
+	int	id;
+	union {
+		unsigned long a6;
+	} state;
+};
+
+/**
+ * __arm_smccc_smc() - make SMC calls
+ * @a0-a7: arguments passed in registers 0 to 7
+ * @res: result values from registers 0 to 3
+ * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
+ *
+ * This function is used to make SMC calls following SMC Calling Convention.
+ * The content of the supplied param are copied to registers 0 to 7 prior
+ * to the SMC instruction. The return values are updated with the content
+ * from register 0 to 3 on return from the SMC instruction.  An optional
+ * quirk structure provides vendor specific behavior.
+ */
+asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
+			unsigned long a2, unsigned long a3, unsigned long a4,
+			unsigned long a5, unsigned long a6, unsigned long a7,
+			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
+
+/**
+ * __arm_smccc_hvc() - make HVC calls
+ * @a0-a7: arguments passed in registers 0 to 7
+ * @res: result values from registers 0 to 3
+ * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
+ *
+ * This function is used to make HVC calls following SMC Calling
+ * Convention.  The content of the supplied param are copied to registers 0
+ * to 7 prior to the HVC instruction. The return values are updated with
+ * the content from register 0 to 3 on return from the HVC instruction.  An
+ * optional quirk structure provides vendor specific behavior.
+ */
+asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
+			unsigned long a2, unsigned long a3, unsigned long a4,
+			unsigned long a5, unsigned long a6, unsigned long a7,
+			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
+
+#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
+
+#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
+
+#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
+
+#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
+
+#endif /*__ASSEMBLY__*/
+#endif /*__LINUX_ARM_SMCCC_H*/
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH v2 2/3] ARM: adjust arm-smccc code for use in U-Boot
  2017-04-13  2:39 [U-Boot] [PATCH v2 0/3] ARM: support System Reset via PSCI Masahiro Yamada
  2017-04-13  2:39 ` [U-Boot] [PATCH v2 1/3] ARM: import arm-smccc code from Linux 4.11-rc6 Masahiro Yamada
@ 2017-04-13  2:39 ` Masahiro Yamada
  2017-04-13 13:57   ` Masahiro Yamada
  2017-04-13  2:39 ` [U-Boot] [PATCH v2 3/3] sysreset: psci: support system reset in a generic way with PSCI Masahiro Yamada
  2 siblings, 1 reply; 7+ messages in thread
From: Masahiro Yamada @ 2017-04-13  2:39 UTC (permalink / raw)
  To: u-boot

Adjust ARM SMC Calling Convention code for U-Boot:
  - Replace the license block with SPDX
  - Change path to asm-offsets.h
  - Define UNWIND() as no-op
  - Add Kconfig entry
  - Add asm-offsets

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v2:
  - split into separate patches "import" and "adjust"

 arch/arm/Kconfig                    |  8 ++++++++
 arch/arm/cpu/armv7/Makefile         |  1 +
 arch/arm/cpu/armv7/smccc-call.S     | 12 ++----------
 arch/arm/cpu/armv8/Makefile         |  2 ++
 arch/arm/cpu/armv8/smccc-call.S     | 12 ++----------
 arch/arm/include/asm/opcodes-sec.h  | 11 ++---------
 arch/arm/include/asm/opcodes-virt.h | 14 +-------------
 arch/arm/include/asm/opcodes.h      |  4 +---
 arch/arm/lib/asm-offsets.c          |  8 ++++++++
 include/linux/arm-smccc.h           | 10 +---------
 10 files changed, 28 insertions(+), 54 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7b20750..84744ef 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -174,6 +174,14 @@ config SYS_CACHELINE_SIZE
 	default 64 if SYS_CACHE_SHIFT_6
 	default 32 if SYS_CACHE_SHIFT_5
 
+config ARM_SMCCC
+	bool "Support for ARM SMC Calling Convention (SMCCC)"
+	depends on CPU_V7 || ARM64
+	help
+	  Say Y here if you want to enable ARM SMC Calling Convention.
+	  This should be enabled if U-Boot needs to communicate with system
+	  firmware (for example, PSCI) according to SMCCC.
+
 config SEMIHOSTING
 	bool "support boot from semihosting"
 	help
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
index 02e8778..3a9913a 100644
--- a/arch/arm/cpu/armv7/Makefile
+++ b/arch/arm/cpu/armv7/Makefile
@@ -18,6 +18,7 @@ obj-y	+= lowlevel_init.o
 endif
 endif
 
+obj-$(CONFIG_ARM_SMCCC)		+= smccc-call.o
 obj-$(CONFIG_ARMV7_NONSEC)	+= nonsec_virt.o virt-v7.o virt-dt.o
 obj-$(CONFIG_ARMV7_PSCI)	+= psci.o psci-common.o
 
diff --git a/arch/arm/cpu/armv7/smccc-call.S b/arch/arm/cpu/armv7/smccc-call.S
index e5d4306..c2fdbad 100644
--- a/arch/arm/cpu/armv7/smccc-call.S
+++ b/arch/arm/cpu/armv7/smccc-call.S
@@ -1,22 +1,14 @@
 /*
  * Copyright (c) 2015, Linaro Limited
  *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
+ * SPDX-License-Identifier:	GPL-2.0
  */
 #include <linux/linkage.h>
 
 #include <asm/opcodes-sec.h>
 #include <asm/opcodes-virt.h>
-#include <asm/unwind.h>
 
+#define UNWIND(x...)
 	/*
 	 * Wrap c macros in asm macros to delay expansion until after the
 	 * SMCCC asm macro is expanded.
diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
index 65915ee..c447085 100644
--- a/arch/arm/cpu/armv8/Makefile
+++ b/arch/arm/cpu/armv8/Makefile
@@ -16,6 +16,8 @@ obj-y	+= tlb.o
 obj-y	+= transition.o
 obj-y	+= fwcall.o
 obj-y	+= cpu-dt.o
+obj-$(CONFIG_ARM_SMCCC)		+= smccc-call.o
+
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_ARMV8_SPIN_TABLE) += spin_table.o spin_table_v8.o
 endif
diff --git a/arch/arm/cpu/armv8/smccc-call.S b/arch/arm/cpu/armv8/smccc-call.S
index 6252234..bbb6cba 100644
--- a/arch/arm/cpu/armv8/smccc-call.S
+++ b/arch/arm/cpu/armv8/smccc-call.S
@@ -1,19 +1,11 @@
 /*
  * Copyright (c) 2015, Linaro Limited
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
+ * SPDX-License-Identifier:	GPL-2.0
  */
 #include <linux/linkage.h>
 #include <linux/arm-smccc.h>
-#include <asm/asm-offsets.h>
+#include <generated/asm-offsets.h>
 
 	.macro SMCCC instr
 	.cfi_startproc
diff --git a/arch/arm/include/asm/opcodes-sec.h b/arch/arm/include/asm/opcodes-sec.h
index bc3a917..16dee8f 100644
--- a/arch/arm/include/asm/opcodes-sec.h
+++ b/arch/arm/include/asm/opcodes-sec.h
@@ -1,14 +1,7 @@
 /*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
  * Copyright (C) 2012 ARM Limited
+ *
+ * SPDX-License-Identifier:	GPL-2.0
  */
 
 #ifndef __ASM_ARM_OPCODES_SEC_H
diff --git a/arch/arm/include/asm/opcodes-virt.h b/arch/arm/include/asm/opcodes-virt.h
index efcfdf9..923f257 100644
--- a/arch/arm/include/asm/opcodes-virt.h
+++ b/arch/arm/include/asm/opcodes-virt.h
@@ -2,19 +2,7 @@
  * opcodes-virt.h: Opcode definitions for the ARM virtualization extensions
  * Copyright (C) 2012  Linaro Limited
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * SPDX-License-Identifier:	GPL-2.0
  */
 #ifndef __ASM_ARM_OPCODES_VIRT_H
 #define __ASM_ARM_OPCODES_VIRT_H
diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h
index e796c59..199f0ba 100644
--- a/arch/arm/include/asm/opcodes.h
+++ b/arch/arm/include/asm/opcodes.h
@@ -1,9 +1,7 @@
 /*
  *  arch/arm/include/asm/opcodes.h
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * SPDX-License-Identifier:	GPL-2.0
  */
 
 #ifndef __ASM_ARM_OPCODES_H
diff --git a/arch/arm/lib/asm-offsets.c b/arch/arm/lib/asm-offsets.c
index e5bcaea..d620dc0 100644
--- a/arch/arm/lib/asm-offsets.c
+++ b/arch/arm/lib/asm-offsets.c
@@ -14,6 +14,7 @@
 
 #include <common.h>
 #include <linux/kbuild.h>
+#include <linux/arm-smccc.h>
 
 #if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX35) \
 	|| defined(CONFIG_MX51) || defined(CONFIG_MX53)
@@ -198,5 +199,12 @@ int main(void)
 	DEFINE(PLL_DP_HFS_MFN, offsetof(struct dpll, dp_hfs_mfn));
 #endif
 
+#ifdef CONFIG_ARM_SMCCC
+	DEFINE(ARM_SMCCC_RES_X0_OFFS, offsetof(struct arm_smccc_res, a0));
+	DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2));
+	DEFINE(ARM_SMCCC_QUIRK_ID_OFFS, offsetof(struct arm_smccc_quirk, id));
+	DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS, offsetof(struct arm_smccc_quirk, state));
+#endif
+
 	return 0;
 }
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 4c5bca3..28e61ce 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -1,15 +1,7 @@
 /*
  * Copyright (c) 2015, Linaro Limited
  *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
+ * SPDX-License-Identifier:	GPL-2.0
  */
 #ifndef __LINUX_ARM_SMCCC_H
 #define __LINUX_ARM_SMCCC_H
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH v2 3/3] sysreset: psci: support system reset in a generic way with PSCI
  2017-04-13  2:39 [U-Boot] [PATCH v2 0/3] ARM: support System Reset via PSCI Masahiro Yamada
  2017-04-13  2:39 ` [U-Boot] [PATCH v2 1/3] ARM: import arm-smccc code from Linux 4.11-rc6 Masahiro Yamada
  2017-04-13  2:39 ` [U-Boot] [PATCH v2 2/3] ARM: adjust arm-smccc code for use in U-Boot Masahiro Yamada
@ 2017-04-13  2:39 ` Masahiro Yamada
  2017-04-16 19:31   ` Simon Glass
  2 siblings, 1 reply; 7+ messages in thread
From: Masahiro Yamada @ 2017-04-13  2:39 UTC (permalink / raw)
  To: u-boot

If the system is running PSCI firmware, the System Reset function
(func ID: 0x80000009) is supposed to be handled by PSCI, that is,
the SoC/board specific reset implementation should be moved to PSCI.
U-Boot should call the PSCI service according to the arm-smccc
manner.

The arm-smccc is supported on ARMv7 or later.  Especially, ARMv8
generation SoCs are likely to run ARM Trusted Firmware BL31.  In
this case, U-Boot is a non-secure world boot loader, so it should
not be able to reset the system directly.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v2: None

 arch/arm/Kconfig                   |  1 +
 drivers/Kconfig                    |  2 +
 drivers/Makefile                   |  5 +-
 drivers/firmware/Kconfig           |  6 +++
 drivers/firmware/Makefile          |  2 +
 drivers/firmware/firmware-uclass.c | 11 +++++
 drivers/firmware/psci.c            | 94 ++++++++++++++++++++++++++++++++++++++
 drivers/sysreset/Kconfig           | 10 ++++
 drivers/sysreset/Makefile          |  1 +
 drivers/sysreset/sysreset_psci.c   | 41 +++++++++++++++++
 include/dm/uclass-id.h             |  1 +
 include/linux/psci.h               | 13 ++++++
 12 files changed, 185 insertions(+), 2 deletions(-)
 create mode 100644 drivers/firmware/Kconfig
 create mode 100644 drivers/firmware/Makefile
 create mode 100644 drivers/firmware/firmware-uclass.c
 create mode 100644 drivers/firmware/psci.c
 create mode 100644 drivers/sysreset/sysreset_psci.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 84744ef..64984dc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -177,6 +177,7 @@ config SYS_CACHELINE_SIZE
 config ARM_SMCCC
 	bool "Support for ARM SMC Calling Convention (SMCCC)"
 	depends on CPU_V7 || ARM64
+	select ARM_PSCI_FW
 	help
 	  Say Y here if you want to enable ARM SMC Calling Convention.
 	  This should be enabled if U-Boot needs to communicate with system
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 0e5d97d..d0a36ab 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -22,6 +22,8 @@ source "drivers/dfu/Kconfig"
 
 source "drivers/dma/Kconfig"
 
+source "drivers/firmware/Kconfig"
+
 source "drivers/fpga/Kconfig"
 
 source "drivers/gpio/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 5d8baa5..4a4b237 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -23,7 +23,7 @@ obj-$(CONFIG_SPL_SERIAL_SUPPORT) += serial/
 obj-$(CONFIG_SPL_SPI_SUPPORT) += spi/
 obj-$(CONFIG_SPL_POWER_SUPPORT) += power/ power/pmic/
 obj-$(CONFIG_SPL_POWER_SUPPORT) += power/regulator/
-obj-$(CONFIG_SPL_DRIVERS_MISC_SUPPORT) += misc/ sysreset/
+obj-$(CONFIG_SPL_DRIVERS_MISC_SUPPORT) += misc/ sysreset/ firmware/
 obj-$(CONFIG_SPL_MTD_SUPPORT) += mtd/
 obj-$(CONFIG_SPL_NAND_SUPPORT) += mtd/nand/
 obj-$(CONFIG_SPL_ONENAND_SUPPORT) += mtd/onenand/
@@ -52,7 +52,7 @@ endif
 ifdef CONFIG_TPL_BUILD
 
 obj-$(CONFIG_TPL_I2C_SUPPORT) += i2c/
-obj-$(CONFIG_TPL_DRIVERS_MISC_SUPPORT) += misc/ sysreset/
+obj-$(CONFIG_TPL_DRIVERS_MISC_SUPPORT) += misc/ sysreset/ firmware/
 obj-$(CONFIG_TPL_MMC_SUPPORT) += mmc/
 obj-$(CONFIG_TPL_MPC8XXX_INIT_DDR_SUPPORT) += ddr/fsl/
 obj-$(CONFIG_TPL_NAND_SUPPORT) += mtd/nand/
@@ -71,6 +71,7 @@ obj-y += block/
 obj-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount/
 obj-$(CONFIG_CPU) += cpu/
 obj-y += crypto/
+obj-y += firmware/
 obj-$(CONFIG_FPGA) += fpga/
 obj-y += hwmon/
 obj-y += misc/
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
new file mode 100644
index 0000000..4c32426
--- /dev/null
+++ b/drivers/firmware/Kconfig
@@ -0,0 +1,6 @@
+config FIRMWARE
+	bool
+
+config ARM_PSCI_FW
+	bool
+	select FIRMWARE
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
new file mode 100644
index 0000000..b208255
--- /dev/null
+++ b/drivers/firmware/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_FIRMWARE)		+= firmware-uclass.o
+obj-$(CONFIG_ARM_PSCI_FW)	+= psci.o
diff --git a/drivers/firmware/firmware-uclass.c b/drivers/firmware/firmware-uclass.c
new file mode 100644
index 0000000..01b6a44
--- /dev/null
+++ b/drivers/firmware/firmware-uclass.c
@@ -0,0 +1,11 @@
+/*
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <dm/uclass.h>
+
+/* Firmware access is platform-dependent.  No generic code in uclass */
+UCLASS_DRIVER(firmware) = {
+	.id		= UCLASS_FIRMWARE,
+	.name		= "firmware",
+};
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
new file mode 100644
index 0000000..40fba64
--- /dev/null
+++ b/drivers/firmware/psci.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2017 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * Based on drivers/firmware/psci.c from Linux:
+ * Copyright (C) 2015 ARM Limited
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm/device.h>
+#include <dm/lists.h>
+#include <libfdt.h>
+#include <linux/arm-smccc.h>
+#include <linux/errno.h>
+#include <linux/psci.h>
+
+psci_fn *invoke_psci_fn;
+
+static unsigned long __invoke_psci_fn_hvc(unsigned long function_id,
+			unsigned long arg0, unsigned long arg1,
+			unsigned long arg2)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_hvc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
+	return res.a0;
+}
+
+static unsigned long __invoke_psci_fn_smc(unsigned long function_id,
+			unsigned long arg0, unsigned long arg1,
+			unsigned long arg2)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
+	return res.a0;
+}
+
+static int psci_bind(struct udevice *dev)
+{
+	/* No SYSTEM_RESET support for PSCI 0.1 */
+	if (of_device_is_compatible(dev, "arm,psci-0.2") ||
+	    of_device_is_compatible(dev, "arm,psci-1.0")) {
+		int ret;
+
+		/* bind psci-sysreset optionally */
+		ret = device_bind_driver(dev, "psci-sysreset", "psci-sysreset",
+					 NULL);
+		if (ret)
+			debug("PSCI System Reset was not bound.\n");
+	}
+
+	return 0;
+}
+
+static int psci_probe(struct udevice *dev)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	const char *method;
+
+	method = fdt_stringlist_get(gd->fdt_blob, dev->of_offset, "method", 0,
+				    NULL);
+	if (!method) {
+		printf("missing \"method\" property\n");
+		return -ENXIO;
+	}
+
+	if (!strcmp("hvc", method)) {
+		invoke_psci_fn = __invoke_psci_fn_hvc;
+	} else if (!strcmp("smc", method)) {
+		invoke_psci_fn = __invoke_psci_fn_smc;
+	} else {
+		printf("invalid \"method\" property: %s\n", method);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct udevice_id psci_of_match[] = {
+	{ .compatible = "arm,psci" },
+	{ .compatible = "arm,psci-0.2" },
+	{ .compatible = "arm,psci-1.0" },
+	{},
+};
+
+U_BOOT_DRIVER(psci) = {
+	.name = "psci",
+	.id = UCLASS_FIRMWARE,
+	.of_match = psci_of_match,
+	.bind = psci_bind,
+	.probe = psci_probe,
+};
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index 05a37b9..9664630 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -13,4 +13,14 @@ config SYSRESET
 	  to effect a reset. The uclass will try all available drivers when
 	  reset_walk() is called.
 
+if SYSRESET
+
+config SYSRESET_PSCI
+	bool "Enable support for PSCI System Reset"
+	depends on ARM_PSCI_FW
+	help
+	  Enable PSCI SYSTEM_RESET function call.  To use this, PSCI firmware
+	  must be running on your system.
+
+endif
 endmenu
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index 49b8bb6..7bb8406 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -5,6 +5,7 @@
 #
 
 obj-$(CONFIG_SYSRESET) += sysreset-uclass.o
+obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
 
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_ROCKCHIP_RK3036) += sysreset_rk3036.o
diff --git a/drivers/sysreset/sysreset_psci.c b/drivers/sysreset/sysreset_psci.c
new file mode 100644
index 0000000..a4911b7
--- /dev/null
+++ b/drivers/sysreset/sysreset_psci.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <dm/device.h>
+#include <sysreset.h>
+#include <linux/errno.h>
+#include <linux/psci.h>
+
+static int psci_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+	unsigned long function_id;
+
+	switch (type) {
+	case SYSRESET_WARM:
+	case SYSRESET_COLD:
+		function_id = PSCI_0_2_FN_SYSTEM_RESET;
+		break;
+	case SYSRESET_POWER:
+		function_id = PSCI_0_2_FN_SYSTEM_OFF;
+		break;
+	default:
+		return -ENOSYS;
+	}
+
+	invoke_psci_fn(function_id, 0, 0, 0);
+
+	return -EINPROGRESS;
+}
+
+static struct sysreset_ops psci_sysreset_ops = {
+	.request = psci_sysreset_request,
+};
+
+U_BOOT_DRIVER(psci_sysreset) = {
+	.name = "psci-sysreset",
+	.id = UCLASS_SYSRESET,
+	.ops = &psci_sysreset_ops,
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 8c92d0b..1b635e4 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -35,6 +35,7 @@ enum uclass_id {
 	UCLASS_DMA,		/* Direct Memory Access */
 	UCLASS_ETH,		/* Ethernet device */
 	UCLASS_GPIO,		/* Bank of general-purpose I/O pins */
+	UCLASS_FIRMWARE,	/* Firmware */
 	UCLASS_I2C,		/* I2C bus */
 	UCLASS_I2C_EEPROM,	/* I2C EEPROM device */
 	UCLASS_I2C_GENERIC,	/* Generic I2C device */
diff --git a/include/linux/psci.h b/include/linux/psci.h
index 310d83e..8d13bd2 100644
--- a/include/linux/psci.h
+++ b/include/linux/psci.h
@@ -87,4 +87,17 @@
 #define PSCI_RET_NOT_PRESENT			-7
 #define PSCI_RET_DISABLED			-8
 
+#ifdef CONFIG_ARM_PSCI_FW
+typedef unsigned long (psci_fn)(unsigned long, unsigned long,
+				unsigned long, unsigned long);
+
+extern psci_fn *invoke_psci_fn;
+#else
+unsigned long invoke_psci_fn(unsigned long a0, unsigned long a1,
+			     unsigned long a2, unsigned long a3)
+{
+	return PSCI_RET_DISABLED;
+}
+#endif
+
 #endif /* _UAPI_LINUX_PSCI_H */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH v2 2/3] ARM: adjust arm-smccc code for use in U-Boot
  2017-04-13  2:39 ` [U-Boot] [PATCH v2 2/3] ARM: adjust arm-smccc code for use in U-Boot Masahiro Yamada
@ 2017-04-13 13:57   ` Masahiro Yamada
  0 siblings, 0 replies; 7+ messages in thread
From: Masahiro Yamada @ 2017-04-13 13:57 UTC (permalink / raw)
  To: u-boot

Self-review.

2017-04-13 11:39 GMT+09:00 Masahiro Yamada <yamada.masahiro@socionext.com>:
> Adjust ARM SMC Calling Convention code for U-Boot:
>   - Replace the license block with SPDX
>   - Change path to asm-offsets.h
>   - Define UNWIND() as no-op
>   - Add Kconfig entry
>   - Add asm-offsets
>
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>


>  #ifndef __ASM_ARM_OPCODES_SEC_H
> diff --git a/arch/arm/include/asm/opcodes-virt.h b/arch/arm/include/asm/opcodes-virt.h
> index efcfdf9..923f257 100644
> --- a/arch/arm/include/asm/opcodes-virt.h
> +++ b/arch/arm/include/asm/opcodes-virt.h
> @@ -2,19 +2,7 @@
>   * opcodes-virt.h: Opcode definitions for the ARM virtualization extensions
>   * Copyright (C) 2012  Linaro Limited
>   *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License along
> - * with this program; if not, write to the Free Software Foundation, Inc.,
> - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + * SPDX-License-Identifier:    GPL-2.0
>   */


I noticed my misconversion.

This should be GPL-2.0+




-- 
Best Regards
Masahiro Yamada

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH v2 3/3] sysreset: psci: support system reset in a generic way with PSCI
  2017-04-13  2:39 ` [U-Boot] [PATCH v2 3/3] sysreset: psci: support system reset in a generic way with PSCI Masahiro Yamada
@ 2017-04-16 19:31   ` Simon Glass
  2017-04-17  2:26     ` Masahiro Yamada
  0 siblings, 1 reply; 7+ messages in thread
From: Simon Glass @ 2017-04-16 19:31 UTC (permalink / raw)
  To: u-boot

Hi Masahiro,

On 12 April 2017 at 20:39, Masahiro Yamada
<yamada.masahiro@socionext.com> wrote:
> If the system is running PSCI firmware, the System Reset function
> (func ID: 0x80000009) is supposed to be handled by PSCI, that is,
> the SoC/board specific reset implementation should be moved to PSCI.
> U-Boot should call the PSCI service according to the arm-smccc
> manner.
>
> The arm-smccc is supported on ARMv7 or later.  Especially, ARMv8
> generation SoCs are likely to run ARM Trusted Firmware BL31.  In
> this case, U-Boot is a non-secure world boot loader, so it should
> not be able to reset the system directly.
>
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
> ---
>
> Changes in v2: None
>
>  arch/arm/Kconfig                   |  1 +
>  drivers/Kconfig                    |  2 +
>  drivers/Makefile                   |  5 +-
>  drivers/firmware/Kconfig           |  6 +++
>  drivers/firmware/Makefile          |  2 +
>  drivers/firmware/firmware-uclass.c | 11 +++++
>  drivers/firmware/psci.c            | 94 ++++++++++++++++++++++++++++++++++++++
>  drivers/sysreset/Kconfig           | 10 ++++
>  drivers/sysreset/Makefile          |  1 +
>  drivers/sysreset/sysreset_psci.c   | 41 +++++++++++++++++
>  include/dm/uclass-id.h             |  1 +
>  include/linux/psci.h               | 13 ++++++
>  12 files changed, 185 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/firmware/Kconfig
>  create mode 100644 drivers/firmware/Makefile
>  create mode 100644 drivers/firmware/firmware-uclass.c
>  create mode 100644 drivers/firmware/psci.c
>  create mode 100644 drivers/sysreset/sysreset_psci.c

Reviewed-by: Simon Glass <sjg@chromium.org>

It is not clear what the firmware uclass is for. Also there are no
operations. How about adding a header file with at least a comment in
it?

- Simon

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH v2 3/3] sysreset: psci: support system reset in a generic way with PSCI
  2017-04-16 19:31   ` Simon Glass
@ 2017-04-17  2:26     ` Masahiro Yamada
  0 siblings, 0 replies; 7+ messages in thread
From: Masahiro Yamada @ 2017-04-17  2:26 UTC (permalink / raw)
  To: u-boot

Hi Simon,


2017-04-17 4:31 GMT+09:00 Simon Glass <sjg@chromium.org>:
> Hi Masahiro,
>
> On 12 April 2017 at 20:39, Masahiro Yamada
> <yamada.masahiro@socionext.com> wrote:
>> If the system is running PSCI firmware, the System Reset function
>> (func ID: 0x80000009) is supposed to be handled by PSCI, that is,
>> the SoC/board specific reset implementation should be moved to PSCI.
>> U-Boot should call the PSCI service according to the arm-smccc
>> manner.
>>
>> The arm-smccc is supported on ARMv7 or later.  Especially, ARMv8
>> generation SoCs are likely to run ARM Trusted Firmware BL31.  In
>> this case, U-Boot is a non-secure world boot loader, so it should
>> not be able to reset the system directly.
>>
>> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
>> ---
>>
>> Changes in v2: None
>>
>>  arch/arm/Kconfig                   |  1 +
>>  drivers/Kconfig                    |  2 +
>>  drivers/Makefile                   |  5 +-
>>  drivers/firmware/Kconfig           |  6 +++
>>  drivers/firmware/Makefile          |  2 +
>>  drivers/firmware/firmware-uclass.c | 11 +++++
>>  drivers/firmware/psci.c            | 94 ++++++++++++++++++++++++++++++++++++++
>>  drivers/sysreset/Kconfig           | 10 ++++
>>  drivers/sysreset/Makefile          |  1 +
>>  drivers/sysreset/sysreset_psci.c   | 41 +++++++++++++++++
>>  include/dm/uclass-id.h             |  1 +
>>  include/linux/psci.h               | 13 ++++++
>>  12 files changed, 185 insertions(+), 2 deletions(-)
>>  create mode 100644 drivers/firmware/Kconfig
>>  create mode 100644 drivers/firmware/Makefile
>>  create mode 100644 drivers/firmware/firmware-uclass.c
>>  create mode 100644 drivers/firmware/psci.c
>>  create mode 100644 drivers/sysreset/sysreset_psci.c
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> It is not clear what the firmware uclass is for. Also there are no
> operations. How about adding a header file with at least a comment in
> it?


Actually, the firmware uclass does not provide
any generalized operation, but in the DM framework,
a driver must belong to some uclass.


I thought about this a bit, then
another idea is perhaps to re-use UCLASS_MISC
instead of adding a new opaque uclass.
We can use misc_ioctl() for PSCI call.




-- 
Best Regards
Masahiro Yamada

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-04-17  2:26 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-13  2:39 [U-Boot] [PATCH v2 0/3] ARM: support System Reset via PSCI Masahiro Yamada
2017-04-13  2:39 ` [U-Boot] [PATCH v2 1/3] ARM: import arm-smccc code from Linux 4.11-rc6 Masahiro Yamada
2017-04-13  2:39 ` [U-Boot] [PATCH v2 2/3] ARM: adjust arm-smccc code for use in U-Boot Masahiro Yamada
2017-04-13 13:57   ` Masahiro Yamada
2017-04-13  2:39 ` [U-Boot] [PATCH v2 3/3] sysreset: psci: support system reset in a generic way with PSCI Masahiro Yamada
2017-04-16 19:31   ` Simon Glass
2017-04-17  2:26     ` Masahiro Yamada

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.