summaryrefslogtreecommitdiff
path: root/arch/sandbox/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sandbox/cpu')
-rw-r--r--arch/sandbox/cpu/Makefile2
-rw-r--r--arch/sandbox/cpu/cache.c23
-rw-r--r--arch/sandbox/cpu/os.c45
-rw-r--r--arch/sandbox/cpu/start.c21
-rw-r--r--arch/sandbox/cpu/state.c4
5 files changed, 90 insertions, 5 deletions
diff --git a/arch/sandbox/cpu/Makefile b/arch/sandbox/cpu/Makefile
index bac96447d5..de7fe7f391 100644
--- a/arch/sandbox/cpu/Makefile
+++ b/arch/sandbox/cpu/Makefile
@@ -5,7 +5,7 @@
# (C) Copyright 2000-2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-obj-y := cpu.o state.o
+obj-y := cache.o cpu.o state.o
extra-y := start.o os.o
extra-$(CONFIG_SANDBOX_SDL) += sdl.o
obj-$(CONFIG_SPL_BUILD) += spl.o
diff --git a/arch/sandbox/cpu/cache.c b/arch/sandbox/cpu/cache.c
new file mode 100644
index 0000000000..46c62c0b44
--- /dev/null
+++ b/arch/sandbox/cpu/cache.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <asm/state.h>
+
+void flush_cache(unsigned long addr, unsigned long size)
+{
+ /* Clang uses (char *) parameters, GCC (void *) */
+ __builtin___clear_cache((void *)addr, (void *)(addr + size));
+}
+
+void invalidate_icache_all(void)
+{
+ struct sandbox_state *state = state_get_current();
+
+ /* Clang uses (char *) parameters, GCC (void *) */
+ __builtin___clear_cache((void *)state->ram_buf,
+ (void *)(state->ram_buf + state->ram_size));
+}
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 0d8efd83f6..80996a91ce 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -3,6 +3,8 @@
* Copyright (c) 2011 The Chromium OS Authors.
*/
+#define _GNU_SOURCE
+
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
@@ -15,11 +17,13 @@
#include <string.h>
#include <termios.h>
#include <time.h>
+#include <ucontext.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
+#include <linux/compiler_attributes.h>
#include <linux/types.h>
#include <asm/getopt.h>
@@ -191,6 +195,42 @@ static void os_sigint_handler(int sig)
raise(SIGINT);
}
+static void os_signal_handler(int sig, siginfo_t *info, void *con)
+{
+ ucontext_t __maybe_unused *context = con;
+ unsigned long pc;
+
+#if defined(__x86_64__)
+ pc = context->uc_mcontext.gregs[REG_RIP];
+#elif defined(__aarch64__)
+ pc = context->uc_mcontext.pc;
+#elif defined(__riscv)
+ pc = context->uc_mcontext.__gregs[REG_PC];
+#else
+ const char msg[] =
+ "\nUnsupported architecture, cannot read program counter\n";
+
+ os_write(1, msg, sizeof(msg));
+ pc = 0;
+#endif
+
+ os_signal_action(sig, pc);
+}
+
+int os_setup_signal_handlers(void)
+{
+ struct sigaction act;
+
+ act.sa_sigaction = os_signal_handler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_SIGINFO | SA_NODEFER;
+ if (sigaction(SIGILL, &act, NULL) ||
+ sigaction(SIGBUS, &act, NULL) ||
+ sigaction(SIGSEGV, &act, NULL))
+ return -1;
+ return 0;
+}
+
/* Put tty into raw mode so <tab> and <ctrl+c> work */
void os_tty_raw(int fd, bool allow_sigs)
{
@@ -750,6 +790,11 @@ int os_find_u_boot(char *fname, int maxlen)
int os_spl_to_uboot(const char *fname)
{
+ struct sandbox_state *state = state_get_current();
+
+ printf("%s\n", __func__);
+ /* U-Boot will delete ram buffer after read: "--rm_memory"*/
+ state->ram_buf_rm = true;
return os_jump_to_file(fname);
}
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index a03e5aa0b3..8322ed7a1f 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <command.h>
#include <dm/root.h>
+#include <efi_loader.h>
#include <errno.h>
#include <init.h>
#include <os.h>
@@ -406,6 +407,15 @@ void state_show(struct sandbox_state *state)
printf("\n");
}
+void __efi_runtime EFIAPI efi_reset_system(
+ enum efi_reset_type reset_type,
+ efi_status_t reset_status,
+ unsigned long data_size, void *reset_data)
+{
+ os_fd_restore();
+ os_relaunch(os_argv);
+}
+
void sandbox_reset(void)
{
/* Do this here while it still has an effect */
@@ -447,10 +457,21 @@ int main(int argc, char *argv[])
if (os_parse_args(state, argc, argv))
return 1;
+ /* Remove old memory file if required */
+ if (state->ram_buf_rm && state->ram_buf_fname) {
+ os_unlink(state->ram_buf_fname);
+ state->write_ram_buf = false;
+ state->ram_buf_fname = NULL;
+ }
+
ret = sandbox_read_state(state, state->state_fname);
if (ret)
goto err;
+ ret = os_setup_signal_handlers();
+ if (ret)
+ goto err;
+
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
gd->malloc_base = CONFIG_MALLOC_F_ADDR;
#endif
diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index 59f37fab0b..b2901b7a8c 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -415,10 +415,6 @@ int state_uninit(void)
}
}
- /* Remove old memory file if required */
- if (state->ram_buf_rm && state->ram_buf_fname)
- os_unlink(state->ram_buf_fname);
-
/* Delete this at the last moment so as not to upset gdb too much */
if (state->jumped_fname)
os_unlink(state->jumped_fname);