Skip to contentSkip to conversation

ARM: support System Reset via PSCI

PATCH New Masahiro Yamada 2 participants 5 messages Apr 10, 2017 – Apr 11, 2017

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover ARM: support System Reset via PSCI

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/2)

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

Masahiro Yamada (2):
ARM: import arm-smccc from Linux 4.11-rc6
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            |  11 ++
 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, 704 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
Signature · 1 line
2.7.4
#1 lore raw

PATCH 1/2 ARM: import arm-smccc from Linux 4.11-rc6

This 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

They needed to be adjusted for U-Boot:
- Replace the license block with SPDX
- Adjust path to asm-offsets.h
- define UNWIND() as no-op

---

 arch/arm/Kconfig                    |   8 ++
 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 ++
 include/linux/arm-smccc.h           | 126 ++++++++++++++++++++
 10 files changed, 518 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
arch/arm/Kconfig +8 -0
index 7b20750..84744ef 100644
@@ -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
arch/arm/cpu/armv7/Makefile +1 -0
index 02e8778..3a9913a 100644
@@ -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
 
arch/arm/cpu/armv7/smccc-call.S new file +56 -0

56 lines not on this page · raw message

arch/arm/cpu/armv8/Makefile +2 -0
index 65915ee..c447085 100644
@@ -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
arch/arm/cpu/armv8/smccc-call.S new file +44 -0

44 lines not on this page · raw message

arch/arm/include/asm/opcodes-sec.h new file +17 -0
new file mode 100644
index 0000000..16dee8f
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2012 ARM Limited
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#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 */
arch/arm/include/asm/opcodes-virt.h new file +27 -0
new file mode 100644
index 0000000..923f257
@@ -0,0 +1,27 @@
+/*
+ * opcodes-virt.h: Opcode definitions for the ARM virtualization extensions
+ * Copyright (C) 2012  Linaro Limited
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+#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 */
arch/arm/include/asm/opcodes.h new file +229 -0

229 lines not on this page · raw message

arch/arm/lib/asm-offsets.c +8 -0
index e5bcaea..d620dc0 100644
@@ -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;
 }
include/linux/arm-smccc.h new file +126 -0

126 lines not on this page · raw message

Signature · 1 line
2.7.4
#2 lore raw

PATCH 2/2 sysreset: psci: support system reset in a generic way with PSCI

In reply to Masahiro Yamada

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. In this case, U-Boot is a non-secure world boot loader, so it should not be able to reset the system directly.

---

 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           | 11 +++++
 drivers/sysreset/Makefile          |  1 +
 drivers/sysreset/sysreset_psci.c   | 41 +++++++++++++++++
 include/dm/uclass-id.h             |  1 +
 include/linux/psci.h               | 13 ++++++
 12 files changed, 186 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
arch/arm/Kconfig +1 -0
index 84744ef..64984dc 100644
@@ -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
drivers/Kconfig +2 -0
index 0e5d97d..d0a36ab 100644
@@ -22,6 +22,8 @@ source "drivers/dfu/Kconfig"
 
 source "drivers/dma/Kconfig"
 
+source "drivers/firmware/Kconfig"
+
 source "drivers/fpga/Kconfig"
 
 source "drivers/gpio/Kconfig"
drivers/Makefile +3 -2
index 5d8baa5..4a4b237 100644
@@ -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/
drivers/firmware/Kconfig new file +6 -0
new file mode 100644
index 0000000..4c32426
@@ -0,0 +1,6 @@
+config FIRMWARE
+	bool
+
+config ARM_PSCI_FW
+	bool
+	select FIRMWARE
drivers/firmware/Makefile new file +2 -0
new file mode 100644
index 0000000..b208255
@@ -0,0 +1,2 @@
+obj-$(CONFIG_FIRMWARE)		+= firmware-uclass.o
+obj-$(CONFIG_ARM_PSCI_FW)	+= psci.o
drivers/firmware/firmware-uclass.c new file +11 -0
new file mode 100644
index 0000000..01b6a44
@@ -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",
+};
drivers/firmware/psci.c new file +94 -0

94 lines not on this page · raw message

drivers/sysreset/Kconfig +11 -0
index 05a37b9..1498d37 100644
@@ -13,4 +13,15 @@ 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 service
+	  (for example, ARM Trusted Firmware BL31) must be running on your
+	  system.
+
+endif
 endmenu
drivers/sysreset/Makefile +1 -0
index 49b8bb6..7bb8406 100644
@@ -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
drivers/sysreset/sysreset_psci.c new file +41 -0

41 lines not on this page · raw message

include/dm/uclass-id.h +1 -0
index 8c92d0b..1b635e4 100644
@@ -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 */
include/linux/psci.h +13 -0
index 310d83e..8d13bd2 100644
@@ -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 */
Signature · 1 line
2.7.4
#3 lore raw

cover ARM: support System Reset via PSCI

In reply to Masahiro Yamada

Hi Masahiro,

Quoted 10 lines

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.

Quoted 5 lines

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

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

I'm just wondering if it would be possible to:

1. Provide the exact Linux files (with SHA1) from main line

2. On top of this patch add u-boot adjustments

3. Add u-boot specific support for PSCI

In this way we would have exact info about the source of porting (or was it ported exactly from v4.11-rc6 tag?)

Best regards,
�ukasz Majewski

Quoted 36 lines

Masahiro Yamada (2):
ARM: import arm-smccc from Linux 4.11-rc6
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            |  11 ++
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, 704

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

Quoted 5 lines
 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

Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de

#4 lore raw

cover ARM: support System Reset via PSCI

Hi Lukasz,

2017-04-10 18:16 GMT+09:00 Lukasz Majewski <[email protected]>:

Quoted 20 lines

Hi Masahiro,

Quoted 10 lines

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.

Quoted 5 lines

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

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

I'm just wondering if it would be possible to:

Quoted 8 lines

1. Provide the exact Linux files (with SHA1) from main line

2. On top of this patch add u-boot adjustments

3. Add u-boot specific support for PSCI

In this way we would have exact info about the source of porting (or was it ported exactly from v4.11-rc6 tag?)

I am OK with this.

I will wait for a little more comments
before sending v2.

Thanks!

Signature · 2 lines
Best Regards
Masahiro Yamada