diff mbox

System reset IPI facility and Mambo implementation

Message ID 20170202142447.14112-1-npiggin@gmail.com
State Changes Requested
Headers show

Commit Message

Nicholas Piggin Feb. 2, 2017, 2:24 p.m. UTC
Add an opal call OPAL_SIGNAL_SYSTEM_RESET which allows system reset
exceptions to be raised on other CPUs and act as an NMI IPI. There
is an initial simple Mambo implementation, but allowances are made
for a more complex hardware implementation.

This is based on the hardware implementation patch by Alistair Popple.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
Hi,

I'm not sure what the state of Alistair's patch is, but it may
make testing easier to initially add this mambo implementation.

Thanks,
Nick

 doc/opal-api/opal-signal-system-reset-145.txt | 31 +++++++++++++++++
 include/opal-api.h                            |  3 +-
 platforms/mambo/mambo.c                       | 48 +++++++++++++++++++++++++++
 3 files changed, 81 insertions(+), 1 deletion(-)
 create mode 100644 doc/opal-api/opal-signal-system-reset-145.txt

Comments

Alistair Popple Feb. 3, 2017, 5:28 a.m. UTC | #1
On Fri, 3 Feb 2017 12:24:47 AM Nicholas Piggin wrote:
> Add an opal call OPAL_SIGNAL_SYSTEM_RESET which allows system reset
> exceptions to be raised on other CPUs and act as an NMI IPI. There
> is an initial simple Mambo implementation, but allowances are made
> for a more complex hardware implementation.
>
> This is based on the hardware implementation patch by Alistair Popple.
>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
> Hi,
>
> I'm not sure what the state of Alistair's patch is, but it may
> make testing easier to initially add this mambo implementation.

My implementation on or P8 hardware probably needs a bit more work and
testing which I haven't found the time to do yet. Having a solid way
for the kernel to call these functions would greatly assist testing
though and this looks like it matches the OPAL API needed for the HW.

Reviewed-by: Alistair Popple <alistair@popple.id.au>

Thanks!

