Hi Heinrich, On Sun, 25 Oct 2020 at 00:04, Heinrich Schuchardt <xypron.g...@gmx.de> wrote: > > Up to now the sandbox would shutdown upon a cold reset request. Instead it > should be reset. > > In our coding we use static variables. The only safe way to return to an > initial state is to relaunch the U-Boot binary.
This is unfortunate, but I suspect you may be right. Have you looked at it? > > The reset implementation uses a longjmp() to return to the main() function > and then relaunches U-Boot using execv(). > > Signed-off-by: Heinrich Schuchardt <xypron.g...@gmx.de> > --- > arch/sandbox/cpu/os.c | 14 ++++++++++++++ > arch/sandbox/cpu/start.c | 22 ++++++++++++++++++++++ > arch/sandbox/cpu/state.c | 1 + > arch/sandbox/include/asm/u-boot-sandbox.h | 3 +++ > drivers/sysreset/sysreset_sandbox.c | 3 +++ > include/os.h | 5 +++++ > 6 files changed, 48 insertions(+) > > diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c > index c461fb0db0..ed044e87fb 100644 > --- a/arch/sandbox/cpu/os.c > +++ b/arch/sandbox/cpu/os.c > @@ -817,3 +817,17 @@ void *os_find_text_base(void) > > return base; > } > + > +void os_relaunch(int argc, char *argv[]) > +{ > + char **args; > + > + args = calloc(argc + 1, sizeof(char *)); > + if (!args) > + goto out; > + memcpy(args, argv, sizeof(char *) * argc); > + args[argc] = NULL; > + execv(args[0], args); > +out: > + os_exit(1); > +} > diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c > index c6a2bbe468..ee1d4b9581 100644 > --- a/arch/sandbox/cpu/start.c > +++ b/arch/sandbox/cpu/start.c > @@ -5,6 +5,7 @@ > > #include <common.h> > #include <command.h> > +#include <dm/root.h> Put before linux/ below > #include <errno.h> > #include <init.h> > #include <os.h> > @@ -14,11 +15,15 @@ > #include <asm/io.h> > #include <asm/malloc.h> > #include <asm/sections.h> > +#include <asm/setjmp.h> > #include <asm/state.h> > #include <linux/ctype.h> > > DECLARE_GLOBAL_DATA_PTR; > > +/* longjmp buffer for reset */ > +static struct jmp_buf_data reset_jmp; > + > /* Compare two options so that they can be sorted into alphabetical order */ > static int h_compare_opt(const void *p1, const void *p2) > { > @@ -394,12 +399,29 @@ void state_show(struct sandbox_state *state) > printf("\n"); > } > > +void sandbox_reset(void) > +{ > + /* Do this here while it still has an effect */ > + os_fd_restore(); > + if (state_uninit()) > + os_exit(2); > + > + if (dm_uninit()) > + os_exit(2); > + > + /* This is considered normal termination for now */ > + longjmp(&reset_jmp, 1); > +} > + > int main(int argc, char *argv[]) > { > struct sandbox_state *state; > gd_t data; > int ret; > > + if (setjmp(&reset_jmp)) > + os_relaunch(argc, argv); > + > memset(&data, '\0', sizeof(data)); > gd = &data; > gd->arch.text_base = os_find_text_base(); > diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c > index 34b6fff7e7..59f37fab0b 100644 > --- a/arch/sandbox/cpu/state.c > +++ b/arch/sandbox/cpu/state.c > @@ -358,6 +358,7 @@ void state_reset_for_test(struct sandbox_state *state) > /* No reset yet, so mark it as such. Always allow power reset */ > state->last_sysreset = SYSRESET_COUNT; > state->sysreset_allowed[SYSRESET_POWER_OFF] = true; > + state->sysreset_allowed[SYSRESET_COLD] = true; > state->allow_memio = false; > > memset(&state->wdt, '\0', sizeof(state->wdt)); > diff --git a/arch/sandbox/include/asm/u-boot-sandbox.h > b/arch/sandbox/include/asm/u-boot-sandbox.h > index 798d003077..b1bdcbcde5 100644 > --- a/arch/sandbox/include/asm/u-boot-sandbox.h > +++ b/arch/sandbox/include/asm/u-boot-sandbox.h > @@ -84,6 +84,9 @@ void sandbox_set_enable_pci_map(int enable); > */ > int sandbox_read_fdt_from_file(void); > > +/* Reset sandbox */ I think this needs a better comment, explaining how it resets. > +void sandbox_reset(void); > + > /* Exit sandbox (quit U-Boot) */ > void sandbox_exit(void); > > diff --git a/drivers/sysreset/sysreset_sandbox.c > b/drivers/sysreset/sysreset_sandbox.c > index 69c22a7000..c92132798c 100644 > --- a/drivers/sysreset/sysreset_sandbox.c > +++ b/drivers/sysreset/sysreset_sandbox.c > @@ -56,6 +56,9 @@ static int sandbox_sysreset_request(struct udevice *dev, > enum sysreset_t type) > switch (type) { > case SYSRESET_COLD: > state->last_sysreset = type; > + if (!state->sysreset_allowed[type]) > + return -EACCES; > + sandbox_reset(); > break; > case SYSRESET_POWER_OFF: > state->last_sysreset = type; > diff --git a/include/os.h b/include/os.h > index 1874ae674f..187dbf06f2 100644 > --- a/include/os.h > +++ b/include/os.h > @@ -355,4 +355,9 @@ int os_read_file(const char *name, void **bufp, int > *sizep); > */ > void *os_find_text_base(void); > > +/** > + * os_relaunch() - restart the sandbox again I think a bit more detail would help > + */ > +void os_relaunch(int argc, char *argv[]); > + > #endif > -- > 2.28.0 > Regards, Simon