summaryrefslogtreecommitdiffstats
path: root/arch/sandbox
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2020-10-14 12:46:52 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2020-10-14 12:46:52 +0200
commitbee1da7fcc005edab18fde60fd2ce956d12c5e18 (patch)
tree77d02747d657192acb10500f979b83e20d0447a3 /arch/sandbox
parentc29ce8d93f9403c3ce6ccc5e82fb7a7be41d6659 (diff)
parent765ecaf52b834278a2449fcb097754a3aae9aa96 (diff)
downloadbarebox-bee1da7fcc005edab18fde60fd2ce956d12c5e18.tar.gz
barebox-bee1da7fcc005edab18fde60fd2ce956d12c5e18.tar.xz
Merge branch 'for-next/sandbox' into master
Diffstat (limited to 'arch/sandbox')
-rw-r--r--arch/sandbox/Makefile1
-rw-r--r--arch/sandbox/board/Makefile3
-rw-r--r--arch/sandbox/board/devices.c3
-rw-r--r--arch/sandbox/board/dtb.c28
-rw-r--r--arch/sandbox/board/env/init/state12
-rw-r--r--arch/sandbox/board/hostfile.c94
-rw-r--r--arch/sandbox/board/power.c82
-rw-r--r--arch/sandbox/board/poweroff.c42
-rw-r--r--arch/sandbox/board/watchdog.c84
-rw-r--r--arch/sandbox/configs/sandbox_defconfig45
-rw-r--r--arch/sandbox/dts/Makefile4
-rw-r--r--arch/sandbox/dts/sandbox-state-example.dtsi50
-rw-r--r--arch/sandbox/dts/sandbox.dts94
-rw-r--r--arch/sandbox/dts/skeleton.dtsi13
-rw-r--r--arch/sandbox/mach-sandbox/include/mach/hostfile.h2
-rw-r--r--arch/sandbox/mach-sandbox/include/mach/linux.h5
-rw-r--r--arch/sandbox/os/common.c135
17 files changed, 513 insertions, 184 deletions
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");