Skip to contentSkip to conversation

PSCI v0.2 framework for ARMv8

PATCH New Arnab Basu 6 participants 33 messages Aug 27, 2014 – Dec 3, 2014 Arm (32-bit)

lore
Share & tools
lore

Arnab Basu

author
#0 lore raw

cover PSCI v0.2 framework for ARMv8

This series of patches creates a generic PSCI v0.2 framework for ARMv8.

The first 3 patches refactor existing code so that ARMv7 PSCI, ARMv8 spin-table and ARMv8 PSCI can coexist.

The next 5 patches create a generic framework for PSCI v0.2 in ARMv8.

The implementation is modelled on the pre-existing PSCI v0.1 support in ARMv7.

PSCI support patches for the ARMv8 Foundation model will follow shortly.

Arnab Basu (8):
ARM: PSCI: Update psci.h for psci v0.2
ARM: PSCI: Alow arch specific DT patching ARMv8/fsl-lsch3: Refactor spin-table code
ARMv8: PSCI: Add linker section to hold PSCI code
ARMv8: PCSI: Add generic ARMv8 PSCI code
ARMv8: PSCI: Fixup the device tree for PSCI v0.2
ARMv8: PSCI: Setup ARMv8 PSCI
ARMv8: PSCI: Enable SMC

 arch/arm/config.mk                 |    2 +-
 arch/arm/cpu/armv7/virt-dt.c       |    7 +-
 arch/arm/cpu/armv8/Makefile        |    2 +
 arch/arm/cpu/armv8/cpu-dt.c        |  128 ++++++++++++++++++++++++++
 arch/arm/cpu/armv8/cpu.c           |   23 +++++
 arch/arm/cpu/armv8/fsl-lsch3/fdt.c |   46 +++------
 arch/arm/cpu/armv8/psci.S          |  177 ++++++++++++++++++++++++++++++++++++
 arch/arm/cpu/armv8/u-boot.lds      |   30 ++++++
 arch/arm/include/asm/macro.h       |    4 +
 arch/arm/include/asm/psci.h        |   42 ++++++++-
 arch/arm/include/asm/system.h      |    7 ++
 arch/arm/lib/bootm-fdt.c           |   11 ++-
 arch/arm/lib/bootm.c               |    3 +
 13 files changed, 446 insertions(+), 36 deletions(-)
 create mode 100644 arch/arm/cpu/armv8/cpu-dt.c
 create mode 100644 arch/arm/cpu/armv8/psci.S
Signature · 1 line
1.7.7.4
author
#1 lore raw

PATCH 1/8 ARM: PSCI: Update psci.h for psci v0.2

---
 arch/arm/include/asm/psci.h |   42 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 41 insertions(+), 1 deletions(-)
arch/arm/include/asm/psci.h +41 -1
index 704b4b0..68579cd 100644
@@ -2,6 +2,10 @@
  * Copyright (C) 2013 - ARM Ltd
  * Author: Marc Zyngier <[email protected]>
  *
+ * Copyright (C) 2014 - Freescale Semiconductor Ltd
+ * Author: Arnab Basu <[email protected]>
+ *	   updated file for PSCI v0.2
+ *
  * 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.
@@ -18,7 +22,7 @@
 #ifndef __ARM_PSCI_H__
 #define __ARM_PSCI_H__
 
-/* PSCI interface */
+/* PSCI v0.1 interface */
 #define ARM_PSCI_FN_BASE		0x95c1ba5e
 #define ARM_PSCI_FN(n)			(ARM_PSCI_FN_BASE + (n))
 
@@ -27,9 +31,45 @@
 #define ARM_PSCI_FN_CPU_ON		ARM_PSCI_FN(2)
 #define ARM_PSCI_FN_MIGRATE		ARM_PSCI_FN(3)
 
+/* PSCI v0.2 interface */
+#define PSCI_0_2_FN_BASE		0x84000000
+#define PSCI_0_2_FN(n)			(PSCI_0_2_FN_BASE + (n))
+#define PSCI_0_2_64BIT			0x40000000
+#define PSCI_0_2_FN64_BASE		\
+				(PSCI_0_2_FN_BASE + PSCI_0_2_64BIT)
+#define PSCI_0_2_FN64(n)		(PSCI_0_2_FN64_BASE + (n))
+
+#define PSCI_0_2_FN_PSCI_VERSION	PSCI_0_2_FN(0)
+#define PSCI_0_2_FN_CPU_SUSPEND		PSCI_0_2_FN(1)
+#define PSCI_0_2_FN_CPU_OFF		PSCI_0_2_FN(2)
+#define PSCI_0_2_FN_CPU_ON		PSCI_0_2_FN(3)
+#define PSCI_0_2_FN_AFFINITY_INFO	PSCI_0_2_FN(4)
+#define PSCI_0_2_FN_MIGRATE		PSCI_0_2_FN(5)
+#define PSCI_0_2_FN_MIGRATE_INFO_TYPE	PSCI_0_2_FN(6)
+#define PSCI_0_2_FN_MIGRATE_INFO_UP_CPU	PSCI_0_2_FN(7)
+#define PSCI_0_2_FN_SYSTEM_OFF		PSCI_0_2_FN(8)
+#define PSCI_0_2_FN_SYSTEM_RESET	PSCI_0_2_FN(9)
+
+#define PSCI_0_2_FN64_CPU_SUSPEND		PSCI_0_2_FN64(1)
+#define PSCI_0_2_FN64_CPU_ON			PSCI_0_2_FN64(3)
+#define PSCI_0_2_FN64_AFFINITY_INFO		PSCI_0_2_FN64(4)
+#define PSCI_0_2_FN64_MIGRATE			PSCI_0_2_FN64(5)
+#define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU	PSCI_0_2_FN64(7)
+
+
+/*
+ * Only PSCI return values such as: SUCCESS, NOT_SUPPORTED,
+ * INVALID_PARAMS, and DENIED defined below are applicable
+ * to PSCI v0.1.
+ */
 #define ARM_PSCI_RET_SUCCESS		0
 #define ARM_PSCI_RET_NI			(-1)
 #define ARM_PSCI_RET_INVAL		(-2)
 #define ARM_PSCI_RET_DENIED		(-3)
+#define PSCI_RET_ALREADY_ON		(-4)
+#define PSCI_RET_ON_PENDING		(-5)
+#define PSCI_RET_INTERNAL_FAILURE	(-6)
+#define PSCI_RET_NOT_PRESENT		(-7)
+#define PSCI_RET_DISABLED		(-8)
 
 #endif /* __ARM_PSCI_H__ */
Signature · 1 line
1.7.7.4
#2 lore raw

PATCH 1/8 ARM: PSCI: Update psci.h for psci v0.2

Hello Arnab,

Quoted 79 lines · Arnab Basu
---
 arch/arm/include/asm/psci.h |   42 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 41 insertions(+), 1 deletions(-)
arch/arm/include/asm/psci.h +41 -1
index 704b4b0..68579cd 100644
@@ -2,6 +2,10 @@
  * Copyright (C) 2013 - ARM Ltd
  * Author: Marc Zyngier <[email protected]>
  *
+ * Copyright (C) 2014 - Freescale Semiconductor Ltd
+ * Author: Arnab Basu <[email protected]>
+ *	   updated file for PSCI v0.2
+ *
  * 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.
@@ -18,7 +22,7 @@
 #ifndef __ARM_PSCI_H__
 #define __ARM_PSCI_H__
 
-/* PSCI interface */
+/* PSCI v0.1 interface */
 #define ARM_PSCI_FN_BASE		0x95c1ba5e
 #define ARM_PSCI_FN(n)			(ARM_PSCI_FN_BASE + (n))
 
@@ -27,9 +31,45 @@
 #define ARM_PSCI_FN_CPU_ON		ARM_PSCI_FN(2)
 #define ARM_PSCI_FN_MIGRATE		ARM_PSCI_FN(3)
 
+/* PSCI v0.2 interface */
+#define PSCI_0_2_FN_BASE		0x84000000
+#define PSCI_0_2_FN(n)			(PSCI_0_2_FN_BASE + (n))
+#define PSCI_0_2_64BIT			0x40000000
+#define PSCI_0_2_FN64_BASE		\
+				(PSCI_0_2_FN_BASE + PSCI_0_2_64BIT)
+#define PSCI_0_2_FN64(n)		(PSCI_0_2_FN64_BASE + (n))
+
+#define PSCI_0_2_FN_PSCI_VERSION	PSCI_0_2_FN(0)
+#define PSCI_0_2_FN_CPU_SUSPEND		PSCI_0_2_FN(1)
+#define PSCI_0_2_FN_CPU_OFF		PSCI_0_2_FN(2)
+#define PSCI_0_2_FN_CPU_ON		PSCI_0_2_FN(3)
+#define PSCI_0_2_FN_AFFINITY_INFO	PSCI_0_2_FN(4)
+#define PSCI_0_2_FN_MIGRATE		PSCI_0_2_FN(5)
+#define PSCI_0_2_FN_MIGRATE_INFO_TYPE	PSCI_0_2_FN(6)
+#define PSCI_0_2_FN_MIGRATE_INFO_UP_CPU	PSCI_0_2_FN(7)
+#define PSCI_0_2_FN_SYSTEM_OFF		PSCI_0_2_FN(8)
+#define PSCI_0_2_FN_SYSTEM_RESET	PSCI_0_2_FN(9)
+
+#define PSCI_0_2_FN64_CPU_SUSPEND		PSCI_0_2_FN64(1)
+#define PSCI_0_2_FN64_CPU_ON			PSCI_0_2_FN64(3)
+#define PSCI_0_2_FN64_AFFINITY_INFO		PSCI_0_2_FN64(4)
+#define PSCI_0_2_FN64_MIGRATE			PSCI_0_2_FN64(5)
+#define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU	PSCI_0_2_FN64(7)
+
+
+/*
+ * Only PSCI return values such as: SUCCESS, NOT_SUPPORTED,
+ * INVALID_PARAMS, and DENIED defined below are applicable
+ * to PSCI v0.1.
+ */
 #define ARM_PSCI_RET_SUCCESS		0
 #define ARM_PSCI_RET_NI			(-1)
 #define ARM_PSCI_RET_INVAL		(-2)
 #define ARM_PSCI_RET_DENIED		(-3)
+#define PSCI_RET_ALREADY_ON		(-4)
+#define PSCI_RET_ON_PENDING		(-5)
+#define PSCI_RET_INTERNAL_FAILURE	(-6)
+#define PSCI_RET_NOT_PRESENT		(-7)
+#define PSCI_RET_DISABLED		(-8)
 
 #endif /* __ARM_PSCI_H__ */
Signature · 1 line
1.7.7.4

Applied, with apologies for the delay. This patch will appear in 2015.01.

Amicalement,

Signature · 1 line
Albert.
#3 lore raw

PATCH 1/8 ARM: PSCI: Update psci.h for psci v0.2 -- CORRECTION

Hello Albert,

Quoted 80 lines · Albert ARIBAUD

Hello Arnab,

Quoted 76 lines · Arnab Basu
---
 arch/arm/include/asm/psci.h |   42 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 41 insertions(+), 1 deletions(-)
