diff options
Diffstat (limited to 'arch/sandbox')
-rw-r--r-- | arch/sandbox/Kconfig | 9 | ||||
-rw-r--r-- | arch/sandbox/cpu/Makefile | 2 | ||||
-rw-r--r-- | arch/sandbox/cpu/cache.c | 23 | ||||
-rw-r--r-- | arch/sandbox/cpu/os.c | 45 | ||||
-rw-r--r-- | arch/sandbox/cpu/start.c | 21 | ||||
-rw-r--r-- | arch/sandbox/cpu/state.c | 4 | ||||
-rw-r--r-- | arch/sandbox/dts/sandbox.dts | 4 | ||||
-rw-r--r-- | arch/sandbox/dts/sandbox.dtsi | 16 | ||||
-rw-r--r-- | arch/sandbox/dts/test.dts | 25 | ||||
-rw-r--r-- | arch/sandbox/include/asm/i2c.h | 14 | ||||
-rw-r--r-- | arch/sandbox/include/asm/serial.h | 30 | ||||
-rw-r--r-- | arch/sandbox/include/asm/spi.h | 10 | ||||
-rw-r--r-- | arch/sandbox/include/asm/test.h | 16 | ||||
-rw-r--r-- | arch/sandbox/lib/interrupts.c | 35 |
14 files changed, 224 insertions, 30 deletions
diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig index 65f988e736..f83282d9d5 100644 --- a/arch/sandbox/Kconfig +++ b/arch/sandbox/Kconfig @@ -51,6 +51,15 @@ config HOST_64BIT endchoice +config SANDBOX_CRASH_RESET + bool "Reset on crash" + help + If an illegal instruction or an illegal memory access occurs, the + sandbox by default writes a crash dump and exits. If you set this + flag, the sandbox is reset instead. This may be useful when running + test suites like the UEFI self certification test which continue + with the next test after a crash. + config SANDBOX_BITS_PER_LONG int default 32 if HOST_32BIT 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); diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts index 8b50a40289..a8938a3acc 100644 --- a/arch/sandbox/dts/sandbox.dts +++ b/arch/sandbox/dts/sandbox.dts @@ -41,7 +41,7 @@ cros_ec: cros-ec { reg = <0 0>; - u-boot,dm-pre-reloc; + u-boot,dm-pre-proper; compatible = "google,cros-ec-sandbox"; }; @@ -83,7 +83,7 @@ }; spi: spi@0 { - u-boot,dm-pre-reloc; + u-boot,dm-pre-proper; #address-cells = <1>; #size-cells = <0>; reg = <0 0>; diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi index 81cdc55b0d..d842f02176 100644 --- a/arch/sandbox/dts/sandbox.dtsi +++ b/arch/sandbox/dts/sandbox.dtsi @@ -56,7 +56,7 @@ }; gpio_a: gpios@0 { - u-boot,dm-pre-reloc; + u-boot,dm-pre-proper; gpio-controller; compatible = "sandbox,gpio"; #gpio-cells = <1>; @@ -65,7 +65,7 @@ }; gpio_b: gpios@1 { - u-boot,dm-pre-reloc; + u-boot,dm-pre-proper; gpio-controller; compatible = "sandbox,gpio"; #gpio-cells = <2>; @@ -120,7 +120,7 @@ }; lcd { - u-boot,dm-pre-reloc; + u-boot,dm-pre-proper; compatible = "sandbox,lcd-sdl"; xres = <1366>; yres = <768>; @@ -209,7 +209,7 @@ spi@0 { firmware_storage_spi: flash@0 { - u-boot,dm-pre-reloc; + u-boot,dm-pre-proper; reg = <0>; compatible = "spansion,m25p16", "jedec,spi-nor"; spi-max-frequency = <40000000>; @@ -248,11 +248,6 @@ stringarray = "one"; }; - spl-test4 { - u-boot,dm-pre-reloc; - compatible = "sandbox,spl-test.2"; - }; - spl-test5 { u-boot,dm-tpl; compatible = "sandbox,spl-test"; @@ -283,7 +278,6 @@ }; tpm { - u-boot,dm-pre-reloc; compatible = "google,sandbox-tpm"; }; @@ -420,6 +414,6 @@ }; keyboard-controller { - u-boot,dm-pre-reloc; + u-boot,dm-pre-proper; }; }; diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index f3b766271d..c9b9b7b75e 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -33,10 +33,11 @@ testfdt6 = "/e-test"; testbus3 = "/some-bus"; testfdt0 = "/some-bus/c-test@0"; - testfdt1 = "/some-bus/c-test@1"; + testfdt12 = "/some-bus/c-test@1"; testfdt3 = "/b-test"; testfdt5 = "/some-bus/c-test@5"; testfdt8 = "/a-test"; + testfdtm1 = &testfdtm1; fdt-dummy0 = "/translation-test@8000/dev@0,0"; fdt-dummy1 = "/translation-test@8000/dev@1,100"; fdt-dummy2 = "/translation-test@8000/dev@2,200"; @@ -864,13 +865,21 @@ #size-cells = <0>; reg = <0 1>; compatible = "sandbox,spi"; - cs-gpios = <0>, <&gpio_a 0>; + cs-gpios = <0>, <0>, <&gpio_a 0>; spi.bin@0 { reg = <0>; compatible = "spansion,m25p16", "jedec,spi-nor"; spi-max-frequency = <40000000>; sandbox,filename = "spi.bin"; }; + spi.bin@1 { + reg = <1>; + compatible = "spansion,m25p16", "jedec,spi-nor"; + spi-max-frequency = <50000000>; + sandbox,filename = "spi.bin"; + spi-cpol; + spi-cpha; + }; }; syscon0: syscon@0 { @@ -917,6 +926,18 @@ idle-state = <0xabcd>; }; + testfdtm0 { + compatible = "denx,u-boot-fdtm-test"; + }; + + testfdtm1: testfdtm1 { + compatible = "denx,u-boot-fdtm-test"; + }; + + testfdtm2 { + compatible = "denx,u-boot-fdtm-test"; + }; + timer@0 { compatible = "sandbox,timer"; clock-frequency = <1000000>; diff --git a/arch/sandbox/include/asm/i2c.h b/arch/sandbox/include/asm/i2c.h new file mode 100644 index 0000000000..b482be485c --- /dev/null +++ b/arch/sandbox/include/asm/i2c.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2020 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#ifndef __asn_i2c_h +#define __asn_i2c_h + +struct sandbox_i2c_priv { + bool test_mode; +}; + +#endif /* __asn_i2c_h */ diff --git a/arch/sandbox/include/asm/serial.h b/arch/sandbox/include/asm/serial.h new file mode 100644 index 0000000000..bc82aebd0e --- /dev/null +++ b/arch/sandbox/include/asm/serial.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2020 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#ifndef __asm_serial_h +#define __asm_serial_h + +#include <dt-structs.h> + +struct sandbox_serial_plat { +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct dtd_sandbox_serial dtplat; +#endif + int colour; /* Text colour to use for output, -1 for none */ +}; + +/** + * struct sandbox_serial_priv - Private data for this driver + * + * @buf: holds input characters available to be read by this driver + */ +struct sandbox_serial_priv { + struct membuff buf; + char serial_buf[16]; + bool start_of_line; +}; + +#endif /* __asm_serial_h */ diff --git a/arch/sandbox/include/asm/spi.h b/arch/sandbox/include/asm/spi.h index 98e1826e2c..e8268bbe07 100644 --- a/arch/sandbox/include/asm/spi.h +++ b/arch/sandbox/include/asm/spi.h @@ -32,14 +32,4 @@ struct sandbox_spi_emu_ops { int (*xfer)(void *priv, const u8 *rx, u8 *tx, uint bytes); }; -/* - * Extract the bus/cs from the spi spec and return the start of the spi - * client spec. If the bus/cs are invalid for the current config, then - * it returns NULL. - * - * Example: arg="0:1:foo" will set bus to 0, cs to 1, and return "foo" - */ -const char *sandbox_spi_parse_spec(const char *arg, unsigned long *bus, - unsigned long *cs); - #endif diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 7f99d07c47..05f66f700c 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -203,6 +203,22 @@ void sandbox_set_allow_beep(struct udevice *dev, bool allow); int sandbox_get_beep_frequency(struct udevice *dev); /** + * sandbox_spi_get_speed() - Get current speed setting of a sandbox spi bus + * + * @dev: Device to check + * @return current bus speed + */ +uint sandbox_spi_get_speed(struct udevice *dev); + +/** + * sandbox_spi_get_mode() - Get current mode setting of a sandbox spi bus + * + * @dev: Device to check + * @return current mode + */ +uint sandbox_spi_get_mode(struct udevice *dev); + +/** * sandbox_get_pch_spi_protect() - Get the PCI SPI protection status * * @dev: Device to check diff --git a/arch/sandbox/lib/interrupts.c b/arch/sandbox/lib/interrupts.c index 21f761ac3b..9c2c60b8c6 100644 --- a/arch/sandbox/lib/interrupts.c +++ b/arch/sandbox/lib/interrupts.c @@ -6,7 +6,13 @@ */ #include <common.h> +#include <efi_loader.h> #include <irq_func.h> +#include <os.h> +#include <asm-generic/signal.h> +#include <asm/u-boot-sandbox.h> + +DECLARE_GLOBAL_DATA_PTR; int interrupt_init(void) { @@ -21,3 +27,32 @@ int disable_interrupts(void) { return 0; } + +void os_signal_action(int sig, unsigned long pc) +{ + efi_restore_gd(); + + switch (sig) { + case SIGILL: + printf("\nIllegal instruction\n"); + break; + case SIGBUS: + printf("\nBus error\n"); + break; + case SIGSEGV: + printf("\nSegmentation violation\n"); + break; + default: + break; + } + printf("pc = 0x%lx, ", pc); + printf("pc_reloc = 0x%lx\n\n", pc - gd->reloc_off); + efi_print_image_infos((void *)pc); + + if (IS_ENABLED(CONFIG_SANDBOX_CRASH_RESET)) { + printf("resetting ...\n\n"); + sandbox_reset(); + } else { + sandbox_exit(); + } +} |