Message ID | 20170202142447.14112-1-npiggin@gmail.com |
---|---|
State | Changes Requested |
Headers | show |
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(); > } >
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.
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
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 --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(); }
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