arch/arm/include/asm/psci.h +41 -1
index 704b4b0..68579cd 100644
@@ -2,6 +2,10 @@
  * Copyright (C) 2013 - ARM Ltd
  * Author: Marc Zyngier <[email protected]>
  *
+ * Copyright (C) 2014 - Freescale Semiconductor Ltd
+ * Author: Arnab Basu <[email protected]>
+ *	   updated file for PSCI v0.2
+ *
  * 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.
@@ -18,7 +22,7 @@
 #ifndef __ARM_PSCI_H__
 #define __ARM_PSCI_H__
 
-/* PSCI interface */
+/* PSCI v0.1 interface */
 #define ARM_PSCI_FN_BASE		0x95c1ba5e
 #define ARM_PSCI_FN(n)			(ARM_PSCI_FN_BASE + (n))
 
@@ -27,9 +31,45 @@
 #define ARM_PSCI_FN_CPU_ON		ARM_PSCI_FN(2)
 #define ARM_PSCI_FN_MIGRATE		ARM_PSCI_FN(3)
 
+/* PSCI v0.2 interface */
+#define PSCI_0_2_FN_BASE		0x84000000
+#define PSCI_0_2_FN(n)			(PSCI_0_2_FN_BASE + (n))
+#define PSCI_0_2_64BIT			0x40000000
+#define PSCI_0_2_FN64_BASE		\
+				(PSCI_0_2_FN_BASE + PSCI_0_2_64BIT)
+#define PSCI_0_2_FN64(n)		(PSCI_0_2_FN64_BASE + (n))
+
+#define PSCI_0_2_FN_PSCI_VERSION	PSCI_0_2_FN(0)
+#define PSCI_0_2_FN_CPU_SUSPEND		PSCI_0_2_FN(1)
+#define PSCI_0_2_FN_CPU_OFF		PSCI_0_2_FN(2)
+#define PSCI_0_2_FN_CPU_ON		PSCI_0_2_FN(3)
+#define PSCI_0_2_FN_AFFINITY_INFO	PSCI_0_2_FN(4)
+#define PSCI_0_2_FN_MIGRATE		PSCI_0_2_FN(5)
+#define PSCI_0_2_FN_MIGRATE_INFO_TYPE	PSCI_0_2_FN(6)
+#define PSCI_0_2_FN_MIGRATE_INFO_UP_CPU	PSCI_0_2_FN(7)
+#define PSCI_0_2_FN_SYSTEM_OFF		PSCI_0_2_FN(8)
+#define PSCI_0_2_FN_SYSTEM_RESET	PSCI_0_2_FN(9)
+
+#define PSCI_0_2_FN64_CPU_SUSPEND		PSCI_0_2_FN64(1)
+#define PSCI_0_2_FN64_CPU_ON			PSCI_0_2_FN64(3)
+#define PSCI_0_2_FN64_AFFINITY_INFO		PSCI_0_2_FN64(4)
+#define PSCI_0_2_FN64_MIGRATE			PSCI_0_2_FN64(5)
+#define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU	PSCI_0_2_FN64(7)
+
+
+/*
+ * Only PSCI return values such as: SUCCESS, NOT_SUPPORTED,
+ * INVALID_PARAMS, and DENIED defined below are applicable
+ * to PSCI v0.1.
+ */
 #define ARM_PSCI_RET_SUCCESS		0
 #define ARM_PSCI_RET_NI			(-1)
 #define ARM_PSCI_RET_INVAL		(-2)
 #define ARM_PSCI_RET_DENIED		(-3)
+#define PSCI_RET_ALREADY_ON		(-4)
+#define PSCI_RET_ON_PENDING		(-5)
+#define PSCI_RET_INTERNAL_FAILURE	(-6)
+#define PSCI_RET_NOT_PRESENT		(-7)
+#define PSCI_RET_DISABLED		(-8)
 
Quoted 6 lines
Quoted 3 lines
arch/arm/include/asm/psci.h +0 -0
 #endif /* __ARM_PSCI_H__ */
Signature · 1 line
1.7.7.4

Applied, with apologies for the delay. This patch will appear in 2015.01.

Drat -- I'd forgotten Arnab had hinted on possibly modifying patches from the series, and I assumed this one would not. Un-applied for now.

Quoted 3 lines

Amicalement,

Signature · 1 line
Albert.

Amicalement,

Signature · 1 line
Albert.
author
#4 lore raw

PATCH 2/8 ARM: PSCI: Alow arch specific DT patching

In reply to Arnab Basu

Both ARMv7 and ARMv8 need to patch the device tree but the kind of patching done is different. This creates a function that can be defined by each architecture to handle the differences

---
 arch/arm/cpu/armv7/virt-dt.c |    7 ++++++-
 arch/arm/lib/bootm-fdt.c     |   11 ++++++++---
 2 files changed, 14 insertions(+), 4 deletions(-)
arch/arm/cpu/armv7/virt-dt.c +6 -1
index 0b0d6a7..3fbec39 100644
@@ -88,7 +88,7 @@ static int fdt_psci(void *fdt)
 	return 0;
 }
 
-int armv7_update_dt(void *fdt)
+static int armv7_update_dt(void *fdt)
 {
 #ifndef CONFIG_ARMV7_SECURE_BASE
 	/* secure code lives in RAM, keep it alive */
@@ -98,3 +98,8 @@ int armv7_update_dt(void *fdt)
 
 	return fdt_psci(fdt);
 }
+
+int cpu_update_dt(void *fdt)
+{
+	return armv7_update_dt(fdt);
+}
arch/arm/lib/bootm-fdt.c +8 -3
index d4f1578..daabc03 100644
@@ -21,6 +21,11 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+__weak int cpu_update_dt(void *fdt)
+{
+	return 0;
+}
+
 int arch_fixup_fdt(void *blob)
 {
 	bd_t *bd = gd->bd;
@@ -34,11 +39,11 @@ int arch_fixup_fdt(void *blob)
 	}
 
 	ret = fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS);
-#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT)
+
 	if (ret)
 		return ret;
 
-	ret = armv7_update_dt(blob);
-#endif
+	ret = cpu_update_dt(blob);
+
 	return ret;
 }
Signature · 1 line
1.7.7.4
#5 lore raw

PATCH 2/8 ARM: PSCI: Alow arch specific DT patching

Hi Arnab,

Quoted 3 lines · Arnab Basu

Both ARMv7 and ARMv8 need to patch the device tree but the kind of patching done is different. This creates a function that can be defined by each architecture to handle the differences

I have no problem with the patch, but what is it that we need to do differently for ARMv7 and ARMv8?

Mark.

Quoted 65 lines
---
 arch/arm/cpu/armv7/virt-dt.c |    7 ++++++-
 arch/arm/lib/bootm-fdt.c     |   11 ++++++++---
 2 files changed, 14 insertions(+), 4 deletions(-)
arch/arm/cpu/armv7/virt-dt.c +6 -1
index 0b0d6a7..3fbec39 100644
@@ -88,7 +88,7 @@ static int fdt_psci(void *fdt)
 	return 0;
 }
 
-int armv7_update_dt(void *fdt)
+static int armv7_update_dt(void *fdt)
 {
 #ifndef CONFIG_ARMV7_SECURE_BASE
 	/* secure code lives in RAM, keep it alive */
@@ -98,3 +98,8 @@ int armv7_update_dt(void *fdt)
 
 	return fdt_psci(fdt);
 }
+
+int cpu_update_dt(void *fdt)
+{
+	return armv7_update_dt(fdt);
+}
arch/arm/lib/bootm-fdt.c +8 -3
index d4f1578..daabc03 100644
@@ -21,6 +21,11 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+__weak int cpu_update_dt(void *fdt)
+{
+	return 0;
+}
+
 int arch_fixup_fdt(void *blob)
 {
 	bd_t *bd = gd->bd;
@@ -34,11 +39,11 @@ int arch_fixup_fdt(void *blob)
 	}
 
 	ret = fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS);
-#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT)
+
 	if (ret)
 		return ret;
 
-	ret = armv7_update_dt(blob);
-#endif
+	ret = cpu_update_dt(blob);
+
 	return ret;
 }
Signature · 1 line
1.7.7.4
author
#6 lore raw

PATCH 2/8 ARM: PSCI: Alow arch specific DT patching

Hi Mark

Quoted 10 lines · Mark Rutland

Hi Arnab,

Quoted 3 lines · Arnab Basu

Both ARMv7 and ARMv8 need to patch the device tree but the kind of patching done is different. This creates a function that can be defined by each architecture to handle the differences

I have no problem with the patch, but what is it that we need to do differently for ARMv7 and ARMv8?

In ARMv7 there does not seem to be any code around to set "enable-method" to "spin-table". I guess it is assumed that DTs already come with this set.

For ARMv8 we would like to assume that "enable-method" is missing from the cpu node and will be set either to "spin-table" or "psci" by the boot loader.

So the difference is, for ARMv7 the "enable-method" is only modified in case of PSCI, whereas for ARMv8 it is always modified.

Thanks
Arnab

Quoted 2 lines

Mark.

#7 lore raw

PATCH 2/8 ARM: PSCI: Alow arch specific DT patching

Quoted 10 lines · Arnab Basu

Hi Mark

Quoted 7 lines · Mark Rutland

Hi Arnab,

Quoted 3 lines · Arnab Basu

Both ARMv7 and ARMv8 need to patch the device tree but the kind of patching done is different. This creates a function that can be defined by each architecture to handle the differences

Quoted 7 lines
Quoted 3 lines

I have no problem with the patch, but what is it that we need to do differently for ARMv7 and ARMv8?

In ARMv7 there does not seem to be any code around to set "enable-method" to "spin-table". I guess it is assumed that DTs already come with this set.

That'll be a consequence of partial conversion frmo board file on the 32-bit side. For most platforms the SMP boot mechanism is still implicit.

Quoted 3 lines

For ARMv8 we would like to assume that "enable-method" is missing from the cpu node and will be set either to "spin-table" or "psci" by the boot loader.

Sounds good to me.

Quoted 2 lines

So the difference is, for ARMv7 the "enable-method" is only modified in case of PSCI, whereas for ARMv8 it is always modified.

Ok. Thanks for the description. :)

Mark.

author
#8 lore raw

PATCH 3/8 ARMv8/fsl-lsch3: Refactor spin-table code

In reply to Arnab Basu

This creates the function cpu_update_dt for ARMv8 which currently patches the cpu node in the device table and sets enable-method to spin-table.

---
 arch/arm/cpu/armv8/Makefile                      |    1 +
 arch/arm/cpu/armv8/{fsl-lsch3/fdt.c => cpu-dt.c} |   37 ++++++++++--------
 arch/arm/cpu/armv8/fsl-lsch3/fdt.c               |   46 ++++++++--------------
 3 files changed, 38 insertions(+), 46 deletions(-)
 copy arch/arm/cpu/armv8/{fsl-lsch3/fdt.c => cpu-dt.c} (62%)
arch/arm/cpu/armv8/Makefile +1 -0
index 7d93f59..4f0ea87 100644
@@ -14,3 +14,4 @@ obj-y	+= exceptions.o
 obj-y	+= cache.o
 obj-y	+= tlb.o
 obj-y	+= transition.o
