Skip to contentSkip to conversation

psci cleanups + simple v0.2 implementation

PATCH New Zi Shen Lim 3 participants 10 messages Jan 13, 2015 – Jan 14, 2015 Kbuild

lore
Share & tools
lore
#0 lore raw

cover psci cleanups + simple v0.2 implementation

Hi Mark,

The first couple patches are cleanups.

The third patch switches to using v0.2 function ID values for the existing cpu_{on,off} implementations. This intermediate step is arguably unnecessary given the next patch...

The fourth patch provides a simple implementation of PSCI v0.2. The deviations from spec (primarily cpu_suspend not supported) is noted in code comment as well as in commit log.

Please consider merging.

Thanks,
z

Zi Shen Lim (4):
psci: use MPIDR_INVALID instead of -1
psci: remove sentinel from id_table
psci: use PSCI v0.2 function IDs
psci: implement PSCI v0.2

 Makefile.am |   4 +-
 psci.S      | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 143 insertions(+), 31 deletions(-)
Signature · 1 line
2.1.0
#1 lore raw

PATCH 1/4 psci: use MPIDR_INVALID instead of -1

MPIDR_INVALID was already defined, so use it.

---
 psci.S | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
psci.S +3 -3
index 856095b..234493d 100644
@@ -126,7 +126,7 @@ psci_cpu_on:
 	mov	x0, x1
 
 	bl	find_logical_id
-	cmp	x0, #-1
+	cmp	x0, #MPIDR_INVALID
 	b.eq	1f
 
 	adr	x3, branch_table
@@ -172,7 +172,7 @@ __find_logical_index:
 	b 1b
 2:	mov	x0, x1
 	ret
-3:	mov	x0, #-1
+3:	mov	x0, #MPIDR_INVALID
 	ret
 
 setup_vector:
@@ -207,7 +207,7 @@ spin:
 	ldr	x1, =MPIDR_ID_BITS
 	and	x0, x0, x1
 	bl	find_logical_id
-	cmp	x0, #-1
+	cmp	x0, #MPIDR_INVALID
 	b.eq	spin_dead
 
 	adr	x1, branch_table
Signature · 1 line
2.1.0
#2 lore raw

PATCH 1/4 psci: use MPIDR_INVALID instead of -1

Hi,

Quoted 1 line · Zi Shen Lim

MPIDR_INVALID was already defined, so use it.

MPIDR_INVALID is meant to be an invalid MPIDR value, rather than an error code in the case of an invalid MPIDR.

__find_logical_index is meant to return a logical CPU ID, so returning MPIDR_INVALID isn't quite right.

I'd be happier if we used a separate macro for the logical IDs (e.g. ID_INVALID).

Thanks,
Mark.

Quoted 41 lines
---
 psci.S | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
psci.S +3 -3
index 856095b..234493d 100644
@@ -126,7 +126,7 @@ psci_cpu_on:
 	mov	x0, x1
 
 	bl	find_logical_id
-	cmp	x0, #-1
+	cmp	x0, #MPIDR_INVALID
 	b.eq	1f
 
 	adr	x3, branch_table
@@ -172,7 +172,7 @@ __find_logical_index:
 	b 1b
 2:	mov	x0, x1
 	ret
-3:	mov	x0, #-1
+3:	mov	x0, #MPIDR_INVALID
 	ret
 
 setup_vector:
@@ -207,7 +207,7 @@ spin:
 	ldr	x1, =MPIDR_ID_BITS
 	and	x0, x0, x1
 	bl	find_logical_id
-	cmp	x0, #-1
+	cmp	x0, #MPIDR_INVALID
 	b.eq	spin_dead
 
 	adr	x1, branch_table
Signature · 1 line
2.1.0
#3 lore raw

PATCH 1/4 psci: use MPIDR_INVALID instead of -1

Hi Mark,

Quoted 5 lines · Mark Rutland

Hi,

Quoted 1 line · Zi Shen Lim

MPIDR_INVALID was already defined, so use it.

Quoted 8 lines

MPIDR_INVALID is meant to be an invalid MPIDR value, rather than an error code in the case of an invalid MPIDR.

__find_logical_index is meant to return a logical CPU ID, so returning MPIDR_INVALID isn't quite right.

I'd be happier if we used a separate macro for the logical IDs (e.g. ID_INVALID).

I follow your argument here.

I guess I should've reordered patches 1 and 2.
In patch 2, following removal of the sentinel, MPIDR_INVALID is no longer found in id_table itself.
So MPIDR_INVALID is indeed the "ID_INVALID" you're suggesting.

Are you comfortable with this repurposing of MPIDR_INVALID? Now, MPIDR_INVALID (-1) is consistently used as return value of find_logical_id for an invalid/unknown MPIDR.

Quoted 4 lines

Thanks,
Mark.

#4 lore raw

PATCH 2/4 psci: remove sentinel from id_table

In reply to Zi Shen Lim

Tweak the limit check in find_logical_id so we can do away with the sentinel from id_table.

While at it, also remove unused label and fix up spacing.

---
 psci.S | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
