diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2020-10-14 12:46:52 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2020-10-14 12:46:52 +0200 |
commit | bee1da7fcc005edab18fde60fd2ce956d12c5e18 (patch) | |
tree | 77d02747d657192acb10500f979b83e20d0447a3 /arch | |
parent | c29ce8d93f9403c3ce6ccc5e82fb7a7be41d6659 (diff) | |
parent | 765ecaf52b834278a2449fcb097754a3aae9aa96 (diff) | |
download | barebox-bee1da7fcc005edab18fde60fd2ce956d12c5e18.tar.gz barebox-bee1da7fcc005edab18fde60fd2ce956d12c5e18.tar.xz |
Merge branch 'for-next/sandbox' into master
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/cpu/dtb.c | 8 | ||||
-rw-r--r-- | arch/kvx/lib/dtb.c | 12 | ||||
-rw-r--r-- | arch/mips/boot/dtb.c | 8 | ||||
-rw-r--r-- | arch/openrisc/lib/dtb.c | 8 | ||||
-rw-r--r-- | arch/riscv/boot/dtb.c | 14 | ||||
-rw-r--r-- | arch/sandbox/Makefile | 1 | ||||
-rw-r--r-- | arch/sandbox/board/Makefile | 3 | ||||
-rw-r--r-- | arch/sandbox/board/devices.c | 3 | ||||
-rw-r--r-- | arch/sandbox/board/dtb.c | 28 | ||||
-rw-r--r-- | arch/sandbox/board/env/init/state | 12 | ||||
-rw-r--r-- | arch/sandbox/board/hostfile.c | 94 | ||||
-rw-r--r-- | arch/sandbox/board/power.c | 82 | ||||
-rw-r--r-- | arch/sandbox/board/poweroff.c | 42 | ||||
-rw-r--r-- | arch/sandbox/board/watchdog.c | 84 | ||||
-rw-r--r-- | arch/sandbox/configs/sandbox_defconfig | 45 | ||||
-rw-r--r-- | arch/sandbox/dts/Makefile | 4 | ||||
-rw-r--r-- | arch/sandbox/dts/sandbox-state-example.dtsi | 50 | ||||
-rw-r--r-- | arch/sandbox/dts/sandbox.dts | 94 | ||||
-rw-r--r-- | arch/sandbox/dts/skeleton.dtsi | 13 | ||||
-rw-r--r-- | arch/sandbox/mach-sandbox/include/mach/hostfile.h | 2 | ||||
-rw-r--r-- | arch/sandbox/mach-sandbox/include/mach/linux.h | 5 | ||||
-rw-r--r-- | arch/sandbox/os/common.c | 135 |
22 files changed, 518 insertions, 229 deletions
diff --git a/arch/arm/cpu/dtb.c b/arch/arm/cpu/dtb.c index 8094eebf07..35f251d99a 100644 --- a/arch/arm/cpu/dtb.c +++ b/arch/arm/cpu/dtb.c @@ -26,13 +26,7 @@ static int of_arm_init(void) return 0; } - root = of_unflatten_dtb(fdt); - if (!IS_ERR(root)) { - of_set_root_node(root); - of_fix_tree(root); - if (IS_ENABLED(CONFIG_OFDEVICE)) - of_probe(); - } + barebox_register_fdt(fdt); return 0; } diff --git a/arch/kvx/lib/dtb.c b/arch/kvx/lib/dtb.c index 17dcab197f..54ffddaf0a 100644 --- a/arch/kvx/lib/dtb.c +++ b/arch/kvx/lib/dtb.c @@ -12,17 +12,7 @@ static int of_kvx_init(void) int ret; struct device_node *root; - root = of_unflatten_dtb(boot_dtb); - if (IS_ERR(root)) { - ret = PTR_ERR(root); - panic("Failed to parse DTB: %d\n", ret); - } - - ret = of_set_root_node(root); - if (ret) - panic("Failed to set of root node\n"); - - of_probe(); + barebox_register_fdt(boot_dtb); return 0; } diff --git a/arch/mips/boot/dtb.c b/arch/mips/boot/dtb.c index 5e316270f6..2aff4adbe7 100644 --- a/arch/mips/boot/dtb.c +++ b/arch/mips/boot/dtb.c @@ -42,13 +42,7 @@ static int of_mips_init(void) if (!fdt) fdt = __dtb_start; - root = of_unflatten_dtb(fdt); - if (!IS_ERR(root)) { - pr_debug("using internal DTB\n"); - of_set_root_node(root); - if (IS_ENABLED(CONFIG_OFDEVICE)) - of_probe(); - } + barebox_register_fdt(fdt); return 0; } diff --git a/arch/openrisc/lib/dtb.c b/arch/openrisc/lib/dtb.c index 2dd8e4e014..61cf35ddf3 100644 --- a/arch/openrisc/lib/dtb.c +++ b/arch/openrisc/lib/dtb.c @@ -28,13 +28,7 @@ static int of_openrisc_init(void) if (root) return 0; - root = of_unflatten_dtb(__dtb_start); - if (!IS_ERR(root)) { - pr_debug("using internal DTB\n"); - of_set_root_node(root); - if (IS_ENABLED(CONFIG_OFDEVICE)) - of_probe(); - } + barebox_register_fdt(__dtb_start); return 0; } diff --git a/arch/riscv/boot/dtb.c b/arch/riscv/boot/dtb.c index 5d73413a43..b9b68fc7f2 100644 --- a/arch/riscv/boot/dtb.c +++ b/arch/riscv/boot/dtb.c @@ -18,19 +18,7 @@ extern char __dtb_start[]; static int of_riscv_init(void) { - struct device_node *root; - - root = of_get_root_node(); - if (root) - return 0; - - root = of_unflatten_dtb(__dtb_start); - if (!IS_ERR(root)) { - pr_debug("using internal DTB\n"); - of_set_root_node(root); - if (IS_ENABLED(CONFIG_OFDEVICE)) - of_probe(); - } + barebox_register_fdt(__dtb_start); return 0; } diff --git a/arch/sandbox/Makefile b/arch/sandbox/Makefile index 09112c3ba8..17f9a298d7 100644 --- a/arch/sandbox/Makefile +++ b/arch/sandbox/Makefile @@ -24,6 +24,7 @@ KBUILD_CFLAGS += -Dmalloc=barebox_malloc -Dcalloc=barebox_calloc \ -Dgetenv=barebox_getenv -Dprintf=barebox_printf \ -Dglob=barebox_glob -Dglobfree=barebox_globfree \ -Dioctl=barebox_ioctl -Dfstat=barebox_fstat \ + -Dftruncate=barebox_ftruncate -Dasprintf=barebox_asprintf \ -Dopendir=barebox_opendir -Dreaddir=barebox_readdir \ -Dclosedir=barebox_closedir -Dreadlink=barebox_readlink \ -Doptarg=barebox_optarg -Doptind=barebox_optind diff --git a/arch/sandbox/board/Makefile b/arch/sandbox/board/Makefile index 26f6cb1922..c504c967de 100644 --- a/arch/sandbox/board/Makefile +++ b/arch/sandbox/board/Makefile @@ -4,7 +4,8 @@ obj-y += hostfile.o obj-y += console.o obj-y += devices.o obj-y += dtb.o -obj-y += poweroff.o +obj-y += power.o obj-y += dev-random.o +obj-y += watchdog.o extra-y += barebox.lds diff --git a/arch/sandbox/board/devices.c b/arch/sandbox/board/devices.c index 1fd1913ae6..26152a8b90 100644 --- a/arch/sandbox/board/devices.c +++ b/arch/sandbox/board/devices.c @@ -26,9 +26,6 @@ static int sandbox_device_init(void) { struct device_d *dev, *tmp; - barebox_set_model("barebox sandbox"); - barebox_set_hostname("barebox"); - list_for_each_entry_safe(dev, tmp, &sandbox_device_list, list) { /* reset the list_head before registering for real */ dev->list.prev = NULL; diff --git a/arch/sandbox/board/dtb.c b/arch/sandbox/board/dtb.c index d11bde0249..4a8cbfb26f 100644 --- a/arch/sandbox/board/dtb.c +++ b/arch/sandbox/board/dtb.c @@ -32,32 +32,14 @@ int barebox_register_dtb(const void *new_dtb) return 0; } +extern char __dtb_sandbox_start[]; + static int of_sandbox_init(void) { - struct device_node *root; - int ret; - - if (dtb) { - root = of_unflatten_dtb(dtb); - } else { - root = of_new_node(NULL, NULL); - - ret = of_property_write_u32(root, "#address-cells", 2); - if (ret) - return ret; - - ret = of_property_write_u32(root, "#size-cells", 2); - if (ret) - return ret; - } - - if (IS_ERR(root)) - return PTR_ERR(root); + if (!dtb) + dtb = __dtb_sandbox_start; - of_set_root_node(root); - of_fix_tree(root); - if (IS_ENABLED(CONFIG_OFDEVICE)) - of_probe(); + barebox_register_fdt(dtb); return 0; } diff --git a/arch/sandbox/board/env/init/state b/arch/sandbox/board/env/init/state new file mode 100644 index 0000000000..0b8e40409f --- /dev/null +++ b/arch/sandbox/board/env/init/state @@ -0,0 +1,12 @@ +if [ "x$state.dirty" != "x1" -o $global.system.reset != "POR" ]; then + exit +fi + +source /env/data/ansi-colors + +echo -e $CYAN +echo "******************************************************************" +echo "*** Inconsistent barebox state buckets detected on first boot ***" +echo "*** barebox will repair them on next shutdown ***" +echo "*****************************************************************" +echo -e -n $NC diff --git a/arch/sandbox/board/hostfile.c b/arch/sandbox/board/hostfile.c index 63530bd25e..e3e38b7119 100644 --- a/arch/sandbox/board/hostfile.c +++ b/arch/sandbox/board/hostfile.c @@ -124,9 +124,6 @@ static int hf_probe(struct device_d *dev) if (err) return err; - if (!priv->fd) - priv->fd = linux_open(priv->filename, true); - if (priv->fd < 0) return priv->fd; @@ -194,37 +191,98 @@ static int of_hostfile_fixup(struct device_node *root, void *ctx) { struct hf_info *hf = ctx; struct device_node *node; - uint32_t reg[] = { - hf->base >> 32, - hf->base, - hf->size >> 32, - hf->size - }; + bool name_only = false; int ret; - node = of_new_node(root, hf->devname); + node = of_get_child_by_name(root, hf->devname); + if (node) + name_only = true; + else + node = of_new_node(root, hf->devname); - ret = of_property_write_string(node, "compatible", hostfile_dt_ids->compatible); + ret = of_property_write_string(node, "barebox,filename", hf->filename); if (ret) return ret; - ret = of_property_write_u32_array(node, "reg", reg, ARRAY_SIZE(reg)); + if (name_only) + return 0; + + ret = of_property_write_string(node, "compatible", hostfile_dt_ids->compatible); if (ret) return ret; - ret = of_property_write_u32(node, "barebox,fd", hf->fd); + ret = of_property_write_bool(node, "barebox,blockdev", hf->is_blockdev); if (ret) return ret; - ret = of_property_write_string(node, "barebox,filename", hf->filename); - - if (hf->is_blockdev) - ret = of_property_write_bool(node, "barebox,blockdev", true); + ret = of_property_write_bool(node, "barebox,cdev", hf->is_cdev); + if (ret) + return ret; - return ret; + return of_property_write_bool(node, "barebox,read-only", hf->is_readonly); } int barebox_register_filedev(struct hf_info *hf) { return of_register_fixup(of_hostfile_fixup, hf); } + +static int of_hostfile_map_fixup(struct device_node *root, void *ctx) +{ + struct device_node *node; + int ret; + + for_each_compatible_node_from(node, root, NULL, hostfile_dt_ids->compatible) { + struct hf_info hf = {}; + uint64_t reg[2] = {}; + bool no_filename; + + hf.devname = node->name; + + ret = of_property_read_string(node, "barebox,filename", &hf.filename); + no_filename = ret; + + hf.is_blockdev = of_property_read_bool(node, "barebox,blockdev"); + hf.is_cdev = of_property_read_bool(node, "barebox,cdev"); + hf.is_readonly = of_property_read_bool(node, "barebox,read-only"); + + of_property_read_u64_array(node, "reg", reg, ARRAY_SIZE(reg)); + + hf.base = reg[0]; + hf.size = reg[1]; + + ret = linux_open_hostfile(&hf); + if (ret) + goto out; + + reg[0] = hf.base; + reg[1] = hf.size; + + ret = of_property_write_u64_array(node, "reg", reg, ARRAY_SIZE(reg)); + if (ret) + goto out; + + ret = of_property_write_bool(node, "barebox,blockdev", hf.is_blockdev); + if (ret) + goto out; + + if (no_filename) { + ret = of_property_write_string(node, "barebox,filename", hf.filename); + if (ret) + goto out; + } + + ret = of_property_write_u32(node, "barebox,fd", hf.fd); +out: + if (ret) + pr_err("error fixing up %s: %pe\n", hf.devname, ERR_PTR(ret)); + } + + return 0; +} + +static int barebox_fixup_filedevs(void) +{ + return of_register_fixup(of_hostfile_map_fixup, NULL); +} +pure_initcall(barebox_fixup_filedevs); diff --git a/arch/sandbox/board/power.c b/arch/sandbox/board/power.c new file mode 100644 index 0000000000..3cc9447958 --- /dev/null +++ b/arch/sandbox/board/power.c @@ -0,0 +1,82 @@ +#include <common.h> +#include <driver.h> +#include <poweroff.h> +#include <restart.h> +#include <mach/linux.h> +#include <reset_source.h> +#include <mfd/syscon.h> + +struct sandbox_power { + struct restart_handler rst_hang, rst_reexec; + struct regmap *src; + u32 src_offset; +}; + +static void sandbox_poweroff(struct poweroff_handler *poweroff) +{ + linux_exit(); +} + +static void sandbox_rst_hang(struct restart_handler *rst) +{ + linux_hang(); +} + +static void sandbox_rst_reexec(struct restart_handler *rst) +{ + struct sandbox_power *power = container_of(rst, struct sandbox_power, rst_reexec); + regmap_update_bits(power->src, power->src_offset, 0xff, RESET_RST); + linux_reexec(); +} + +static int sandbox_power_probe(struct device_d *dev) +{ + struct sandbox_power *power = xzalloc(sizeof(*power)); + unsigned int rst; + int ret; + + poweroff_handler_register_fn(sandbox_poweroff); + + power->rst_hang = (struct restart_handler) { + .name = "hang", + .restart = sandbox_rst_hang + }; + + power->rst_reexec = (struct restart_handler) { + .name = "reexec", .priority = 200, + .restart = sandbox_rst_reexec, + }; + + restart_handler_register(&power->rst_hang); + + if (IS_ENABLED(CONFIG_SANDBOX_REEXEC)) + restart_handler_register(&power->rst_reexec); + + power->src = syscon_regmap_lookup_by_phandle(dev->device_node, "barebox,reset-source"); + if (IS_ERR(power->src)) + return 0; + + ret = of_property_read_u32_index(dev->device_node, "barebox,reset-source", 1, + &power->src_offset); + if (ret) + return 0; + + ret = regmap_read(power->src, power->src_offset, &rst); + if (ret == 0 && rst == 0) + rst = RESET_POR; + + reset_source_set_prinst(rst, RESET_SOURCE_DEFAULT_PRIORITY, 0); + return 0; +} + +static __maybe_unused struct of_device_id sandbox_power_dt_ids[] = { + { .compatible = "barebox,sandbox-power" }, + { /* sentinel */ } +}; + +static struct driver_d sandbox_power_drv = { + .name = "sandbox-power", + .of_compatible = sandbox_power_dt_ids, + .probe = sandbox_power_probe, +}; +coredevice_platform_driver(sandbox_power_drv); diff --git a/arch/sandbox/board/poweroff.c b/arch/sandbox/board/poweroff.c deleted file mode 100644 index 8ce739af72..0000000000 --- a/arch/sandbox/board/poweroff.c +++ /dev/null @@ -1,42 +0,0 @@ -#include <common.h> -#include <init.h> -#include <poweroff.h> -#include <restart.h> -#include <mach/linux.h> - -static void sandbox_poweroff(struct poweroff_handler *poweroff) -{ - linux_exit(); -} - -static void sandbox_rst_hang(struct restart_handler *rst) -{ - linux_hang(); -} - -static struct restart_handler rst_hang = { - .name = "hang", - .restart = sandbox_rst_hang -}; - -static void sandbox_rst_reexec(struct restart_handler *rst) -{ - linux_reexec(); -} - -static struct restart_handler rst_reexec = { - .name = "reexec", .priority = 200, - .restart = sandbox_rst_reexec, -}; - -static int poweroff_register_feature(void) -{ - poweroff_handler_register_fn(sandbox_poweroff); - restart_handler_register(&rst_hang); - - if (IS_ENABLED(CONFIG_SANDBOX_REEXEC)) - restart_handler_register(&rst_reexec); - - return 0; -} -coredevice_initcall(poweroff_register_feature); diff --git a/arch/sandbox/board/watchdog.c b/arch/sandbox/board/watchdog.c new file mode 100644 index 0000000000..336451282f --- /dev/null +++ b/arch/sandbox/board/watchdog.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include <common.h> +#include <errno.h> +#include <driver.h> +#include <mach/linux.h> +#include <of.h> +#include <watchdog.h> +#include <mfd/syscon.h> +#include <reset_source.h> + +struct sandbox_watchdog { + struct watchdog wdd; + bool cant_disable :1; +}; + +static inline struct sandbox_watchdog *to_sandbox_watchdog(struct watchdog *wdd) +{ + return container_of(wdd, struct sandbox_watchdog, wdd); +} + +static int sandbox_watchdog_set_timeout(struct watchdog *wdd, unsigned int timeout) +{ + struct sandbox_watchdog *wd = to_sandbox_watchdog(wdd); + + if (!timeout && wd->cant_disable) + return -ENOSYS; + + if (timeout > wdd->timeout_max) + return -EINVAL; + + return linux_watchdog_set_timeout(timeout); +} + +static int sandbox_watchdog_probe(struct device_d *dev) +{ + struct device_node *np = dev->device_node; + struct sandbox_watchdog *wd; + struct watchdog *wdd; + struct regmap *src; + u32 src_offset; + int ret; + + wd = xzalloc(sizeof(*wd)); + + wdd = &wd->wdd; + wdd->hwdev = dev; + wdd->set_timeout = sandbox_watchdog_set_timeout; + wdd->timeout_max = 1000; + + wd->cant_disable = of_property_read_bool(np, "barebox,cant-disable"); + + ret = watchdog_register(wdd); + if (ret) { + dev_err(dev, "Failed to register watchdog device\n"); + return ret; + } + + src = syscon_regmap_lookup_by_phandle(np, "barebox,reset-source"); + if (IS_ERR(src)) + return 0; + + ret = of_property_read_u32_index(np, "barebox,reset-source", 1, &src_offset); + if (ret) + return 0; + + regmap_update_bits(src, src_offset, 0xff, RESET_WDG); + + dev_info(dev, "probed\n"); + return 0; +} + + +static __maybe_unused struct of_device_id sandbox_watchdog_dt_ids[] = { + { .compatible = "barebox,sandbox-watchdog" }, + { /* sentinel */ } +}; + +static struct driver_d sandbox_watchdog_drv = { + .name = "sandbox-watchdog", + .of_compatible = sandbox_watchdog_dt_ids, + .probe = sandbox_watchdog_probe, +}; +device_platform_driver(sandbox_watchdog_drv); diff --git a/arch/sandbox/configs/sandbox_defconfig b/arch/sandbox/configs/sandbox_defconfig index c343f053fa..ca24d81aca 100644 --- a/arch/sandbox/configs/sandbox_defconfig +++ b/arch/sandbox/configs/sandbox_defconfig @@ -2,20 +2,34 @@ CONFIG_HUSH_FANCY_PROMPT=y CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y CONFIG_MENU=y +CONFIG_CONSOLE_ALLOW_COLOR=y CONFIG_PARTITION=y +CONFIG_PARTITION_DISK_EFI=y CONFIG_DEFAULT_COMPRESSION_GZIP=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW_REBOOT_MODE=y CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/sandbox/board/env" +CONFIG_STATE=y +CONFIG_STATE_CRYPTO=y +CONFIG_RESET_SOURCE=y CONFIG_CMD_DMESG=y CONFIG_LONGHELP=y +CONFIG_CMD_IOMEM=y CONFIG_CMD_IMD=y CONFIG_CMD_MEMINFO=y -# CONFIG_CMD_BOOTM is not set +CONFIG_CMD_POLLER=y +CONFIG_CMD_SLICE=y CONFIG_CMD_GO=y +CONFIG_CMD_LOADB=y +CONFIG_CMD_LOADS=y +CONFIG_CMD_LOADY=y +CONFIG_CMD_RESET=y +CONFIG_CMD_SAVES=y CONFIG_CMD_UIMAGE=y CONFIG_CMD_PARTITION=y CONFIG_CMD_EXPORT=y CONFIG_CMD_DEFAULTENV=y +CONFIG_CMD_LOADENV=y CONFIG_CMD_PRINTENV=y CONFIG_CMD_MAGICVAR=y CONFIG_CMD_MAGICVAR_HELP=y @@ -39,14 +53,18 @@ CONFIG_CMD_PING=y CONFIG_CMD_TFTP=y CONFIG_CMD_ECHO_E=y CONFIG_CMD_EDIT=y +CONFIG_CMD_LOGIN=y CONFIG_CMD_MENU=y CONFIG_CMD_MENU_MANAGEMENT=y CONFIG_CMD_MENUTREE=y +CONFIG_CMD_PASSWD=y CONFIG_CMD_SPLASH=y +CONFIG_CMD_FBTEST=y CONFIG_CMD_READLINE=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_CRC=y CONFIG_CMD_CRC_CMP=y +CONFIG_CMD_MEMTEST=y CONFIG_CMD_MM=y CONFIG_CMD_DETECT=y CONFIG_CMD_FLASH=y @@ -56,18 +74,31 @@ CONFIG_CMD_LED=y CONFIG_CMD_POWEROFF=y CONFIG_CMD_SPI=y CONFIG_CMD_LED_TRIGGER=y +CONFIG_CMD_WD=y CONFIG_CMD_2048=y +CONFIG_CMD_KEYSTORE=y +CONFIG_CMD_LINUX_EXEC=y +CONFIG_CMD_OF_DIFF=y CONFIG_CMD_OF_NODE=y CONFIG_CMD_OF_PROPERTY=y CONFIG_CMD_OF_DISPLAY_TIMINGS=y +CONFIG_CMD_OF_FIXUP_STATUS=y +CONFIG_CMD_OF_OVERLAY=y CONFIG_CMD_OFTREE=y CONFIG_CMD_TIME=y +CONFIG_CMD_STATE=y +CONFIG_CMD_DHRYSTONE=y CONFIG_CMD_SPD_DECODE=y +CONFIG_CMD_SEED=y CONFIG_NET=y CONFIG_NET_NFS=y CONFIG_NET_NETCONSOLE=y +CONFIG_NET_SNTP=y +CONFIG_NET_FASTBOOT=y CONFIG_OFDEVICE=y CONFIG_OF_BAREBOX_DRIVERS=y +CONFIG_OF_BAREBOX_ENV_IN_FS=y +CONFIG_OF_OVERLAY_LIVE=y CONFIG_DRIVER_NET_TAP=y CONFIG_DRIVER_SPI_GPIO=y CONFIG_I2C=y @@ -76,6 +107,9 @@ CONFIG_MTD=y CONFIG_MTD_M25P80=y CONFIG_VIDEO=y CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_MFD_SYSCON=y +CONFIG_STATE_DRV=y +CONFIG_UBOOTVAR=y CONFIG_LED=y CONFIG_LED_GPIO=y CONFIG_LED_GPIO_OF=y @@ -84,9 +118,12 @@ CONFIG_LED_GPIO_BICOLOR=y CONFIG_LED_TRIGGERS=y CONFIG_EEPROM_AT25=y CONFIG_EEPROM_AT24=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_POLLER=y # CONFIG_PINCTRL is not set CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y +CONFIG_SYSCON_REBOOT_MODE=y CONFIG_FS_CRAMFS=y CONFIG_FS_EXT4=y CONFIG_FS_TFTP=y @@ -94,12 +131,17 @@ CONFIG_FS_NFS=y CONFIG_FS_FAT=y CONFIG_FS_FAT_WRITE=y CONFIG_FS_FAT_LFN=y +CONFIG_FS_JFFS2=y CONFIG_FS_BPKFS=y CONFIG_FS_UIMAGEFS=y +CONFIG_FS_PSTORE=y +CONFIG_FS_PSTORE_CONSOLE=y CONFIG_FS_SQUASHFS=y +CONFIG_FS_UBOOTVARFS=y CONFIG_BZLIB=y CONFIG_LZ4_DECOMPRESS=y CONFIG_XZ_DECOMPRESS=y +CONFIG_BASE64=y CONFIG_LZO_DECOMPRESS=y CONFIG_BMP=y CONFIG_PNG=y @@ -112,4 +154,3 @@ CONFIG_BAREBOX_LOGO_240=y CONFIG_BAREBOX_LOGO_320=y CONFIG_BAREBOX_LOGO_400=y CONFIG_BAREBOX_LOGO_640=y -CONFIG_DIGEST_HMAC_GENERIC=y diff --git a/arch/sandbox/dts/Makefile b/arch/sandbox/dts/Makefile index 6f4344da68..c8d83141ce 100644 --- a/arch/sandbox/dts/Makefile +++ b/arch/sandbox/dts/Makefile @@ -1,5 +1,5 @@ -always-$(CONFIG_OFTREE) += \ - sandbox.dtb +obj-$(CONFIG_OFTREE) += \ + sandbox.dtb.o # just to build a built-in.o. Otherwise compilation fails when no devicetree is # created. diff --git a/arch/sandbox/dts/sandbox-state-example.dtsi b/arch/sandbox/dts/sandbox-state-example.dtsi deleted file mode 100644 index 98640f6677..0000000000 --- a/arch/sandbox/dts/sandbox-state-example.dtsi +++ /dev/null @@ -1,50 +0,0 @@ -/ { - aliases { - state = &state; - }; - - disk { - compatible = "barebox,hostfile"; - barebox,filename = "disk"; - reg = <0x0 0x0 0x0 0x100000>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - hostfile_state: state@0 { - reg = <0x0 0x1000>; - label = "state"; - }; - }; - }; - - state: state { - magic = <0xaa3b86a6>; - compatible = "barebox,state"; - backend-type = "raw"; - backend = <&hostfile_state>; - backend-storage-type = "direct"; - backend-stridesize = <64>; - - #address-cells = <1>; - #size-cells = <1>; - vars { - #address-cells = <1>; - #size-cells = <1>; - - x { - reg = <0x0 0x4>; - type = "uint32"; - default = <1>; - }; - - y { - reg = <0x4 0x4>; - type = "uint32"; - default = <3>; - }; - }; - }; -}; diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts index 2595aa13fa..afe48154c4 100644 --- a/arch/sandbox/dts/sandbox.dts +++ b/arch/sandbox/dts/sandbox.dts @@ -1,7 +1,97 @@ /dts-v1/; -#include "skeleton.dtsi" - / { + model = "Sandbox"; + compatible = "barebox,sandbox"; + + #address-cells = <2>; + #size-cells = <2>; + + aliases { + bmode = &bmode; + state = &state; + }; + + chosen { + environment { + compatible = "barebox,environment"; + device-path = &part_env; + }; + }; + + memory { + device_type = "memory"; + reg = <0 0 0 0>; + }; + + state: state { + magic = <0xaa3b86a6>; + compatible = "barebox,state"; + backend-type = "raw"; + backend = <&part_state>; + backend-storage-type = "direct"; + backend-stridesize = <64>; + + #address-cells = <1>; + #size-cells = <1>; + + vars { + #address-cells = <1>; + #size-cells = <1>; + + x { + reg = <0x0 0x4>; + type = "uint32"; + default = <1>; + }; + + y { + reg = <0x4 0x4>; + type = "uint32"; + default = <3>; + }; + }; + }; + + stickypage: stickypage { + compatible = "barebox,hostfile", "syscon", "simple-mfd"; + reg = <0 0 0 4096>; + barebox,cdev; /* no caching allowed */ + + bmode: reboot-mode { + compatible = "syscon-reboot-mode"; + offset = <0>; + mask = <0xffffff00>; + mode-normal = <0x00000000>; + mode-loader = <0xbbbbbb00>; + }; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* 0x00+4 reserved for syscon use */ + + part_env: env@400 { + reg = <0x400 0x800>; + label = "env"; + }; + + part_state: state@800 { + reg = <0xC00 0x400>; + label = "state"; + }; + }; + }; + + power { + compatible = "barebox,sandbox-power"; + barebox,reset-source = <&stickypage 0>; + }; + watchdog { + compatible = "barebox,sandbox-watchdog"; + barebox,reset-source = <&stickypage 0>; + }; }; diff --git a/arch/sandbox/dts/skeleton.dtsi b/arch/sandbox/dts/skeleton.dtsi deleted file mode 100644 index 8ba7663eb5..0000000000 --- a/arch/sandbox/dts/skeleton.dtsi +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Skeleton device tree; the bare minimum needed to boot; just include and - * add a compatible value. The bootloader will typically populate the memory - * node. - */ - -/ { - #address-cells = <2>; - #size-cells = <2>; - chosen { }; - aliases { }; - memory { device_type = "memory"; reg = <0 0 0 0>; }; -}; diff --git a/arch/sandbox/mach-sandbox/include/mach/hostfile.h b/arch/sandbox/mach-sandbox/include/mach/hostfile.h index c3f9af97c4..3ef34bcc1c 100644 --- a/arch/sandbox/mach-sandbox/include/mach/hostfile.h +++ b/arch/sandbox/mach-sandbox/include/mach/hostfile.h @@ -8,6 +8,8 @@ struct hf_info { const char *devname; const char *filename; unsigned int is_blockdev:1; + unsigned int is_cdev:1; + unsigned int is_readonly:1; }; int barebox_register_filedev(struct hf_info *hf); diff --git a/arch/sandbox/mach-sandbox/include/mach/linux.h b/arch/sandbox/mach-sandbox/include/mach/linux.h index 1ab48e52a0..b26bfc24a2 100644 --- a/arch/sandbox/mach-sandbox/include/mach/linux.h +++ b/arch/sandbox/mach-sandbox/include/mach/linux.h @@ -1,6 +1,8 @@ #ifndef __ASM_ARCH_LINUX_H #define __ASM_ARCH_LINUX_H +struct hf_info; + struct device_d; int sandbox_add_device(struct device_d *dev); @@ -11,6 +13,7 @@ int linux_register_device(const char *name, void *start, void *end); int tap_alloc(const char *dev); uint64_t linux_get_time(void); int linux_open(const char *filename, int readwrite); +int linux_open_hostfile(struct hf_info *hf); int linux_read(int fd, void *buf, size_t count); int linux_read_nonblock(int fd, void *buf, size_t count); ssize_t linux_write(int fd, const void *buf, size_t count); @@ -22,6 +25,8 @@ void linux_reexec(void); int linux_execve(const char * filename, char *const argv[], char *const envp[]); +int linux_watchdog_set_timeout(unsigned int timeout); + int barebox_register_console(int stdinfd, int stdoutfd); int barebox_register_dtb(const void *dtb); diff --git a/arch/sandbox/os/common.c b/arch/sandbox/os/common.c index 43ee95edb6..da87be29c7 100644 --- a/arch/sandbox/os/common.c +++ b/arch/sandbox/os/common.c @@ -19,6 +19,7 @@ * These are host includes. Never include any barebox header * files here... */ +#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <stdint.h> @@ -38,6 +39,8 @@ #include <sys/wait.h> #include <sys/ioctl.h> #include <linux/fs.h> +#include <sys/time.h> +#include <signal.h> /* * ...except the ones needed to connect with barebox */ @@ -124,6 +127,7 @@ void __attribute__((noreturn)) linux_exit(void) exit(0); } +static size_t saved_argv_len; static char **saved_argv; void linux_reexec(void) @@ -242,6 +246,29 @@ int linux_execve(const char * filename, char *const argv[], char *const envp[]) } } +static void linux_watchdog(int signo) +{ + linux_reexec(); + _exit(0); +} + +int linux_watchdog_set_timeout(unsigned int timeout) +{ + static int signal_handler_installed; + + if (!signal_handler_installed) { + struct sigaction sact = { + .sa_flags = SA_NODEFER, .sa_handler = linux_watchdog + }; + + sigemptyset(&sact.sa_mask); + sigaction(SIGALRM, &sact, NULL); + signal_handler_installed = 1; + } + + return alarm(timeout); +} + extern void start_barebox(void); extern void mem_malloc_init(void *start, void *end); @@ -252,10 +279,8 @@ static int add_image(const char *_str, char *devname_template, int *devname_numb struct hf_info *hf = malloc(sizeof(struct hf_info)); char *str, *filename, *devname; char tmp[16]; - int readonly = 0, cdev = 0, blkdev = 0; - struct stat s; char *opt; - int fd, ret; + int ret; if (!hf) return -1; @@ -265,11 +290,11 @@ static int add_image(const char *_str, char *devname_template, int *devname_numb filename = strsep_unescaped(&str, ","); while ((opt = strsep_unescaped(&str, ","))) { if (!strcmp(opt, "ro")) - readonly = 1; + hf->is_readonly = 1; if (!strcmp(opt, "cdev")) - cdev = 1; + hf->is_cdev = 1; if (!strcmp(opt, "blkdev")) - blkdev = 1; + hf->is_blockdev = 1; } /* parses: "devname=filename" */ @@ -282,13 +307,64 @@ static int add_image(const char *_str, char *devname_template, int *devname_numb devname = tmp; } - printf("add %s backed by file %s%s\n", devname, - filename, readonly ? "(ro)" : ""); - - fd = open(filename, (readonly ? O_RDONLY : O_RDWR) | O_CLOEXEC); - hf->fd = fd; hf->filename = filename; - hf->is_blockdev = blkdev; + hf->devname = strdup(devname); + + ret = barebox_register_filedev(hf); + if (ret) + free(hf); + + return ret; +} + +int linux_open_hostfile(struct hf_info *hf) +{ + char *buf = NULL; + struct stat s; + int fd; + + printf("add %s %sbacked by file %s%s\n", hf->devname, + hf->filename ? "" : "initially un", hf->filename ?: "", + hf->is_readonly ? "(ro)" : ""); + + if (hf->filename) { + fd = hf->fd = open(hf->filename, (hf->is_readonly ? O_RDONLY : O_RDWR) | O_CLOEXEC); + } else { + char *filename; + int ret; + + ret = asprintf(&buf, "--image=%s=/tmp/barebox-hostfileXXXXXX", hf->devname); + if (ret < 0) { + perror("asprintf"); + goto err_out; + } + + filename = buf + strlen("--image==") + strlen(hf->devname); + + fd = hf->fd = mkstemp(filename); + if (fd >= 0) { + ret = fcntl(fd, F_SETFD, FD_CLOEXEC); + if (ret < 0) { + perror("fcntl"); + goto err_out; + } + + ret = ftruncate(fd, hf->size); + if (ret < 0) { + perror("ftruncate"); + goto err_out; + } + + hf->filename = filename; + + saved_argv = realloc(saved_argv, + ++saved_argv_len * sizeof(*saved_argv)); + if (!saved_argv) + exit(1); + saved_argv[saved_argv_len - 2] = buf; + saved_argv[saved_argv_len - 1] = NULL; + } + } if (fd < 0) { perror("open"); @@ -300,42 +376,41 @@ static int add_image(const char *_str, char *devname_template, int *devname_numb goto err_out; } + hf->base = (unsigned long)MAP_FAILED; hf->size = s.st_size; - hf->devname = strdup(devname); if (S_ISBLK(s.st_mode)) { if (ioctl(fd, BLKGETSIZE64, &hf->size) == -1) { perror("ioctl"); goto err_out; } - if (!cdev) + if (!hf->is_cdev) hf->is_blockdev = 1; } - if (hf->size <= SIZE_MAX) + if (hf->size <= SIZE_MAX) { hf->base = (unsigned long)mmap(NULL, hf->size, - PROT_READ | (readonly ? 0 : PROT_WRITE), + PROT_READ | (hf->is_readonly ? 0 : PROT_WRITE), MAP_SHARED, fd, 0); - else - printf("warning: %s: contiguous map failed\n", filename); - if (hf->base == (unsigned long)MAP_FAILED) - printf("warning: mmapping %s failed: %s\n", filename, strerror(errno)); + if (hf->base == (unsigned long)MAP_FAILED) + printf("warning: mmapping %s failed: %s\n", + hf->filename, strerror(errno)); + } else { + printf("warning: %s: contiguous map failed\n", hf->filename); + } - if (blkdev && hf->size % 512 != 0) { + if (hf->is_blockdev && hf->size % 512 != 0) { printf("warning: registering %s as block device failed: invalid block size\n", - filename); + hf->filename); return -EINVAL; } - ret = barebox_register_filedev(hf); - if (ret) - goto err_out; return 0; err_out: if (fd > 0) close(fd); - free(hf); + free(buf); return -1; } @@ -405,8 +480,6 @@ int main(int argc, char *argv[]) __sanitizer_set_death_callback(cookmode); #endif - saved_argv = argv; - while (1) { option_index = 0; opt = getopt_long(argc, argv, optstring, @@ -444,6 +517,12 @@ int main(int argc, char *argv[]) } } + saved_argv_len = argc + 1; + saved_argv = calloc(saved_argv_len, sizeof(*saved_argv)); + if (!saved_argv) + exit(1); + memcpy(saved_argv, argv, saved_argv_len * sizeof(*saved_argv)); + ram = malloc(malloc_size); if (!ram) { printf("unable to get malloc space\n"); |