>
> Thanks,
> Nick
>
>  doc/opal-api/opal-signal-system-reset-145.txt | 31 +++++++++++++++++
>  include/opal-api.h                            |  3 +-
>  platforms/mambo/mambo.c                       | 48 +++++++++++++++++++++++++++
>  3 files changed, 81 insertions(+), 1 deletion(-)
>  create mode 100644 doc/opal-api/opal-signal-system-reset-145.txt
>
> diff --git a/doc/opal-api/opal-signal-system-reset-145.txt b/doc/opal-api/opal-signal-system-reset-145.txt
> new file mode 100644
> index 00000000..25b96dbb
> --- /dev/null
> +++ b/doc/opal-api/opal-signal-system-reset-145.txt
> @@ -0,0 +1,31 @@
> +OPAL_SIGNAL_SYSTEM_RESET
> +-------------------
> +
> +#define OPAL_SIGNAL_SYSTEM_RESET			145
> +
> +int64_t signal_system_reset(int32_t cpu_nr)
> +
> +Arguments:
> +
> +  int32_t cpu_nr
> +    Either the cpu server number of the target cpu to reset, or
> +    SYS_RESET_ALL (-1) to indicate all cpus should be reset, or
> +    SYS_RESET_ALL_OTHERS (-2) to indicate all but the current cpu
> +    should be reset.
> +
> +This OPAL call causes the specified cpu(s) to be reset to the system
> +reset exception handler (0x100).
> +
> +The exact contents of system registers (e.g., SRR1 wakeup causes) may
> +vary depending on implementation and should not be relied upon.
> +
> +Resetting active threads on the same core as this call is run may
> +not be supported by some platforms. In that case, OPAL_PARTIAL will be
> +returned and NONE of the interrupts will be delivered.
> +
> +Return Values:
> +OPAL_SUCCESS: the power down was updated successful
> +OPAL_PARAMETER: a parameter was incorrect
> +OPAL_HARDWARE: hardware indicated failure during instruction ramming
> +OPAL_PARTIAL: not all requested cpus could be reset at this time
> +OPAL_UNSUPPORTED: this processor generation is not supported
> diff --git a/include/opal-api.h b/include/opal-api.h
> index c891db97..c32a2fde 100644
> --- a/include/opal-api.h
> +++ b/include/opal-api.h
> @@ -200,7 +200,8 @@
>  #define OPAL_XIVE_RESERVED2			142
>  #define OPAL_XIVE_RESERVED3			143
>  #define OPAL_XIVE_RESERVED4			144
> -#define OPAL_LAST				144
> +#define OPAL_SIGNAL_SYSTEM_RESET		145
> +#define OPAL_LAST				145
>
>  /* Device tree flags */
>
> diff --git a/platforms/mambo/mambo.c b/platforms/mambo/mambo.c
> index 976efeac..3131db9c 100644
> --- a/platforms/mambo/mambo.c
> +++ b/platforms/mambo/mambo.c
> @@ -19,6 +19,7 @@
>  #include <device.h>
>  #include <console.h>
>  #include <chip.h>
> +#include <cpu.h>
>  #include <opal-api.h>
>  #include <opal-internal.h>
>  #include <time-utils.h>
> @@ -211,8 +212,55 @@ static void mambo_rtc_init(void)
>  	opal_register(OPAL_RTC_READ, mambo_rtc_read, 2);
>  }
>
> +static void mambo_system_reset_cpu(struct cpu_thread *cpu)
> +{
> +	uint32_t core_id;
> +	uint32_t thread_id;
> +	char tcl_cmd[50];
> +
> +	core_id = pir_to_core_id(cpu->pir);
> +	thread_id = pir_to_thread_id(cpu->pir);
> +
> +	snprintf(tcl_cmd, sizeof(tcl_cmd), "mysim cpu %i:%i interrupt SystemReset", core_id, thread_id);
> +	callthru_tcl(tcl_cmd, strlen(tcl_cmd));
> +}
> +
> +#define SYS_RESET_ALL		-1
> +#define SYS_RESET_ALL_OTHERS	-2
> +
> +static int64_t mambo_signal_system_reset(int32_t cpu_nr)
> +{
> +	struct cpu_thread *cpu;
> +
> +	if (cpu_nr < 0) {
> +		if (cpu_nr < SYS_RESET_ALL_OTHERS)
> +			return OPAL_PARAMETER;
> +
> +		for_each_cpu(cpu) {
> +			if (cpu_nr == SYS_RESET_ALL_OTHERS && cpu == this_cpu())
> +				continue;
> +			mambo_system_reset_cpu(cpu);
> +		}
> +		return OPAL_SUCCESS;
> +
> +	} else {
> +		cpu = find_cpu_by_server(cpu_nr);
> +		if (!cpu)
> +			return OPAL_PARAMETER;
> +
> +		mambo_system_reset_cpu(cpu);
> +		return OPAL_SUCCESS;
> +	}
> +}
> +
> +static void mambo_sreset_init(void)
> +{
> +	opal_register(OPAL_SIGNAL_SYSTEM_RESET, mambo_signal_system_reset, 1);
> +}
> +
>  static void mambo_platform_init(void)
>  {
> +	mambo_sreset_init();
>  	mambo_rtc_init();
>  	bogus_disk_flash_init();
>  }
>
Stewart Smith Feb. 3, 2017, 6:08 a.m. UTC | #2
Nicholas Piggin <npiggin@gmail.com> writes:
> Add an opal call OPAL_SIGNAL_SYSTEM_RESET which allows system reset
> exceptions to be raised on other CPUs and act as an NMI IPI. There
> is an initial simple Mambo implementation, but allowances are made
> for a more complex hardware implementation.
>
> This is based on the hardware implementation patch by Alistair Popple.
>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
> Hi,
>
> I'm not sure what the state of Alistair's patch is, but it may
> make testing easier to initially add this mambo implementation.

I'm hoping he spins a V2 on top of this patch :)

A thought... this is the kind of functionality that's ideal to get some
kind of test case written for so that we don't go and by accident break
it. So I'm CCing in Pridhiviraj so that it's on the todo list to get
going as part of op-test-framework tests.

> diff --git a/doc/opal-api/opal-signal-system-reset-145.txt b/doc/opal-api/opal-signal-system-reset-145.txt
> new file mode 100644
> index 00000000..25b96dbb
> --- /dev/null
> +++ b/doc/opal-api/opal-signal-system-reset-145.txt

FYI, we've moved to .rst and ReSTructured text, but it's not a big deal,
I can convert when merging if needed.