psci.S +2 -4
index 234493d..d045e56 100644
@@ -69,7 +69,6 @@ vector:
 id_table:
 	.quad CPU_IDS
 __id_end:
-	.quad MPIDR_INVALID
 
 .equ	nr_cpus, ((__id_end - id_table) / 8)
 
@@ -159,17 +158,16 @@ psci_cpu_on:
  * Clobbers x1, x2, x3
  */
 find_logical_id:
-__find_logical_index:
 	adr	x2, id_table
 	mov	x1, xzr
 1:	mov	x3, #nr_cpus	// check we haven't walked off the end of the array
 	cmp	x1, x3
-	b.gt	3f
+	b.ge	3f
 	ldr	x3, [x2, x1, lsl #3]
 	cmp	x3, x0
 	b.eq	2f
 	add	x1, x1, #1
-	b 1b
+	b	1b
 2:	mov	x0, x1
 	ret
 3:	mov	x0, #MPIDR_INVALID
Signature · 1 line
2.1.0
#5 lore raw

PATCH 2/4 psci: remove sentinel from id_table

Hi,

Quoted 6 lines · Zi Shen Lim

Tweak the limit check in find_logical_id so we can do away with the sentinel from id_table.

While at it, also remove unused label and fix up spacing.

This looks like a nice cleanup to me.

So long as this passes build and boot testing I'll apply this shortly.

Thanks,
Mark.

Quoted 40 lines
---
 psci.S | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
psci.S +2 -4
index 234493d..d045e56 100644
@@ -69,7 +69,6 @@ vector:
 id_table:
 	.quad CPU_IDS
 __id_end:
-	.quad MPIDR_INVALID
 
 .equ	nr_cpus, ((__id_end - id_table) / 8)
 
@@ -159,17 +158,16 @@ psci_cpu_on:
  * Clobbers x1, x2, x3
  */
 find_logical_id:
-__find_logical_index:
 	adr	x2, id_table
 	mov	x1, xzr
 1:	mov	x3, #nr_cpus	// check we haven't walked off the end of the array
 	cmp	x1, x3
-	b.gt	3f
+	b.ge	3f
 	ldr	x3, [x2, x1, lsl #3]
 	cmp	x3, x0
 	b.eq	2f
 	add	x1, x1, #1
-	b 1b
+	b	1b
 2:	mov	x0, x1
 	ret
 3:	mov	x0, #MPIDR_INVALID
Signature · 1 line
2.1.0
#6 lore raw

PATCH 3/4 psci: use PSCI v0.2 function IDs

In reply to Zi Shen Lim

Update PSCI function IDs to match those defined in v0.2 of the specification.

---
 Makefile.am | 4 ++--
 psci.S      | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
Makefile.am +2 -2
index 0c174e6..4f5bfdd 100644
@@ -25,8 +25,8 @@ BOOTMETHOD	:= psci.o
 PSCI_NODE	:= psci {				\
 			compatible = \"arm,psci\";	\
 			method = \"smc\";		\
-			cpu_on = <0x84000002>;		\
-			cpu_off = <0x84000001>;		\
+			cpu_on = <0xc4000003>;		\
+			cpu_off = <0x84000002>;		\
 		   };
 CPU_NODES	:= $(shell $(top_srcdir)/gen-cpu-nodes.sh $(CPU_IDS))
 CPUS_NODE	:= cpus {		\
psci.S +2 -2
index d045e56..c51e125 100644
@@ -8,8 +8,8 @@
  */
 #include "common.S"
 
-#define PSCI_CPU_OFF		0x84000001
-#define PSCI_CPU_ON		0x84000002
+#define PSCI_CPU_OFF		0x84000002
+#define PSCI_CPU_ON		0xc4000003
 
 #define PSCI_RET_SUCCESS	0
 #define PSCI_RET_NOT_IMPL	(-1)
Signature · 1 line
2.1.0
#7 lore raw

PATCH 4/4 psci: implement PSCI v0.2

In reply to Zi Shen Lim

In this simple implementation:
* cpu_suspend is not supported, and as such is not fully compliant with the spec.
* The system_{off,reset} functions currently just spin on one CPU, when it should instead power {down,cycle} the system.

---
 Makefile.am |   4 +-
 psci.S      | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 138 insertions(+), 24 deletions(-)
Makefile.am +1 -3
index 4f5bfdd..471462a 100644
@@ -23,10 +23,8 @@ BOOTLOADER	:= boot.S
 if PSCI
 BOOTMETHOD	:= psci.o
 PSCI_NODE	:= psci {				\
-			compatible = \"arm,psci\";	\
+			compatible = \"arm,psci-0.2\";	\
 			method = \"smc\";		\
-			cpu_on = <0xc4000003>;		\
-			cpu_off = <0x84000002>;		\
 		   };
 CPU_NODES	:= $(shell $(top_srcdir)/gen-cpu-nodes.sh $(CPU_IDS))
 CPUS_NODE	:= cpus {		\
psci.S +137 -21

234 lines not on this page · raw message

Signature · 1 line
2.1.0
#8 lore raw

cover psci cleanups + simple v0.2 implementation

In reply to Zi Shen Lim
Quoted 1 line · Zi Shen Lim

Hi Mark,

Hi,

Quoted 9 lines

The first couple patches are cleanups.

The third patch switches to using v0.2 function ID values for the existing cpu_{on,off} implementations. This intermediate step is arguably unnecessary given the next patch...

The fourth patch provides a simple implementation of PSCI v0.2. The deviations from spec (primarily cpu_suspend not supported) is noted in code comment as well as in commit log.

While I'm not opposed to implementing PSCI 0.2, the two major reasons for not having implemented it so far were simplicity and spec-compliance. Unless implementing PSCI 0.2 gains us something, I don't see the point in moving from PSCI 0.1.

I think not having any supported CPU_SUSPEND states is fine. For spec compliance I'm more worried by the behaviour of AFFINITY_INFO (as this implementation seems to ignore the lowest_affinity_level parameter), and the behaviour of SYSTEM_{OFF,RESET} -- I wonder if these could be implemented via semihosting.

Given that SYSTEM_OFF and SYSTEM_RESET are effectively not implemented, the only thing that I see we gain from this PSCI 0.2 implementation is AFFINITY_INFO to close a race with CPU_OFF. Is PSCI 0.2 just a nice-to-have feature, or is there something it provides that you particularly want?

I occasionally need to use a new boot-wrapper with old kernels which only handle PSCI 0.1, so we also need to maintain compatiblity in the way the DT binding doc describes:

psci {
	compatible = "arm,psci-0.2", "arm,psci";
	method = "smc";
	cpu_on = < ... >;
	cpu_off = < ... >;
};

Thanks,
Mark.

Quoted 16 lines

Please consider merging.

Thanks, z

Zi Shen Lim (4): psci: use MPIDR_INVALID instead of -1 psci: remove sentinel from id_table psci: use PSCI v0.2 function IDs psci:
implement PSCI v0.2

 Makefile.am |   4 +- psci.S      | 170

++++++++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 143 insertions(+), 31 deletions(-)

-- 2.1.0

#9 lore raw

cover psci cleanups + simple v0.2 implementation

Quoted 11 lines · Mark Rutland
Quoted 1 line · Zi Shen Lim

Hi Mark,

Hi,

Quoted 6 lines

The first couple patches are cleanups.

The third patch switches to using v0.2 function ID values for the existing cpu_{on,off} implementations. This intermediate step is arguably unnecessary given the next patch...

Quoted 8 lines
Quoted 3 lines

The fourth patch provides a simple implementation of PSCI v0.2. The deviations from spec (primarily cpu_suspend not supported) is noted in code comment as well as in commit log.

While I'm not opposed to implementing PSCI 0.2, the two major reasons for not having implemented it so far were simplicity and spec-compliance. Unless implementing PSCI 0.2 gains us something, I don't see the point in moving from PSCI 0.1.

I'm in full agreement here. I don't think we'd want boot-wrapper to become overly complicated - at some point we might as well use ARM Trusted Firmware.

Quoted 2 lines

I think not having any supported CPU_SUSPEND states is fine. For spec

Okay :)

Quoted 2 lines

compliance I'm more worried by the behaviour of AFFINITY_INFO (as this implementation seems to ignore the lowest_affinity_level parameter), and

The simple implementation of psci_affinity_info only supports lowest_affinity_level==0.
Motivation: the known user of this (arch/arm64/kernel/psci.c) only uses lowest_affinity_level=0.
Do we need something more complex?

Quoted 2 lines

the behaviour of SYSTEM_{OFF,RESET} -- I wonder if these could be implemented via semihosting.

Good point. Haven't thought about that option.
I also wonder if linux will use PSCI for these functions.

Quoted 6 lines

Given that SYSTEM_OFF and SYSTEM_RESET are effectively not implemented, the only thing that I see we gain from this PSCI 0.2 implementation is AFFINITY_INFO to close a race with CPU_OFF. Is PSCI 0.2 just a nice-to-have feature, or is there something it provides that you particularly want?

I'm currently using this as baseline for PSCI 0.2 related work. I have other (non-FVP) platform-specific changes as well, but figured at least the generic/common portions could be shared upstream.

Quoted 11 lines

I occasionally need to use a new boot-wrapper with old kernels which only handle PSCI 0.1, so we also need to maintain compatiblity in the way the DT binding doc describes:

psci {
        compatible = "arm,psci-0.2", "arm,psci";
        method = "smc";
        cpu_on = < ... >;
        cpu_off = < ... >;
};

Ok. In that case, along with the DT compatibility above, we'll also need patch 3.

Quoted 20 lines

Thanks,
Mark.

Quoted 16 lines

Please consider merging.

Thanks, z

Zi Shen Lim (4): psci: use MPIDR_INVALID instead of -1 psci: remove sentinel from id_table psci: use PSCI v0.2 function IDs psci:
implement PSCI v0.2

 Makefile.am |   4 +- psci.S      | 170

++++++++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 143 insertions(+), 31 deletions(-)

-- 2.1.0