+obj-y	+= cpu-dt.o
arch/arm/cpu/armv8/cpu-dt.c renamed from arch/arm/cpu/armv8/fsl-lsch3/fdt.c +21 -16
similarity index 62%
copy from arch/arm/cpu/armv8/fsl-lsch3/fdt.c
copy to arch/arm/cpu/armv8/cpu-dt.c
index 2dbcdcb..9792bc0 100644
@@ -7,17 +7,24 @@
 #include <common.h>
 #include <libfdt.h>
 #include <fdt_support.h>
-#include "mp.h"
 
 #ifdef CONFIG_MP
-void ft_fixup_cpu(void *blob)
+
+__weak u64 arch_get_release_addr(u64 cpu_id)
+{
+	return 0;
+}
+
+__weak void arch_spin_table_reserve_mem(void *fdt)
+{
+}
+
+static void cpu_update_dt_spin_table(void *blob)
 {
 	int off;
-	__maybe_unused u64 spin_tbl_addr = (u64)get_spin_tbl_addr();
-	fdt32_t *reg;
+	__maybe_unused u64 val;
 	int addr_cells;
-	u64 val;
-	size_t *boot_code_size = &(__secondary_boot_code_size);
+	__maybe_unused fdt32_t *reg;
 
 	off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpus", 4);
 	of_bus_default_count_cells(blob, off, &addr_cells, NULL);
@@ -26,31 +33,29 @@ void ft_fixup_cpu(void *blob)
 	while (off != -FDT_ERR_NOTFOUND) {
 		reg = (fdt32_t *)fdt_getprop(blob, off, "reg", 0);
 		if (reg) {
-			val = spin_tbl_addr;
-#ifndef CONFIG_FSL_SMP_RELEASE_ALL
-			val += id_to_core(of_read_number(reg, addr_cells))
-				* SPIN_TABLE_ELEM_SIZE;
-#endif
+			val = arch_get_release_addr(
+					of_read_number(reg, addr_cells));
 			val = cpu_to_fdt64(val);
 			fdt_setprop_string(blob, off, "enable-method",
 					   "spin-table");
 			fdt_setprop(blob, off, "cpu-release-addr",
 				    &val, sizeof(val));
 		} else {
-			puts("cpu NULL\n");
+			puts("Unable to read reg property\n");
 		}
+
 		off = fdt_node_offset_by_prop_value(blob, off, "device_type",
 						    "cpu", 4);
 	}
 
-	fdt_add_mem_rsv(blob, (uintptr_t)&secondary_boot_code,
-			*boot_code_size);
+	arch_spin_table_reserve_mem(blob);
 }
 #endif
 
-void ft_cpu_setup(void *blob, bd_t *bd)
+int cpu_update_dt(void *fdt)
 {
 #ifdef CONFIG_MP
-	ft_fixup_cpu(blob);
+	cpu_update_dt_spin_table(fdt);
 #endif
+	return 0;
 }
arch/arm/cpu/armv8/fsl-lsch3/fdt.c +16 -30

58 lines not on this page · raw message

Signature · 1 line
1.7.7.4
#9 lore raw

PATCH 3/8 ARMv8/fsl-lsch3: Refactor spin-table code

Hello Arnab,

Quoted 8 lines · Arnab Basu

This creates the function cpu_update_dt for ARMv8 which currently patches the cpu node in the device table and sets enable-method to spin-table.

---

This patch fails to apply cleanly. Can you please rebase the series on top of current u-boot/master?

Amicalement,

Signature · 1 line
Albert.
#10 lore raw

PATCH 3/8 ARMv8/fsl-lsch3: Refactor spin-table code

Hi Albert

Quoted 17 lines

-----Original Message-----
From: Albert ARIBAUD [mailto:albert.u.boot at aribaud.net]
Sent: Monday, October 27, 2014 2:36 AM
To: Basu Arnab-B45036
Cc: marc.zyngier at arm.com; mark.rutland at arm.com; Sun York-R58495; Yoder Stuart-B08248; u-boot at lists.denx.de
Subject: Re: [U-Boot] [PATCH 3/8] ARMv8/fsl-lsch3: Refactor spin-table code

Hello Arnab,

Quoted 4 lines · Arnab Basu

This creates the function cpu_update_dt for ARMv8 which currently patches the cpu node in the device table and sets enable-method to spin-table.

Quoted 7 lines
Quoted 4 lines

---

This patch fails to apply cleanly. Can you please rebase the series on top of current u-boot/master?

Yes, in fact I need to rework some of the other patches in the series too. I got a little side tracked, hence the delay. I will get on this..

Thanks
Arnab

Quoted 4 lines

Amicalement,
--
Albert.

author
#11 lore raw

PATCH 4/8 ARMv8: PSCI: Add linker section to hold PSCI code

In reply to Arnab Basu

A separate linker section makes it possible to keep this code either in DDR or in some secure memory location provided specifically for the purpose.

So far no one is using this section.

---
 arch/arm/config.mk            |    2 +-
 arch/arm/cpu/armv8/u-boot.lds |   30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletions(-)
arch/arm/config.mk +1 -1
index c339e6d..9272e9c 100644
@@ -111,7 +111,7 @@ endif
 
 # limit ourselves to the sections we want in the .bin.
 ifdef CONFIG_ARM64
-OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
+OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
 else
 OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn
 endif
arch/arm/cpu/armv8/u-boot.lds +30 -0
index 4c12222..bd95fff 100644
@@ -8,6 +8,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#include <config.h>
+
 OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
 OUTPUT_ARCH(aarch64)
 ENTRY(_start)
@@ -23,6 +25,34 @@ SECTIONS
 		*(.text*)
 	}
 
+#ifdef CONFIG_ARMV8_PSCI
+
+#ifndef CONFIG_ARMV8_SECURE_BASE
+#define CONFIG_ARMV8_SECURE_BASE
+#endif
+
+	.__secure_start : {
+		. = ALIGN(0x1000);
+		*(.__secure_start)
+	}
+
+	.secure_text CONFIG_ARMV8_SECURE_BASE :
+		AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
+	{
+		*(._secure.text)
+	}
+
+	. = LOADADDR(.__secure_start) +
+		SIZEOF(.__secure_start) +
+		SIZEOF(.secure_text);
+
+	__secure_end_lma = .;
+	.__secure_end : AT(__secure_end_lma) {
+		*(.__secure_end)
+		LONG(0x1d1071c);	/* Must output something to reset LMA */
+	}
+#endif
+
 	. = ALIGN(8);
 	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
 
Signature · 1 line
1.7.7.4
#12 lore raw

PATCH 4/8 ARMv8: PSCI: Add linker section to hold PSCI code

Hi Arnab,

Quoted 59 lines · Arnab Basu

A separate linker section makes it possible to keep this code either in DDR or in some secure memory location provided specifically for the purpose.

So far no one is using this section.

---
 arch/arm/config.mk            |    2 +-
 arch/arm/cpu/armv8/u-boot.lds |   30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletions(-)
arch/arm/config.mk +1 -1
index c339e6d..9272e9c 100644
@@ -111,7 +111,7 @@ endif
 
 # limit ourselves to the sections we want in the .bin.
 ifdef CONFIG_ARM64
-OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
+OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
 else
 OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn
 endif
arch/arm/cpu/armv8/u-boot.lds +17 -0
index 4c12222..bd95fff 100644
@@ -8,6 +8,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#include <config.h>
+
 OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
 OUTPUT_ARCH(aarch64)
 ENTRY(_start)
@@ -23,6 +25,34 @@ SECTIONS
 		*(.text*)
 	}
 
+#ifdef CONFIG_ARMV8_PSCI
+
+#ifndef CONFIG_ARMV8_SECURE_BASE
+#define CONFIG_ARMV8_SECURE_BASE
+#endif
+
+	.__secure_start : {
+		. = ALIGN(0x1000);
+		*(.__secure_start)
+	}
+
+	.secure_text CONFIG_ARMV8_SECURE_BASE :
+		AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
+	{
+		*(._secure.text)

arch/arm/cpu/armv8/u-boot.lds SECTIONS · line 52

Quoted 10 lines
arch/arm/cpu/armv8/u-boot.lds +10 -0
+	}
+
+	. = LOADADDR(.__secure_start) +
+		SIZEOF(.__secure_start) +
+		SIZEOF(.secure_text);
+
+	__secure_end_lma = .;
+	.__secure_end : AT(__secure_end_lma) {
+		*(.__secure_end)
+		LONG(0x1d1071c);	/* Must output something to reset LMA */

Can you explain in more detail what issue this fixes?

arch/arm/cpu/armv8/u-boot.lds SECTIONS · line 58

Quoted 6 lines
arch/arm/cpu/armv8/u-boot.lds +3 -0
+	}
+#endif
+
 	. = ALIGN(8);
 	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
 

Amicalement,

Signature · 1 line
Albert.
#13 lore raw

PATCH 4/8 ARMv8: PSCI: Add linker section to hold PSCI code

Quoted 68 lines · Albert ARIBAUD

Hi Arnab,

Quoted 63 lines · Arnab Basu

A separate linker section makes it possible to keep this code either in DDR or in some secure memory location provided specifically for the purpose.

So far no one is using this section.

---
 arch/arm/config.mk            |    2 +-
 arch/arm/cpu/armv8/u-boot.lds |   30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletions(-)
arch/arm/config.mk +1 -1
index c339e6d..9272e9c 100644
@@ -111,7 +111,7 @@ endif
 
 # limit ourselves to the sections we want in the .bin.
 ifdef CONFIG_ARM64
-OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
+OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
 else
 OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn
 endif
arch/arm/cpu/armv8/u-boot.lds +21 -0
index 4c12222..bd95fff 100644
@@ -8,6 +8,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#include <config.h>
+
 OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
 OUTPUT_ARCH(aarch64)
 ENTRY(_start)
@@ -23,6 +25,34 @@ SECTIONS
 		*(.text*)
 	}
 
+#ifdef CONFIG_ARMV8_PSCI
+
+#ifndef CONFIG_ARMV8_SECURE_BASE
+#define CONFIG_ARMV8_SECURE_BASE
+#endif
+
+	.__secure_start : {
+		. = ALIGN(0x1000);
+		*(.__secure_start)
+	}
+
+	.secure_text CONFIG_ARMV8_SECURE_BASE :
+		AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
+	{
+		*(._secure.text)
+	}
+
+	. = LOADADDR(.__secure_start) +
+		SIZEOF(.__secure_start) +
Quoted 8 lines

arch/arm/cpu/armv8/u-boot.lds SECTIONS · line 52