> @@ -0,0 +1,31 @@
> +OPAL_SIGNAL_SYSTEM_RESET
> +-------------------
> +
> +#define OPAL_SIGNAL_SYSTEM_RESET			145
> +
> +int64_t signal_system_reset(int32_t cpu_nr)
> +
> +Arguments:
> +
> +  int32_t cpu_nr
> +    Either the cpu server number of the target cpu to reset, or
> +    SYS_RESET_ALL (-1) to indicate all cpus should be reset, or
> +    SYS_RESET_ALL_OTHERS (-2) to indicate all but the current cpu
> +    should be reset.
> +
> +This OPAL call causes the specified cpu(s) to be reset to the system
> +reset exception handler (0x100).
> +
> +The exact contents of system registers (e.g., SRR1 wakeup causes) may
> +vary depending on implementation and should not be relied upon.
> +
> +Resetting active threads on the same core as this call is run may
> +not be supported by some platforms. In that case, OPAL_PARTIAL will be
> +returned and NONE of the interrupts will be delivered.

Cool - I gather the API definition has settled down a bit?

For OPAL_PARTIAL, does the "and none were delivered" also apply to
SYS_RESET_ALL_OTHERS ? I'd guess not, but we may want to be explicit.

> +Return Values:
> +OPAL_SUCCESS: the power down was updated successful
> +OPAL_PARAMETER: a parameter was incorrect
> +OPAL_HARDWARE: hardware indicated failure during instruction ramming
> +OPAL_PARTIAL: not all requested cpus could be reset at this time
> +OPAL_UNSUPPORTED: this processor generation is not supported
> diff --git a/include/opal-api.h b/include/opal-api.h
> index c891db97..c32a2fde 100644
> --- a/include/opal-api.h
> +++ b/include/opal-api.h
> @@ -200,7 +200,8 @@
>  #define OPAL_XIVE_RESERVED2			142
>  #define OPAL_XIVE_RESERVED3			143
>  #define OPAL_XIVE_RESERVED4			144
> -#define OPAL_LAST				144
> +#define OPAL_SIGNAL_SYSTEM_RESET		145
> +#define OPAL_LAST				145
>  
>  /* Device tree flags */
>  
> diff --git a/platforms/mambo/mambo.c b/platforms/mambo/mambo.c
> index 976efeac..3131db9c 100644
> --- a/platforms/mambo/mambo.c
> +++ b/platforms/mambo/mambo.c
> @@ -19,6 +19,7 @@
>  #include <device.h>
>  #include <console.h>
>  #include <chip.h>
> +#include <cpu.h>
>  #include <opal-api.h>
>  #include <opal-internal.h>
>  #include <time-utils.h>
> @@ -211,8 +212,55 @@ static void mambo_rtc_init(void)
>  	opal_register(OPAL_RTC_READ, mambo_rtc_read, 2);
>  }
>  
> +static void mambo_system_reset_cpu(struct cpu_thread *cpu)
> +{
> +	uint32_t core_id;
> +	uint32_t thread_id;
> +	char tcl_cmd[50];
> +
> +	core_id = pir_to_core_id(cpu->pir);
> +	thread_id = pir_to_thread_id(cpu->pir);
> +
> +	snprintf(tcl_cmd, sizeof(tcl_cmd), "mysim cpu %i:%i interrupt SystemReset", core_id, thread_id);
> +	callthru_tcl(tcl_cmd, strlen(tcl_cmd));
> +}
> +
> +#define SYS_RESET_ALL		-1
> +#define SYS_RESET_ALL_OTHERS	-2
> +
> +static int64_t mambo_signal_system_reset(int32_t cpu_nr)
> +{
> +	struct cpu_thread *cpu;
> +
> +	if (cpu_nr < 0) {
> +		if (cpu_nr < SYS_RESET_ALL_OTHERS)
> +			return OPAL_PARAMETER;
> +
> +		for_each_cpu(cpu) {
> +			if (cpu_nr == SYS_RESET_ALL_OTHERS && cpu == this_cpu())
> +				continue;
> +			mambo_system_reset_cpu(cpu);

For SYS_RESET_ALL, If we're not running on the last CPU, we would reset
ourselves before we could reset ourselves before we reset the others, right?

otherwise looks good.
Nicholas Piggin Feb. 3, 2017, 8:28 a.m. UTC | #3
On Fri, 03 Feb 2017 17:08:51 +1100
Stewart Smith <stewart@linux.vnet.ibm.com> wrote:

> Nicholas Piggin <npiggin@gmail.com> writes:
> > Add an opal call OPAL_SIGNAL_SYSTEM_RESET which allows system reset
> > exceptions to be raised on other CPUs and act as an NMI IPI. There
> > is an initial simple Mambo implementation, but allowances are made
> > for a more complex hardware implementation.
> >
> > This is based on the hardware implementation patch by Alistair Popple.
> >
> > Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> > ---
> > Hi,
> >
> > I'm not sure what the state of Alistair's patch is, but it may
> > make testing easier to initially add this mambo implementation.  
> 
> I'm hoping he spins a V2 on top of this patch :)
> 
> A thought... this is the kind of functionality that's ideal to get some
> kind of test case written for so that we don't go and by accident break
> it. So I'm CCing in Pridhiviraj so that it's on the todo list to get
> going as part of op-test-framework tests.
> 
> > diff --git a/doc/opal-api/opal-signal-system-reset-145.txt b/doc/opal-api/opal-signal-system-reset-145.txt
> > new file mode 100644
> > index 00000000..25b96dbb
> > --- /dev/null
> > +++ b/doc/opal-api/opal-signal-system-reset-145.txt  
> 
> FYI, we've moved to .rst and ReSTructured text, but it's not a big deal,
> I can convert when merging if needed.
> 
> > @@ -0,0 +1,31 @@
> > +OPAL_SIGNAL_SYSTEM_RESET
> > +-------------------
> > +
> > +#define OPAL_SIGNAL_SYSTEM_RESET			145
> > +
> > +int64_t signal_system_reset(int32_t cpu_nr)
> > +
> > +Arguments:
> > +
> > +  int32_t cpu_nr
> > +    Either the cpu server number of the target cpu to reset, or
> > +    SYS_RESET_ALL (-1) to indicate all cpus should be reset, or
> > +    SYS_RESET_ALL_OTHERS (-2) to indicate all but the current cpu
> > +    should be reset.
> > +
> > +This OPAL call causes the specified cpu(s) to be reset to the system
> > +reset exception handler (0x100).
> > +
> > +The exact contents of system registers (e.g., SRR1 wakeup causes) may
> > +vary depending on implementation and should not be relied upon.
> > +
> > +Resetting active threads on the same core as this call is run may
> > +not be supported by some platforms. In that case, OPAL_PARTIAL will be
> > +returned and NONE of the interrupts will be delivered.  
> 
> Cool - I gather the API definition has settled down a bit?

Yes, although we're still deciding whether to expose this OPAL_PARTIAL
and have the OS fix it up, or handle it all in opal by having a system
reset interrupt call in opal (see the other reply to Linux implementation
patch).

> For OPAL_PARTIAL, does the "and none were delivered" also apply to
> SYS_RESET_ALL_OTHERS ? I'd guess not, but we may want to be explicit.

Well if we do expose this to Linux, it would be easier to ensure none
are delivered (and that's what my Linux implementation assumed). We
want to avoid sending multiple NMIs to any CPU.


> > +static int64_t mambo_signal_system_reset(int32_t cpu_nr)
> > +{
> > +	struct cpu_thread *cpu;
> > +
> > +	if (cpu_nr < 0) {
> > +		if (cpu_nr < SYS_RESET_ALL_OTHERS)
> > +			return OPAL_PARAMETER;
> > +
> > +		for_each_cpu(cpu) {
> > +			if (cpu_nr == SYS_RESET_ALL_OTHERS && cpu == this_cpu())
> > +				continue;
> > +			mambo_system_reset_cpu(cpu);  
> 
> For SYS_RESET_ALL, If we're not running on the last CPU, we would reset
> ourselves before we could reset ourselves before we reset the others, right?

Yeah that's a good catch and I was just thinking about it. We should
do ours last.

The Linux implementation doesn't actually use _ALL broadcasts, but the
hypercall has it and so I've thought it could go in the API. A platform
can return PARTIAL if it doesn't want to support it. There was some
idea it might be useful to pull *all* CPUs into known states on emergency
stacks in some cases, so we may yet consider using it.

Thanks,
Nick
Stewart Smith Feb. 6, 2017, 8:18 a.m. UTC | #4
Nicholas Piggin <npiggin@gmail.com> writes:

> On Fri, 03 Feb 2017 17:08:51 +1100
> Stewart Smith <stewart@linux.vnet.ibm.com> wrote:
>
>> Nicholas Piggin <npiggin@gmail.com> writes:
>> > Add an opal call OPAL_SIGNAL_SYSTEM_RESET which allows system reset
>> > exceptions to be raised on other CPUs and act as an NMI IPI. There
>> > is an initial simple Mambo implementation, but allowances are made
>> > for a more complex hardware implementation.
>> >
>> > This is based on the hardware implementation patch by Alistair Popple.
>> >
>> > Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
>> > ---
>> > Hi,
>> >
>> > I'm not sure what the state of Alistair's patch is, but it may
>> > make testing easier to initially add this mambo implementation.  
>> 
>> I'm hoping he spins a V2 on top of this patch :)
>> 
>> A thought... this is the kind of functionality that's ideal to get some
>> kind of test case written for so that we don't go and by accident break
>> it. So I'm CCing in Pridhiviraj so that it's on the todo list to get
>> going as part of op-test-framework tests.
>> 
>> > diff --git a/doc/opal-api/opal-signal-system-reset-145.txt b/doc/opal-api/opal-signal-system-reset-145.txt
>> > new file mode 100644
>> > index 00000000..25b96dbb
>> > --- /dev/null
>> > +++ b/doc/opal-api/opal-signal-system-reset-145.txt  
>> 
>> FYI, we've moved to .rst and ReSTructured text, but it's not a big deal,
>> I can convert when merging if needed.
>> 
>> > @@ -0,0 +1,31 @@
>> > +OPAL_SIGNAL_SYSTEM_RESET
>> > +-------------------
>> > +
>> > +#define OPAL_SIGNAL_SYSTEM_RESET			145
>> > +
>> > +int64_t signal_system_reset(int32_t cpu_nr)
>> > +
>> > +Arguments:
>> > +
>> > +  int32_t cpu_nr
>> > +    Either the cpu server number of the target cpu to reset, or
>> > +    SYS_RESET_ALL (-1) to indicate all cpus should be reset, or
>> > +    SYS_RESET_ALL_OTHERS (-2) to indicate all but the current cpu
>> > +    should be reset.
>> > +
>> > +This OPAL call causes the specified cpu(s) to be reset to the system
>> > +reset exception handler (0x100).
>> > +
>> > +The exact contents of system registers (e.g., SRR1 wakeup causes) may
>> > +vary depending on implementation and should not be relied upon.
>> > +
>> > +Resetting active threads on the same core as this call is run may
>> > +not be supported by some platforms. In that case, OPAL_PARTIAL will be
>> > +returned and NONE of the interrupts will be delivered.  
>> 
>> Cool - I gather the API definition has settled down a bit?
>
> Yes, although we're still deciding whether to expose this OPAL_PARTIAL
> and have the OS fix it up, or handle it all in opal by having a system
> reset interrupt call in opal (see the other reply to Linux implementation
> patch).
>
>> For OPAL_PARTIAL, does the "and none were delivered" also apply to
>> SYS_RESET_ALL_OTHERS ? I'd guess not, but we may want to be explicit.
>
> Well if we do expose this to Linux, it would be easier to ensure none
> are delivered (and that's what my Linux implementation assumed). We
> want to avoid sending multiple NMIs to any CPU.
>
>
>> > +static int64_t mambo_signal_system_reset(int32_t cpu_nr)
>> > +{
>> > +	struct cpu_thread *cpu;
>> > +
>> > +	if (cpu_nr < 0) {
>> > +		if (cpu_nr < SYS_RESET_ALL_OTHERS)
>> > +			return OPAL_PARAMETER;
>> > +
>> > +		for_each_cpu(cpu) {
>> > +			if (cpu_nr == SYS_RESET_ALL_OTHERS && cpu == this_cpu())
>> > +				continue;
>> > +			mambo_system_reset_cpu(cpu);  
>> 
>> For SYS_RESET_ALL, If we're not running on the last CPU, we would reset
>> ourselves before we could reset ourselves before we reset the others, right?
>
> Yeah that's a good catch and I was just thinking about it. We should
> do ours last.
>
> The Linux implementation doesn't actually use _ALL broadcasts, but the
> hypercall has it and so I've thought it could go in the API. A platform
> can return PARTIAL if it doesn't want to support it. There was some
> idea it might be useful to pull *all* CPUs into known states on emergency
> stacks in some cases, so we may yet consider using it.

ack. I'll await a v2 with the SYS_RESET_ALL fix and I think it looks
good to go.
diff mbox

Patch

diff --git a/doc/opal-api/opal-signal-system-reset-145.txt b/doc/opal-api/opal-signal-system-reset-145.txt
new file mode 100644
index 00000000..25b96dbb
--- /dev/null
+++ b/doc/opal-api/opal-signal-system-reset-145.txt
@@ -0,0 +1,31 @@ 
+OPAL_SIGNAL_SYSTEM_RESET
+-------------------
+
+#define OPAL_SIGNAL_SYSTEM_RESET			145
+
+int64_t signal_system_reset(int32_t cpu_nr)
+
+Arguments:
+
+  int32_t cpu_nr
+    Either the cpu server number of the target cpu to reset, or
+    SYS_RESET_ALL (-1) to indicate all cpus should be reset, or
+    SYS_RESET_ALL_OTHERS (-2) to indicate all but the current cpu
+    should be reset.
+
+This OPAL call causes the specified cpu(s) to be reset to the system
+reset exception handler (0x100).
+
+The exact contents of system registers (e.g., SRR1 wakeup causes) may
+vary depending on implementation and should not be relied upon.
+
+Resetting active threads on the same core as this call is run may
+not be supported by some platforms. In that case, OPAL_PARTIAL will be
+returned and NONE of the interrupts will be delivered.
+
+Return Values:
+OPAL_SUCCESS: the power down was updated successful
+OPAL_PARAMETER: a parameter was incorrect
+OPAL_HARDWARE: hardware indicated failure during instruction ramming
+OPAL_PARTIAL: not all requested cpus could be reset at this time
+OPAL_UNSUPPORTED: this processor generation is not supported
diff --git a/include/opal-api.h b/include/opal-api.h
index c891db97..c32a2fde 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -200,7 +200,8 @@ 
 #define OPAL_XIVE_RESERVED2			142
 #define OPAL_XIVE_RESERVED3			143
 #define OPAL_XIVE_RESERVED4			144
-#define OPAL_LAST				144
+#define OPAL_SIGNAL_SYSTEM_RESET		145
+#define OPAL_LAST				145
 
 /* Device tree flags */
 
diff --git a/platforms/mambo/mambo.c b/platforms/mambo/mambo.c
index 976efeac..3131db9c 100644
--- a/platforms/mambo/mambo.c
+++ b/platforms/mambo/mambo.c
@@ -19,6 +19,7 @@ 
 #include <device.h>
 #include <console.h>
 #include <chip.h>
+#include <cpu.h>
 #include <opal-api.h>
 #include <opal-internal.h>
 #include <time-utils.h>
@@ -211,8 +212,55 @@  static void mambo_rtc_init(void)
 	opal_register(OPAL_RTC_READ, mambo_rtc_read, 2);
 }
 
+static void mambo_system_reset_cpu(struct cpu_thread *cpu)
+{
+	uint32_t core_id;
+	uint32_t thread_id;
+	char tcl_cmd[50];
+
+	core_id = pir_to_core_id(cpu->pir);
+	thread_id = pir_to_thread_id(cpu->pir);
+
+	snprintf(tcl_cmd, sizeof(tcl_cmd), "mysim cpu %i:%i interrupt SystemReset", core_id, thread_id);
+	callthru_tcl(tcl_cmd, strlen(tcl_cmd));
+}
+
+#define SYS_RESET_ALL		-1
+#define SYS_RESET_ALL_OTHERS	-2
+
+static int64_t mambo_signal_system_reset(int32_t cpu_nr)
+{
+	struct cpu_thread *cpu;
+
+	if (cpu_nr < 0) {
+		if (cpu_nr < SYS_RESET_ALL_OTHERS)
+			return OPAL_PARAMETER;
+
+		for_each_cpu(cpu) {
+			if (cpu_nr == SYS_RESET_ALL_OTHERS && cpu == this_cpu())
+				continue;
+			mambo_system_reset_cpu(cpu);
+		}
+		return OPAL_SUCCESS;
+
+	} else {
+		cpu = find_cpu_by_server(cpu_nr);
+		if (!cpu)
+			return OPAL_PARAMETER;
+
+		mambo_system_reset_cpu(cpu);
+		return OPAL_SUCCESS;
+	}
+}
+
+static void mambo_sreset_init(void)
+{
+	opal_register(OPAL_SIGNAL_SYSTEM_RESET, mambo_signal_system_reset, 1);
+}
+
 static void mambo_platform_init(void)
 {
+	mambo_sreset_init();
 	mambo_rtc_init();
 	bogus_disk_flash_init();
 }