aboutsummaryrefslogtreecommitdiff
path: root/arch/sandbox/cpu
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2020-12-14 18:57:57 -0500
committerTom Rini <trini@konsulko.com>2020-12-14 18:57:57 -0500
commit8351a29d2df18c92d8e365cfa848218c3859f3d2 (patch)
tree5d29001be9accfb8029df9d9ed78fba196ee07b9 /arch/sandbox/cpu
parentddaa94978583d07ec515e7226e397221d8cc44c8 (diff)
parentb7bbd553de0d9752f919dfc616f560f6f2504c14 (diff)
Merge tag 'dm-pull-14dec20' of git://git.denx.de/u-boot-dm into next
Driver model tidy-up for livetree Driver model big rename for consistency Python 3 clean-ups for patman Update sandbox serial driver to use membuff
Diffstat (limited to 'arch/sandbox/cpu')
-rw-r--r--arch/sandbox/cpu/os.c40
-rw-r--r--arch/sandbox/cpu/start.c4
2 files changed, 44 insertions, 0 deletions
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 0d8efd83f6..b56fa04a34 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)
{
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index a03e5aa0b3..f6c98545e0 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -451,6 +451,10 @@ int main(int argc, char *argv[])
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