Quoted 6 lines
arch/arm/cpu/armv8/u-boot.lds +6 -0
+		SIZEOF(.secure_text);
+
+	__secure_end_lma = .;
+	.__secure_end : AT(__secure_end_lma) {
+		*(.__secure_end)
+		LONG(0x1d1071c);	/* Must output something to reset LMA */

Can you explain in more detail what issue this fixes?

If you use AT to force a new load address (LMA), you must ensure that you actually output something at this address. Here, if *(.__secure_end) ends up being empty, whatever follows would be as if the AT never happened, ending up at the wrong LMA.

The workaround is to force the output of a dummy value in all cases, ensuring that the rest of the text is at a sensible LMA. This is an issue that has been in GNU ld for years, and this workaround is a copy/paste of the same one in the ARMv7 ld script.

Thanks,

	M.
Signature · 1 line
Jazz is not dead. It just smells funny.
#14 lore raw

PATCH 4/8 ARMv8: PSCI: Add linker section to hold PSCI code

Hi Marc,

Quoted 83 lines · Marc Zyngier
Quoted 68 lines · Albert ARIBAUD

Hi Arnab,

Quoted 63 lines · Arnab Basu

A separate linker section makes it possible to keep this code either in DDR or in some secure memory location provided specifically for the purpose.

So far no one is using this section.

---
 arch/arm/config.mk            |    2 +-
 arch/arm/cpu/armv8/u-boot.lds |   30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletions(-)
arch/arm/config.mk +1 -1
index c339e6d..9272e9c 100644
@@ -111,7 +111,7 @@ endif
 
 # limit ourselves to the sections we want in the .bin.
 ifdef CONFIG_ARM64
-OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
+OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
 else
 OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn
 endif
arch/arm/cpu/armv8/u-boot.lds +21 -0
index 4c12222..bd95fff 100644
@@ -8,6 +8,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#include <config.h>
+
 OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
 OUTPUT_ARCH(aarch64)
 ENTRY(_start)
@@ -23,6 +25,34 @@ SECTIONS
 		*(.text*)
 	}
 
+#ifdef CONFIG_ARMV8_PSCI
+
+#ifndef CONFIG_ARMV8_SECURE_BASE
+#define CONFIG_ARMV8_SECURE_BASE
+#endif
+
+	.__secure_start : {
+		. = ALIGN(0x1000);
+		*(.__secure_start)
+	}
+
+	.secure_text CONFIG_ARMV8_SECURE_BASE :
+		AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
+	{
+		*(._secure.text)
+	}
+
+	. = LOADADDR(.__secure_start) +
+		SIZEOF(.__secure_start) +
Quoted 8 lines

arch/arm/cpu/armv8/u-boot.lds SECTIONS · line 52

Quoted 6 lines
arch/arm/cpu/armv8/u-boot.lds +6 -0
+		SIZEOF(.secure_text);
+
+	__secure_end_lma = .;
+	.__secure_end : AT(__secure_end_lma) {
+		*(.__secure_end)
+		LONG(0x1d1071c);	/* Must output something to reset LMA */

Can you explain in more detail what issue this fixes?

If you use AT to force a new load address (LMA), you must ensure that you actually output something at this address. Here, if *(.__secure_end) ends up being empty, whatever follows would be as if the AT never happened, ending up at the wrong LMA.

Quoted 4 lines

The workaround is to force the output of a dummy value in all cases, ensuring that the rest of the text is at a sensible LMA. This is an issue that has been in GNU ld for years, and this workaround is a copy/paste of the same one in the ARMv7 ld script.

I see. Does the ld bug have an identifier that we could mention in a comment in the linker script as a reference?

Quoted 3 lines

Thanks,

	M.

Amicalement,

Signature · 1 line
Albert.
#15 lore raw

PATCH 4/8 ARMv8: PSCI: Add linker section to hold PSCI code

Hi Albert,

Quoted 88 lines · Albert ARIBAUD

Hi Marc,

Quoted 83 lines · Marc Zyngier
Quoted 68 lines · Albert ARIBAUD

Hi Arnab,

Quoted 63 lines · Arnab Basu

A separate linker section makes it possible to keep this code either in DDR or in some secure memory location provided specifically for the purpose.

So far no one is using this section.

---
 arch/arm/config.mk            |    2 +-
 arch/arm/cpu/armv8/u-boot.lds |   30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletions(-)
arch/arm/config.mk +1 -1
index c339e6d..9272e9c 100644
@@ -111,7 +111,7 @@ endif
 
 # limit ourselves to the sections we want in the .bin.
 ifdef CONFIG_ARM64
-OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
+OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
 else
 OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn
 endif
arch/arm/cpu/armv8/u-boot.lds +21 -0
index 4c12222..bd95fff 100644
@@ -8,6 +8,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#include <config.h>
+
 OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
 OUTPUT_ARCH(aarch64)
 ENTRY(_start)
@@ -23,6 +25,34 @@ SECTIONS
 		*(.text*)
 	}
 
+#ifdef CONFIG_ARMV8_PSCI
+
+#ifndef CONFIG_ARMV8_SECURE_BASE
+#define CONFIG_ARMV8_SECURE_BASE
+#endif
+
+	.__secure_start : {
+		. = ALIGN(0x1000);
+		*(.__secure_start)
+	}
+
+	.secure_text CONFIG_ARMV8_SECURE_BASE :
+		AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
+	{
+		*(._secure.text)
+	}
+
+	. = LOADADDR(.__secure_start) +
+		SIZEOF(.__secure_start) +
Quoted 8 lines

arch/arm/cpu/armv8/u-boot.lds SECTIONS · line 52

Quoted 6 lines
arch/arm/cpu/armv8/u-boot.lds +6 -0
+		SIZEOF(.secure_text);
+
+	__secure_end_lma = .;
+	.__secure_end : AT(__secure_end_lma) {
+		*(.__secure_end)
+		LONG(0x1d1071c);	/* Must output something to reset LMA */

Can you explain in more detail what issue this fixes?

If you use AT to force a new load address (LMA), you must ensure that you actually output something at this address. Here, if *(.__secure_end) ends up being empty, whatever follows would be as if the AT never happened, ending up at the wrong LMA.

Quoted 7 lines
Quoted 4 lines

The workaround is to force the output of a dummy value in all cases, ensuring that the rest of the text is at a sensible LMA. This is an issue that has been in GNU ld for years, and this workaround is a copy/paste of the same one in the ARMv7 ld script.

I see. Does the ld bug have an identifier that we could mention in a comment in the linker script as a reference?

Ping.

Quoted 5 lines
Quoted 3 lines

Thanks,

	M.

Amicalement,

Amicalement,

Signature · 1 line
Albert.
#16 lore raw

PATCH 4/8 ARMv8: PSCI: Add linker section to hold PSCI code

Quoted 114 lines · Albert ARIBAUD

Hi Albert,

Quoted 109 lines · Albert ARIBAUD

Hi Marc,

Quoted 1 line · Marc Zyngier

On Thu, Sep 18 2014 at 10:12:17 AM, Albert ARIBAUD

Quoted 6 lines · <[email protected]> wrote:
Quoted 6 lines

Hi Arnab,

Quoted 1 line · Arnab Basu

A separate linker section makes it possible to keep this code

either

Quoted 1 line
Quoted 1 line
Quoted 1 line

in DDR or in some secure memory location provided specifically

for the

Quoted 10 lines
Quoted 10 lines
Quoted 10 lines

purpose.

So far no one is using this section.

---
 arch/arm/config.mk            |    2 +-
 arch/arm/cpu/armv8/u-boot.lds |   30 

++++++++++++++++++++++++++++++

Quoted 11 lines
Quoted 11 lines

arch/arm/config.mk endif · line 114

Quoted 11 lines
 2 files changed, 31 insertions(+), 1 deletions(-)
arch/arm/config.mk +0 -1
index c339e6d..9272e9c 100644
@@ -111,7 +111,7 @@ endif
 
 # limit ourselves to the sections we want in the .bin.
 ifdef CONFIG_ARM64
-OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list 

-j .rela.dyn

Quoted 1 line
Quoted 1 line

arch/arm/config.mk endif · line 114

Quoted 1 line
arch/arm/config.mk +1 -0
+OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .data 

-j .u_boot_list -j .rela.dyn

Quoted 2 lines
Quoted 2 lines

arch/arm/config.mk endif · line 116

Quoted 2 lines
arch/arm/config.mk +0 -0
 else
 OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash 

-j .data -j .got.plt -j .u_boot_list -j .rel.dyn

Quoted 2 lines
Quoted 2 lines

Review

Quoted 2 lines
arch/arm/config.mk +0 -0
 endif
(quoted diff) +0 -0

b/arch/arm/cpu/armv8/u-boot.lds

Quoted 10 lines
Quoted 10 lines

arch/arm/cpu/armv8/u-boot.lds line 13

Quoted 10 lines

index 4c12222..bd95fff 100644

arch/arm/cpu/armv8/u-boot.lds +2 -0
@@ -8,6 +8,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#include <config.h>
+
 OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", 

"elf64-littleaarch64")

Quoted 34 lines
Quoted 25 lines
Quoted 25 lines
arch/arm/cpu/armv8/u-boot.lds +19 -0
 OUTPUT_ARCH(aarch64)
 ENTRY(_start)
@@ -23,6 +25,34 @@ SECTIONS
 		*(.text*)
 	}
 
+#ifdef CONFIG_ARMV8_PSCI
+
+#ifndef CONFIG_ARMV8_SECURE_BASE
+#define CONFIG_ARMV8_SECURE_BASE
+#endif
+
+	.__secure_start : {
+		. = ALIGN(0x1000);
+		*(.__secure_start)
+	}
+
+	.secure_text CONFIG_ARMV8_SECURE_BASE :
+		AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
+	{
+		*(._secure.text)
+	}
+
+	. = LOADADDR(.__secure_start) +
+		SIZEOF(.__secure_start) +
Quoted 8 lines

arch/arm/cpu/armv8/u-boot.lds SECTIONS · line 52

Quoted 6 lines
arch/arm/cpu/armv8/u-boot.lds +6 -0
+		SIZEOF(.secure_text);
+
+	__secure_end_lma = .;
+	.__secure_end : AT(__secure_end_lma) {
+		*(.__secure_end)
+		LONG(0x1d1071c);	/* Must output something to reset LMA */

Can you explain in more detail what issue this fixes?

Quoted 1 line

If you use AT to force a new load address (LMA), you must ensure

that

Quoted 1 line

you actually output something at this address. Here, if

*(.__secure_end)

Quoted 5 lines

ends up being empty, whatever follows would be as if the AT never happened, ending up at the wrong LMA.

The workaround is to force the output of a dummy value in all cases, ensuring that the rest of the text is at a sensible LMA.

This is

Quoted 1 line

an issue that has been in GNU ld for years, and this workaround is

a

Quoted 1 line

copy/paste of the same one in the ARMv7 ld script.

I see. Does the ld bug have an identifier that we could mention in a comment in the linker script as a reference?

The only report I'm aware of is this one:
https://sourceware.org/bugzilla/show_bug.cgi?id=948

There may be other ways to work around this, but my linker-foo is admittedly pretty limited.

Thanks,

         M.
Signature · 1 line
Fast, cheap, reliable. Pick two.
author
#17 lore raw

PATCH 5/8 ARMv8: PCSI: Add generic ARMv8 PSCI code

In reply to Arnab Basu

Implement core support for PSCI. As this is generic code, it doesn't implement anything really useful (all the functions are returning Not Implemented).

This is largely ported from the similar code that exists for ARMv7

---
 arch/arm/cpu/armv8/Makefile |    1 +
 arch/arm/cpu/armv8/psci.S   |  171 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 172 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv8/psci.S
arch/arm/cpu/armv8/Makefile +1 -0
index 4f0ea87..8f6988d 100644
@@ -15,3 +15,4 @@ obj-y	+= cache.o
 obj-y	+= tlb.o
 obj-y	+= transition.o
 obj-y	+= cpu-dt.o
+obj-$(CONFIG_ARMV8_PSCI)	+= psci.o
arch/arm/cpu/armv8/psci.S new file +171 -0

171 lines not on this page · raw message

Signature · 1 line
1.7.7.4
#18 lore raw

PATCH 5/8 ARMv8: PCSI: Add generic ARMv8 PSCI code

Hi Arnab,

Quoted 3 lines · Arnab Basu

Implement core support for PSCI. As this is generic code, it doesn't implement anything really useful (all the functions are returning Not Implemented).

This is really nice to see! Thanks for working on this.

Some functions which return NOT_IMPLEMENTED below are requried to be implemented per the PSCI 0.2 spec.

I hope that the plan is to implement all the required functions before we turn this on?

Otherwise, comments below.

Quoted 69 lines

This is largely ported from the similar code that exists for ARMv7

---
 arch/arm/cpu/armv8/Makefile |    1 +
 arch/arm/cpu/armv8/psci.S   |  171 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 172 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv8/psci.S
arch/arm/cpu/armv8/Makefile +1 -0
index 4f0ea87..8f6988d 100644
@@ -15,3 +15,4 @@ obj-y	+= cache.o
 obj-y	+= tlb.o
 obj-y	+= transition.o
 obj-y	+= cpu-dt.o
+obj-$(CONFIG_ARMV8_PSCI)	+= psci.o
arch/arm/cpu/armv8/psci.S new file +43 -0
new file mode 100644
index 0000000..5f4e3b2
@@ -0,0 +1,171 @@
+/*
+ * (C) Copyright 2014
+ * Arnab Basu <[email protected]>
+ *
+ * Based on arch/arm/cpu/armv7/psci.S
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <linux/linkage.h>
+#include <asm/psci.h>
+
+.pushsection ._secure.text, "ax"
+
+ENTRY(psci_0_2_cpu_suspend_64)
+ENTRY(psci_0_2_cpu_on_64)
+ENTRY(psci_0_2_affinity_info_64)
+ENTRY(psci_0_2_migrate_64)
+ENTRY(psci_0_2_migrate_info_up_cpu_64)
+	mov	x0, #ARM_PSCI_RET_NI	/* Return -1 (Not Implemented) */
+	ret
+ENDPROC(psci_0_2_cpu_suspend_64)
+ENDPROC(psci_0_2_cpu_on_64)
+ENDPROC(psci_0_2_affinity_info_64)
+ENDPROC(psci_0_2_migrate_64)
+ENDPROC(psci_0_2_migrate_info_up_cpu_64)
+.weak psci_0_2_cpu_suspend_64
+.weak psci_0_2_cpu_on_64
+.weak psci_0_2_affinity_info_64
+.weak psci_0_2_migrate_64
+.weak psci_0_2_migrate_info_up_cpu_64
+
+ENTRY(psci_0_2_psci_version)
+	mov	x0, #2			/* Return Major = 0, Minor = 2*/
+	ret
+ENDPROC(psci_0_2_psci_version)
+
+.align 4
+_psci_0_2_table:
+	.quad	PSCI_0_2_FN_PSCI_VERSION
+	.quad	psci_0_2_psci_version
+	.quad	PSCI_0_2_FN64_CPU_SUSPEND
+	.quad	psci_0_2_cpu_suspend_64

arch/arm/cpu/armv8/psci.S line 53

Quoted 10 lines
arch/arm/cpu/armv8/psci.S new file +10 -0
+	.quad	PSCI_0_2_FN64_CPU_ON
+	.quad	psci_0_2_cpu_on_64
+	.quad	PSCI_0_2_FN64_AFFINITY_INFO
+	.quad	psci_0_2_affinity_info_64
+	.quad	PSCI_0_2_FN64_MIGRATE
+	.quad	psci_0_2_migrate_64
+	.quad	PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU
+	.quad	psci_0_2_migrate_info_up_cpu_64
+	.quad	0
+	.quad	0

It would be nice if we could reorganise this something like:

	.quad PSCI_0_2_FN_PSCI_VERSION,		psci_0_2_psci_version
	.quad PSCI_0_2_FN64_CPU_SUSPEND,	psci_0_2_cpu_suspend_64
	.quad PSCI_0_2_FN64_CPU_ON,		psci_0_2_cpu_on_64
	.quad PSCI_0_2_FN64_AFFINITY_INFO,	psci_0_2_affinity_info_64
	.quad PSCI_0_2_FN64_MIGRATE,		psci_0_2_migrate_64
	.quad PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU,	psci_0_2_migrate_info_up_cpu_64
	.quad 0, 				0

As that would make the relationship between IDs and functions clearer (at least to me). Maybe a macro could make this less painful.

Quoted 8 lines
arch/arm/cpu/armv8/psci.S new file +8 -0
+.macro	psci_enter
+	stp	x29, x30, [sp, #-16]!
+	stp	x27, x28, [sp, #-16]!
+	stp	x25, x26, [sp, #-16]!
+	stp	x23, x24, [sp, #-16]!
+	stp	x21, x22, [sp, #-16]!
+	stp	x19, x20, [sp, #-16]!
+	stp	x17, x18, [sp, #-16]!

arch/arm/cpu/armv8/psci.S line 72

Quoted 10 lines
arch/arm/cpu/armv8/psci.S new file +10 -0
+	stp	x15, x16, [sp, #-16]!
+	stp	x13, x14, [sp, #-16]!
+	stp	x11, x12, [sp, #-16]!
+	stp	x9, x10, [sp, #-16]!
+	stp	x7, x8, [sp, #-16]!
+	stp	x5, x6, [sp, #-16]!
+	mrs	x5, elr_el3
+	stp	x5, x4, [sp, #-16]!
+
+	/* EL0 and El1 will execute in secure */

I think this would be better as:

	/* U-Boot will run on the secure side */

arch/arm/cpu/armv8/psci.S line 79

Quoted 7 lines
arch/arm/cpu/armv8/psci.S new file +7 -0
+	mrs	x4, scr_el3
+	bic	x4, x4, #1
+	msr	scr_el3, x4
+.endm
+
+.macro	psci_return
+	/* EL0 and El1 will execute in non-secure */

Similarly:

	/* The OS will run on the non-secure side */
Quoted 11 lines
arch/arm/cpu/armv8/psci.S new file +11 -0
+	mrs	x4, scr_el3
+	orr	x4, x4, #1
+	msr	scr_el3, x4
+
+	ldp	x5, x4, [sp], #16
+	msr	elr_el3, x5
+	ldp	x5, x6, [sp], #16
+	ldp	x7, x8, [sp], #16
+	ldp	x9, x10, [sp], #16
+	ldp	x11, x12, [sp], #16
+	ldp	x13, x14, [sp], #16

arch/arm/cpu/armv8/psci.S line 100

Quoted 10 lines
arch/arm/cpu/armv8/psci.S new file +10 -0
+	ldp	x15, x16, [sp], #16
+	ldp	x17, x18, [sp], #16
+	ldp	x19, x20, [sp], #16
+	ldp	x21, x22, [sp], #16
+	ldp	x23, x24, [sp], #16
+	ldp	x25, x26, [sp], #16
+	ldp	x27, x28, [sp], #16
+	ldp	x29, x30, [sp], #16
+	eret
+.endm

PSCI 0.2 follows the SMC calling convention, where x0-x17 are caller-saved as with the usual AArch64 calling conventions, so we don't need to save/restore them here for AArch64 callers.

We do need to ensure we don't clobber x18-x30, sp_elx and sp_el0. The calling convention is ambiguous as to whether we can clobber sp_el1, but for the moment I'd assume we shouldn't.

For AArch32 callers, only x0-x3 are caller-saved.

arch/arm/cpu/armv8/psci.S line 106

Quoted 5 lines
arch/arm/cpu/armv8/psci.S new file +5 -0
+ENTRY(_smc_psci)
+	psci_enter
+	adr	x4, _psci_0_2_table
+1:	ldr	x5, [x4]		/* Load PSCI function ID */
+	ldr	x6, [x4, #8]		/* Load target PC */

1: ldp x5, x6, [x4] /* Load function ID and handler addr */

arch/arm/cpu/armv8/psci.S line 108

Quoted 2 lines
arch/arm/cpu/armv8/psci.S new file +2 -0
+	cmp	x5, #0			/* If reach the end, bail out */
+	b.eq	fn_not_found

cbz x5, fn_not_found /* If reach the end, bail out */

arch/arm/cpu/armv8/psci.S line 119

Quoted 11 lines
arch/arm/cpu/armv8/psci.S new file +11 -0
+	cmp	x0, x5			/* If not matching, try next entry */
+	b.eq	fn_call
+	add	x4, x4, #16
+	b	1b
+
+fn_call:
+	blr	x6
+	psci_return
+
+fn_not_found:
+	mov	x0, #ARM_PSCI_RET_INVAL  /* Return -2 (Invalid) */

I believe this should be NOT_SUPPORTED (-1), which states that the PSCI implementation doesn't implement this function rather than the arguments to the function were invalid.

arch/arm/cpu/armv8/psci.S line 125

Quoted 6 lines
arch/arm/cpu/armv8/psci.S new file +6 -0
+	psci_return
+ENDPROC(_smc_psci)
+
+ENTRY(default_psci_vector)
+	eret
+ENDPROC(default_psci_vector)

This looks misnamed. This is the vector for exceptions triggered by something other than PSCI.

That said I think we need to do something else here. If we haven't handled the exception we're likely to just return to whatever caused it and take the same exception again.

A failstop behaviour would seem better if the only other exceptions we expect to take are fatal anyway.

arch/arm/cpu/armv8/psci.S line 127

Quoted 1 line
arch/arm/cpu/armv8/psci.S new file +1 -0
+.align 2

I don't think this is necessary; we had code immediately before.

arch/arm/cpu/armv8/psci.S line 132

Quoted 5 lines
arch/arm/cpu/armv8/psci.S new file +5 -0
+__handle_sync:
+	str 	x4, [sp, #-8]!
+	mrs	x4, esr_el3
+	ubfx	x4, x4, #26, #6
+	cmp	x4, #0x17

Could we not have a macro like ESR_EC_SMC64 instead of the #17?

Thanks,
Mark.

Quoted 43 lines
arch/arm/cpu/armv8/psci.S new file +39 -0
+	b.eq	smc_found
+	ldr	x4, [sp], #8
+	b	default_psci_vector
+smc_found:
+	ldr     x4, [sp], #8
+	b	_smc_psci
+
+/*
+ * PSCI Exception vectors.
+ */
+	.align	11
+	.globl	psci_vectors
+psci_vectors:
+	.align	7
+	b	default_psci_vector	/* Current EL Synchronous Thread */
+	.align	7
+	b	default_psci_vector	/* Current EL IRQ Thread */
+	.align	7
+	b	default_psci_vector	/* Current EL FIQ Thread */
+	.align	7
+	b	default_psci_vector	/* Current EL Error Thread */
+	.align	7
+	b	default_psci_vector	/* Current EL Synchronous Handler */
+	.align	7
+	b	default_psci_vector	/* Current EL IRQ Handler */
+	.align	7
+	b	default_psci_vector	/* Current EL FIQ Handler */
+	.align	7
+	b	default_psci_vector	/* Current EL Error Handler */
+	.align	7
+	b	__handle_sync		/* Lower EL Synchronous (64b) */
+	.align	7
+	b	default_psci_vector	/* Lower EL IRQ (64b) */
+	.align	7
+	b	default_psci_vector	/* Lower EL FIQ (64b) */
+	.align	7
+	b	default_psci_vector	/* Lower EL Error (64b) */
+
+.popsection
Signature · 1 line
1.7.7.4
author
#19 lore raw

PATCH 6/8 ARMv8: PSCI: Fixup the device tree for PSCI v0.2

In reply to Arnab Basu

Set the enable-method in the cpu node to psci, create the psci device tree node and also add a reserve section for the psci code that lives in in normal RAM, so that the kernel leaves it alone

---
 arch/arm/cpu/armv8/cpu-dt.c   |   67 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/include/asm/system.h |    4 ++
 2 files changed, 71 insertions(+), 0 deletions(-)
arch/arm/cpu/armv8/cpu-dt.c +67 -0
index 9792bc0..c2c8fe7 100644
@@ -9,7 +9,69 @@
 #include <fdt_support.h>
 
 #ifdef CONFIG_MP
+#ifdef CONFIG_ARMV8_PSCI
 
+static void psci_reserve_mem(void *fdt)
+{
+#ifndef CONFIG_ARMV8_SECURE_BASE
+	/* secure code lives in RAM, keep it alive */
+	fdt_add_mem_rsv(fdt, (unsigned long)__secure_start,
+			__secure_end - __secure_start);
+#endif
+}
+
+static int cpu_update_dt_psci(void *fdt)
+{
+	int nodeoff;
+	int tmp;
+
+	psci_reserve_mem(fdt);
+
+	nodeoff = fdt_path_offset(fdt, "/cpus");
+	if (nodeoff < 0) {
+		printf("couldn't find /cpus\n");
+		return nodeoff;
+	}
+
+	/* add 'enable-method = "psci"' to each cpu node */
+	for (tmp = fdt_first_subnode(fdt, nodeoff);
+	     tmp >= 0;
+	     tmp = fdt_next_subnode(fdt, tmp)) {
+		const struct fdt_property *prop;
+		int len;
+
+		prop = fdt_get_property(fdt, tmp, "device_type", &len);
+		if (!prop)
+			continue;
+		if (len < 4)
+			continue;
+		if (strcmp(prop->data, "cpu"))
+			continue;
+
+		fdt_setprop_string(fdt, tmp, "enable-method", "psci");
+	}
+
+	nodeoff = fdt_path_offset(fdt, "/psci");
+	if (nodeoff < 0) {
+		nodeoff = fdt_path_offset(fdt, "/");
+		if (nodeoff < 0)
+			return nodeoff;
+
+		nodeoff = fdt_add_subnode(fdt, nodeoff, "psci");
+		if (nodeoff < 0)
+			return nodeoff;
+	}
+
+	tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci-0.2");
+	if (tmp)
+		return tmp;
+	tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc");
+	if (tmp)
+		return tmp;
+
+	return 0;
+}
+#else
 __weak u64 arch_get_release_addr(u64 cpu_id)
 {
 	return 0;
@@ -51,11 +113,16 @@ static void cpu_update_dt_spin_table(void *blob)
 	arch_spin_table_reserve_mem(blob);
 }
 #endif
+#endif
 
 int cpu_update_dt(void *fdt)
 {
 #ifdef CONFIG_MP
+#ifdef CONFIG_ARMV8_PSCI
+	cpu_update_dt_psci(fdt);
+#else
 	cpu_update_dt_spin_table(fdt);
 #endif
+#endif
 	return 0;
 }
arch/arm/include/asm/system.h +4 -0
index d51ba66..a1066d4 100644
@@ -77,6 +77,10 @@ void gic_init(void);
 void gic_send_sgi(unsigned long sgino);
 void wait_for_wakeup(void);
 void smp_kick_all_cpus(void);
+#ifdef CONFIG_ARMV8_PSCI
+extern char __secure_start[];
+extern char __secure_end[];
+#endif
 
 void flush_l3_cache(void);
 
Signature · 1 line
1.7.7.4
#20 lore raw

PATCH 6/8 ARMv8: PSCI: Fixup the device tree for PSCI v0.2

Hi,

Quoted 20 lines · Arnab Basu

Set the enable-method in the cpu node to psci, create the psci device tree node and also add a reserve section for the psci code that lives in in normal RAM, so that the kernel leaves it alone

---
 arch/arm/cpu/armv8/cpu-dt.c   |   67 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/include/asm/system.h |    4 ++
 2 files changed, 71 insertions(+), 0 deletions(-)
arch/arm/cpu/armv8/cpu-dt.c +0 -0
index 9792bc0..c2c8fe7 100644
@@ -9,7 +9,69 @@
 #include <fdt_support.h>
 
 #ifdef CONFIG_MP

arch/arm/cpu/armv8/cpu-dt.c line 21

Quoted 10 lines
arch/arm/cpu/armv8/cpu-dt.c +9 -0
+#ifdef CONFIG_ARMV8_PSCI
 
+static void psci_reserve_mem(void *fdt)
+{
+#ifndef CONFIG_ARMV8_SECURE_BASE
+	/* secure code lives in RAM, keep it alive */
+	fdt_add_mem_rsv(fdt, (unsigned long)__secure_start,
+			__secure_end - __secure_start);
+#endif
+}

With PSCI I'd be worried about telling the OS about this memory at all.

If the OS maps the memory we could encounter issues with mismatched aliases and/or unexpected hits in the D-cache, which can result in a loss of ordering and/or visbility guarantees, which could break the PSCI implementation.

With the KVM or trusted firmware PSCI implementations the (guest) OS cannot map the implementation's memory, preventing such problems. The arm64 Linux boot-wrapper is dodgy in this regard currently.

Quoted 19 lines
arch/arm/cpu/armv8/cpu-dt.c +19 -0
+static int cpu_update_dt_psci(void *fdt)
+{
+	int nodeoff;
+	int tmp;
+
+	psci_reserve_mem(fdt);
+
+	nodeoff = fdt_path_offset(fdt, "/cpus");
+	if (nodeoff < 0) {
+		printf("couldn't find /cpus\n");
+		return nodeoff;
+	}
+
+	/* add 'enable-method = "psci"' to each cpu node */
+	for (tmp = fdt_first_subnode(fdt, nodeoff);
+	     tmp >= 0;
+	     tmp = fdt_next_subnode(fdt, tmp)) {
+		const struct fdt_property *prop;
+		int len;

arch/arm/cpu/armv8/cpu-dt.c line 51

Quoted 10 lines
arch/arm/cpu/armv8/cpu-dt.c +10 -0
+
+		prop = fdt_get_property(fdt, tmp, "device_type", &len);
+		if (!prop)
+			continue;
+		if (len < 4)
+			continue;
+		if (strcmp(prop->data, "cpu"))
+			continue;
+
+		fdt_setprop_string(fdt, tmp, "enable-method", "psci");

Do we need to check the return code here, as we do when setting up the psci node?

arch/arm/cpu/armv8/cpu-dt.c line 54

Quoted 3 lines
arch/arm/cpu/armv8/cpu-dt.c +3 -0
+	}
+
+	nodeoff = fdt_path_offset(fdt, "/psci");

We might need to search by compatible string. All psci nodes so far have been called /psci, but that's not guaranteed. Linux looks for nodes compatible with "arm,psci" and/or "arm,psci-0.2".

Quoted 9 lines
arch/arm/cpu/armv8/cpu-dt.c +9 -0
+	if (nodeoff < 0) {
+		nodeoff = fdt_path_offset(fdt, "/");
+		if (nodeoff < 0)
+			return nodeoff;
+
+		nodeoff = fdt_add_subnode(fdt, nodeoff, "psci");
+		if (nodeoff < 0)
+			return nodeoff;
+	}

arch/arm/cpu/armv8/cpu-dt.c line 73

Quoted 10 lines
arch/arm/cpu/armv8/cpu-dt.c +10 -0
+
+	tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci-0.2");
+	if (tmp)
+		return tmp;
+	tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc");
+	if (tmp)
+		return tmp;
+
+	return 0;
+}

Otherwise this looks fine.

Mark.

author
#21 lore raw

PATCH 6/8 ARMv8: PSCI: Fixup the device tree for PSCI v0.2

Hi Mark

Quoted 36 lines · Mark Rutland

Hi,

Quoted 20 lines · Arnab Basu

Set the enable-method in the cpu node to psci, create the psci device tree node and also add a reserve section for the psci code that lives in in normal RAM, so that the kernel leaves it alone

---
  arch/arm/cpu/armv8/cpu-dt.c   |   67 +++++++++++++++++++++++++++++++++++++++++
  arch/arm/include/asm/system.h |    4 ++
  2 files changed, 71 insertions(+), 0 deletions(-)
arch/arm/cpu/armv8/cpu-dt.c +0 -0
index 9792bc0..c2c8fe7 100644
@@ -9,7 +9,69 @@
  #include <fdt_support.h>
 
  #ifdef CONFIG_MP

arch/arm/cpu/armv8/cpu-dt.c line 21

Quoted 10 lines
arch/arm/cpu/armv8/cpu-dt.c +9 -0
+#ifdef CONFIG_ARMV8_PSCI
 
+static void psci_reserve_mem(void *fdt)
+{
+#ifndef CONFIG_ARMV8_SECURE_BASE
+	/* secure code lives in RAM, keep it alive */
+	fdt_add_mem_rsv(fdt, (unsigned long)__secure_start,
+			__secure_end - __secure_start);
+#endif
+}

With PSCI I'd be worried about telling the OS about this memory at all.

Quoted 9 lines

If the OS maps the memory we could encounter issues with mismatched aliases and/or unexpected hits in the D-cache, which can result in a loss of ordering and/or visbility guarantees, which could break the PSCI implementation.

With the KVM or trusted firmware PSCI implementations the (guest) OS cannot map the implementation's memory, preventing such problems. The arm64 Linux boot-wrapper is dodgy in this regard currently.

The idea here is that if there is no PSCI specific (most likely secure) memory allocated in the system, the macro "CONFIG_ARMV8_SECURE_BASE" will not be defined. In this case the PSCI vector table and its support code will be in DDR and will be protected from Linux using memreserve.

If this macro is defined the assumption is that it points to some non-ddr location, say secure OCRAM. In this case U-Boot will copy the PSCI vector table and its support code to that region and we are hoping that this address space is not visible to the OS in the first place.

This is my understanding of the code, maybe Marc would like to comment on if this was the thinking in ARMv7.

I realise that this probably needs to be documented.

Quoted 24 lines
Quoted 24 lines
arch/arm/cpu/armv8/cpu-dt.c +24 -0
+static int cpu_update_dt_psci(void *fdt)
+{
+	int nodeoff;
+	int tmp;
+
+	psci_reserve_mem(fdt);
+
+	nodeoff = fdt_path_offset(fdt, "/cpus");
+	if (nodeoff < 0) {
+		printf("couldn't find /cpus\n");
+		return nodeoff;
+	}
+
+	/* add 'enable-method = "psci"' to each cpu node */
+	for (tmp = fdt_first_subnode(fdt, nodeoff);
+	     tmp >= 0;
+	     tmp = fdt_next_subnode(fdt, tmp)) {
+		const struct fdt_property *prop;
+		int len;
+
+		prop = fdt_get_property(fdt, tmp, "device_type", &len);
+		if (!prop)
+			continue;
+		if (len < 4)
Quoted 9 lines

arch/arm/cpu/armv8/cpu-dt.c line 51

Quoted 5 lines
arch/arm/cpu/armv8/cpu-dt.c +5 -0
+			continue;
+		if (strcmp(prop->data, "cpu"))
+			continue;
+
+		fdt_setprop_string(fdt, tmp, "enable-method", "psci");

Do we need to check the return code here, as we do when setting up the psci node?

Probably, I'll add it.

Quoted 8 lines

arch/arm/cpu/armv8/cpu-dt.c line 54

Quoted 3 lines
arch/arm/cpu/armv8/cpu-dt.c +3 -0
+	}
+
+	nodeoff = fdt_path_offset(fdt, "/psci");

We might need to search by compatible string. All psci nodes so far have been called /psci, but that's not guaranteed. Linux looks for nodes compatible with "arm,psci" and/or "arm,psci-0.2".

I see that it is called "Main node" in the kernel documentation. Any reason it's name has not been fixed to "psci"? Is it too late to do that and save myself some work here? :)

Quoted 13 lines
Quoted 13 lines
arch/arm/cpu/armv8/cpu-dt.c +13 -0
+	if (nodeoff < 0) {
+		nodeoff = fdt_path_offset(fdt, "/");
+		if (nodeoff < 0)
+			return nodeoff;
+
+		nodeoff = fdt_add_subnode(fdt, nodeoff, "psci");
+		if (nodeoff < 0)
+			return nodeoff;
+	}
+
+	tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci-0.2");
+	if (tmp)
+		return tmp;
Quoted 8 lines

arch/arm/cpu/armv8/cpu-dt.c line 73

Quoted 6 lines
arch/arm/cpu/armv8/cpu-dt.c +6 -0
+	tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc");
+	if (tmp)
+		return tmp;
+
+	return 0;
+}

Otherwise this looks fine.

Thanks

Quoted 3 lines

Mark.

#22 lore raw

PATCH 6/8 ARMv8: PSCI: Fixup the device tree for PSCI v0.2

Hi,

Quoted 31 lines
Quoted 21 lines
Quoted 8 lines
arch/arm/cpu/armv8/cpu-dt.c +0 -0
index 9792bc0..c2c8fe7 100644
@@ -9,7 +9,69 @@
  #include <fdt_support.h>
 
  #ifdef CONFIG_MP

arch/arm/cpu/armv8/cpu-dt.c line 21

Quoted 10 lines
arch/arm/cpu/armv8/cpu-dt.c +9 -0
+#ifdef CONFIG_ARMV8_PSCI
 
+static void psci_reserve_mem(void *fdt)
+{
+#ifndef CONFIG_ARMV8_SECURE_BASE
+	/* secure code lives in RAM, keep it alive */
+	fdt_add_mem_rsv(fdt, (unsigned long)__secure_start,
+			__secure_end - __secure_start);
+#endif
+}

With PSCI I'd be worried about telling the OS about this memory at all.

Quoted 9 lines

If the OS maps the memory we could encounter issues with mismatched aliases and/or unexpected hits in the D-cache, which can result in a loss of ordering and/or visbility guarantees, which could break the PSCI implementation.

With the KVM or trusted firmware PSCI implementations the (guest) OS cannot map the implementation's memory, preventing such problems. The arm64 Linux boot-wrapper is dodgy in this regard currently.

Quoted 4 lines

The idea here is that if there is no PSCI specific (most likely secure) memory allocated in the system, the macro "CONFIG_ARMV8_SECURE_BASE" will not be defined. In this case the PSCI vector table and its support code will be in DDR and will be protected from Linux using memreserve.

Sure, this will prevent the OS from explicitly modifying this memory.

However, the OS will still map the memory. This renders the protection incomplete due to the possibility of mismatched attributes and/or unexpected cache hits resulting in nasty coherency problems. We are likely to get away with this most of the time (if the kernel and U-Boot use the same attributes), but it would be very easy to blow things up accidentally.

The only way to prevent that is to completely remove a portion of the memory from the view of the OS, such that it doesn't map the memory at all.

Quoted 4 lines

If this macro is defined the assumption is that it points to some non-ddr location, say secure OCRAM. In this case U-Boot will copy the PSCI vector table and its support code to that region and we are hoping that this address space is not visible to the OS in the first place.

This makes sense, but was not the issue I was referring to.

Quoted 2 lines

This is my understanding of the code, maybe Marc would like to comment on if this was the thinking in ARMv7.

If we're doing this on ARMv7 then it is dodgy there too.

Marc, thoughts?

[...]

Quoted 9 lines
Quoted 8 lines

arch/arm/cpu/armv8/cpu-dt.c line 54

Quoted 3 lines
arch/arm/cpu/armv8/cpu-dt.c +3 -0
+	}
+
+	nodeoff = fdt_path_offset(fdt, "/psci");

We might need to search by compatible string. All psci nodes so far have been called /psci, but that's not guaranteed. Linux looks for nodes compatible with "arm,psci" and/or "arm,psci-0.2".

Quoted 3 lines

I see that it is called "Main node" in the kernel documentation. Any reason it's name has not been fixed to "psci"? Is it too late to do that and save myself some work here? :)

Unfortunately the canonical way to find the PSCI node is by compatible string, and that's what Linux does. While we might be able to ensure all in-tree dts follow this convention, it's not something that should be relied upon.

Sorry :(

Cheers,
Mark.

#23 lore raw

PATCH 6/8 ARMv8: PSCI: Fixup the device tree for PSCI v0.2

Quoted 47 lines · Mark Rutland

Hi,

Quoted 31 lines
Quoted 21 lines
Quoted 8 lines
arch/arm/cpu/armv8/cpu-dt.c +0 -0
index 9792bc0..c2c8fe7 100644
@@ -9,7 +9,69 @@
  #include <fdt_support.h>
 
  #ifdef CONFIG_MP

arch/arm/cpu/armv8/cpu-dt.c line 21

Quoted 10 lines
arch/arm/cpu/armv8/cpu-dt.c +9 -0
+#ifdef CONFIG_ARMV8_PSCI
 
+static void psci_reserve_mem(void *fdt)
+{
+#ifndef CONFIG_ARMV8_SECURE_BASE
+	/* secure code lives in RAM, keep it alive */
+	fdt_add_mem_rsv(fdt, (unsigned long)__secure_start,
+			__secure_end - __secure_start);
+#endif
+}

With PSCI I'd be worried about telling the OS about this memory at all.

Quoted 9 lines

If the OS maps the memory we could encounter issues with mismatched aliases and/or unexpected hits in the D-cache, which can result in a loss of ordering and/or visbility guarantees, which could break the PSCI implementation.

With the KVM or trusted firmware PSCI implementations the (guest) OS cannot map the implementation's memory, preventing such problems. The arm64 Linux boot-wrapper is dodgy in this regard currently.

Quoted 4 lines

The idea here is that if there is no PSCI specific (most likely secure) memory allocated in the system, the macro "CONFIG_ARMV8_SECURE_BASE" will not be defined. In this case the PSCI vector table and its support code will be in DDR and will be protected from Linux using memreserve.

Sure, this will prevent the OS from explicitly modifying this memory.

However, the OS will still map the memory. This renders the protection incomplete due to the possibility of mismatched attributes and/or unexpected cache hits resulting in nasty coherency problems. We are likely to get away with this most of the time (if the kernel and U-Boot use the same attributes), but it would be very easy to blow things up accidentally.

Quoted 3 lines

The only way to prevent that is to completely remove a portion of the memory from the view of the OS, such that it doesn't map the memory at all.

To clarify:

If the PSCI implementation uses some memory not described to the OS there is no problem. Ideally this would be some secure SRAM somwhere, which the OS can never map. So if you are using some secure RAM then there is no issue.

If the memory is described to the non-secure OS, then there can be coherency issues unless either:

* The caches are not in use at EL3. This necessitates something like bakery locks for synchronization.

* The memory is mapped at EL3 as secure, and the core makes a distinction between secure and non-secure memory (see ID_AA64MMFR0_EL1.SNSMem). Otherwise misatched attributes can cause coherency issues (see B2.9 "Mismatched memory attributes" in the ARM ARM).

Thanks,
Mark.

#24 lore raw

PATCH 6/8 ARMv8: PSCI: Fixup the device tree for PSCI v0.2

In reply to Mark Rutland
Quoted 14 lines
Quoted 4 lines

The idea here is that if there is no PSCI specific (most likely secure) memory allocated in the system, the macro "CONFIG_ARMV8_SECURE_BASE" will not be defined. In this case the PSCI vector table and its support code will be in DDR and will be protected from Linux using memreserve.

Sure, this will prevent the OS from explicitly modifying this memory.

However, the OS will still map the memory. This renders the protection incomplete due to the possibility of mismatched attributes and/or unexpected cache hits resulting in nasty coherency problems. We are likely to get away with this most of the time (if the kernel and U-Boot use the same attributes), but it would be very easy to blow things up accidentally.

Quoted 3 lines

The only way to prevent that is to completely remove a portion of the memory from the view of the OS, such that it doesn't map the memory at all.

Can't this be done by simply removing that secure portion of memory from the memory advertised in the memory node of the device tree passed to the non-secure OS? ...should prevent the OS from mapping the memory.

Stuart

#25 lore raw

PATCH 6/8 ARMv8: PSCI: Fixup the device tree for PSCI v0.2

Quoted 14 lines · Stuart Yoder
Quoted 14 lines
Quoted 4 lines

The idea here is that if there is no PSCI specific (most likely secure) memory allocated in the system, the macro "CONFIG_ARMV8_SECURE_BASE" will not be defined. In this case the PSCI vector table and its support code will be in DDR and will be protected from Linux using memreserve.

Sure, this will prevent the OS from explicitly modifying this memory.

However, the OS will still map the memory. This renders the protection incomplete due to the possibility of mismatched attributes and/or unexpected cache hits resulting in nasty coherency problems. We are likely to get away with this most of the time (if the kernel and U-Boot use the same attributes), but it would be very easy to blow things up accidentally.

Quoted 7 lines
Quoted 3 lines

The only way to prevent that is to completely remove a portion of the memory from the view of the OS, such that it doesn't map the memory at all.

Can't this be done by simply removing that secure portion of memory from the memory advertised in the memory node of the device tree passed to the non-secure OS? ...should prevent the OS from mapping the memory.

Yes, removing such memory entirely from the memory nodes would work.

The only caveat (I believe) is that it would be necessary to remove such memory in 2MB naturally-aligned chunks due to the way Linux maps memory.

I intend to at some point decouple the Linux linear mapping from the text mapping, so that Linux can address meemory below it. So it's vital to remove the memory enitrely from the view of the kernel rather than just loading the kernel 2MB higher.

Mark.

author
#26 lore raw

PATCH 7/8 ARMv8: PSCI: Setup ARMv8 PSCI

In reply to Arnab Basu

Setup the ARMv8 PSCI code just before switching to EL2 and jumping to the kernel.

---
 arch/arm/cpu/armv8/cpu.c      |   23 +++++++++++++++++++++++
 arch/arm/cpu/armv8/psci.S     |    6 ++++++
 arch/arm/include/asm/system.h |    3 +++
 arch/arm/lib/bootm.c          |    3 +++
 4 files changed, 35 insertions(+), 0 deletions(-)
arch/arm/cpu/armv8/cpu.c +23 -0
index e06c3cc..55d2654 100644
@@ -41,3 +41,26 @@ int cleanup_before_linux(void)
 
 	return 0;
 }
+
+#ifdef CONFIG_ARMV8_PSCI
+
+static void relocate_secure_section(void)
+{
+#ifdef CONFIG_ARMV8_SECURE_BASE
+	size_t sz = __secure_end - __secure_start;
+
+	memcpy((void *)CONFIG_ARMV8_SECURE_BASE, __secure_start, sz);
+	flush_dcache_range(CONFIG_ARMV8_SECURE_BASE,
+			   CONFIG_ARMV8_SECURE_BASE + sz + 1);
+	invalidate_icache_all();
+#endif
+}
+
+void setup_psci(void)
+{
+	relocate_secure_section();
+	fixup_vectors();
+	psci_arch_init();
+}
+
+#endif
arch/arm/cpu/armv8/psci.S +6 -0
index 5f4e3b2..9eaad3a 100644
@@ -169,3 +169,9 @@ psci_vectors:
 	b	default_psci_vector	/* Lower EL Error (64b) */
 
 .popsection
+
+ENTRY(fixup_vectors)
+        adr     x0, psci_vectors
+        msr     vbar_el3, x0
+        ret
+ENDPROC(fixup_vectors)
arch/arm/include/asm/system.h +3 -0
index a1066d4..214fed3 100644
@@ -78,6 +78,9 @@ void gic_send_sgi(unsigned long sgino);
 void wait_for_wakeup(void);
 void smp_kick_all_cpus(void);
 #ifdef CONFIG_ARMV8_PSCI
+void setup_psci(void);
+void fixup_vectors(void);
+void psci_arch_init(void);
 extern char __secure_start[];
 extern char __secure_end[];
 #endif
arch/arm/lib/bootm.c +3 -0
index 178e8fb..576c7d5 100644
@@ -251,6 +251,9 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
 	announce_and_cleanup(fake);
 
 	if (!fake) {
+#ifdef CONFIG_ARMV8_PSCI
+		setup_psci();
+#endif
 		do_nonsec_virt_switch();
 		kernel_entry(images->ft_addr);
 	}
Signature · 1 line
1.7.7.4
author
#27 lore raw

PATCH 8/8 ARMv8: PSCI: Enable SMC

In reply to Arnab Basu

Enable the SMC instruction so that the kernel can use the psci code

---
 arch/arm/include/asm/macro.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
arch/arm/include/asm/macro.h +4 -0
index 0009c28..94a1e68 100644
@@ -106,7 +106,11 @@ lr	.req	x30
 .endm
 
 .macro armv8_switch_to_el2_m, xreg1
+#ifdef CONFIG_ARMV8_PSCI
+	mov	\xreg1, #0x531	/* Non-secure EL0/EL1 | HVC | 64bit EL2 */
+#else
 	mov	\xreg1, #0x5b1	/* Non-secure EL0/EL1 | HVC | 64bit EL2 */
+#endif
 	msr	scr_el3, \xreg1
 	msr	cptr_el3, xzr	/* Disable coprocessor traps to EL3 */
 	mov	\xreg1, #0x33ff
Signature · 1 line
1.7.7.4
#28 lore raw

PATCH 8/8 ARMv8: PSCI: Enable SMC

Hi Arnab,

Quoted 14 lines · Arnab Basu

Enable the SMC instruction so that the kernel can use the psci code

---
 arch/arm/include/asm/macro.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
arch/arm/include/asm/macro.h +0 -0
index 0009c28..94a1e68 100644

arch/arm/include/asm/macro.h lr .req x30 · line 112

Quoted 7 lines
arch/arm/include/asm/macro.h +3 -0
@@ -106,7 +106,11 @@ lr	.req	x30
 .endm
 
 .macro armv8_switch_to_el2_m, xreg1
+#ifdef CONFIG_ARMV8_PSCI
+	mov	\xreg1, #0x531	/* Non-secure EL0/EL1 | HVC | 64bit EL2 */
+#else
 	mov	\xreg1, #0x5b1	/* Non-secure EL0/EL1 | HVC | 64bit EL2 */

The 'mov' lines have different constant arguments in the instruction; their explanatory comments should not be the same.

arch/arm/include/asm/macro.h lr .req x30 · line 116

Quoted 4 lines
arch/arm/include/asm/macro.h +1 -0
+#endif
 	msr	scr_el3, \xreg1
 	msr	cptr_el3, xzr	/* Disable coprocessor traps to EL3 */
 	mov	\xreg1, #0x33ff

Amicalement,

Signature · 1 line
Albert.
#29 lore raw

PATCH 8/8 ARMv8: PSCI: Enable SMC

Quoted 30 lines

-----Original Message-----
From: Albert ARIBAUD [mailto:albert.u.boot at aribaud.net]
Sent: Thursday, September 18, 2014 2:48 PM
To: Basu Arnab-B45036
Cc: marc.zyngier at arm.com; mark.rutland at arm.com; Sun York-R58495; Yoder Stuart-B08248; u-boot at lists.denx.de
Subject: Re: [U-Boot] [PATCH 8/8] ARMv8: PSCI: Enable SMC

Hi Arnab,

Quoted 16 lines · Arnab Basu

Enable the SMC instruction so that the kernel can use the psci code

---
 arch/arm/include/asm/macro.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
(quoted diff) +0 -0

b/arch/arm/include/asm/macro.h index 0009c28..94a1e68 100644

arch/arm/include/asm/macro.h +0 -0
@@ -106,7 +106,11 @@ lr	.req	x30
 .endm
 
Quoted 9 lines

arch/arm/include/asm/macro.h lr .req x30 · line 112

Quoted 5 lines
arch/arm/include/asm/macro.h +3 -0
 .macro armv8_switch_to_el2_m, xreg1
+#ifdef CONFIG_ARMV8_PSCI
+	mov	\xreg1, #0x531	/* Non-secure EL0/EL1 | HVC | 64bit EL2 */
+#else
 	mov	\xreg1, #0x5b1	/* Non-secure EL0/EL1 | HVC | 64bit EL2 */

The 'mov' lines have different constant arguments in the instruction; their explanatory comments should not be the same.

Right, I'll fix the comment.

Thanks
Arnab

Quoted 9 lines

arch/arm/include/asm/macro.h lr .req x30 · line 116

Quoted 4 lines
arch/arm/include/asm/macro.h +1 -0
+#endif
 	msr	scr_el3, \xreg1
 	msr	cptr_el3, xzr	/* Disable coprocessor traps to EL3 */
 	mov	\xreg1, #0x33ff

Amicalement,
--
Albert.

author
#30 lore raw

cover PSCI v0.2 framework for ARMv8

In reply to Arnab Basu
Quoted 5 lines · Arnab Basu

This series of patches creates a generic PSCI v0.2 framework for ARMv8.

The first 3 patches refactor existing code so that ARMv7 PSCI, ARMv8 spin-table and ARMv8 PSCI can coexist.

Quoted 7 lines

The next 5 patches create a generic framework for PSCI v0.2 in ARMv8.

The implementation is modelled on the pre-existing PSCI v0.1 support in ARMv7.

PSCI support patches for the ARMv8 Foundation model will follow shortly.

I forgot to mention that this patch set requires the following patches:

http://patchwork.ozlabs.org/patch/381479/
http://patchwork.ozlabs.org/patch/381478/
http://patchwork.ozlabs.org/patch/381480/
http://patchwork.ozlabs.org/patch/381481/
http://patchwork.ozlabs.org/patch/381482/

Quoted 27 lines

Arnab Basu (8):
ARM: PSCI: Update psci.h for psci v0.2
ARM: PSCI: Alow arch specific DT patching ARMv8/fsl-lsch3: Refactor spin-table code
ARMv8: PSCI: Add linker section to hold PSCI code
ARMv8: PCSI: Add generic ARMv8 PSCI code
ARMv8: PSCI: Fixup the device tree for PSCI v0.2
ARMv8: PSCI: Setup ARMv8 PSCI
ARMv8: PSCI: Enable SMC

  arch/arm/config.mk                 |    2 +-
  arch/arm/cpu/armv7/virt-dt.c       |    7 +-
  arch/arm/cpu/armv8/Makefile        |    2 +
  arch/arm/cpu/armv8/cpu-dt.c        |  128 ++++++++++++++++++++++++++
  arch/arm/cpu/armv8/cpu.c           |   23 +++++
  arch/arm/cpu/armv8/fsl-lsch3/fdt.c |   46 +++------
  arch/arm/cpu/armv8/psci.S          |  177 ++++++++++++++++++++++++++++++++++++
  arch/arm/cpu/armv8/u-boot.lds      |   30 ++++++
  arch/arm/include/asm/macro.h       |    4 +
  arch/arm/include/asm/psci.h        |   42 ++++++++-
  arch/arm/include/asm/system.h      |    7 ++
  arch/arm/lib/bootm-fdt.c           |   11 ++-
  arch/arm/lib/bootm.c               |    3 +
  13 files changed, 446 insertions(+), 36 deletions(-)

create mode 100644 arch/arm/cpu/armv8/cpu-dt.c
create mode 100644 arch/arm/cpu/armv8/psci.S

#31 lore raw

cover PSCI v0.2 framework for ARMv8

In reply to Arnab Basu
Quoted 5 lines · Arnab Basu

This series of patches creates a generic PSCI v0.2 framework for ARMv8.

The first 3 patches refactor existing code so that ARMv7 PSCI, ARMv8 spin-table and ARMv8 PSCI can coexist.

Quoted 7 lines

The next 5 patches create a generic framework for PSCI v0.2 in ARMv8.

The implementation is modelled on the pre-existing PSCI v0.1 support in ARMv7.

PSCI support patches for the ARMv8 Foundation model will follow shortly.

What's the status of this effort? I'll look into v0.2 support for v7 soon, so I was wondering if there is something recent to possibly build upon / derive from.

Jan

Signature · 2 lines
Siemens AG, Corporate Technology, CT RTC ITP SES-DE
Corporate Competence Center Embedded Linux
#32 lore raw

cover PSCI v0.2 framework for ARMv8

Quoted 11 lines · Jan Kiszka
Quoted 10 lines · Arnab Basu

This series of patches creates a generic PSCI v0.2 framework for ARMv8.

The first 3 patches refactor existing code so that ARMv7 PSCI, ARMv8 spin-table and ARMv8 PSCI can coexist.

The next 5 patches create a generic framework for PSCI v0.2 in ARMv8.

The implementation is modelled on the pre-existing PSCI v0.1 support in ARMv7.

Quoted 6 lines
Quoted 2 lines

PSCI support patches for the ARMv8 Foundation model will follow shortly.

What's the status of this effort? I'll look into v0.2 support for v7 soon, so I was wondering if there is something recent to possibly build upon / derive from.

When I asked on linux-arm-kernel [1], I was told that Arnab Basu has left Freescale, but intends to continue with this series. I don't know if we're likely to see anything newer at any point soon.

Thanks,
Mark.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-December/307820.html