* [PATCH v2 01/11] console: unconditionally run poller_call in ctrlc()
2021-03-01 11:00 [PATCH v2 00/11] common: introduce bthreads, co-operative Ahmad Fatoum
@ 2021-03-01 11:00 ` Ahmad Fatoum
2021-03-03 10:20 ` [PATCH] fixup! common: introduce bthreads, co-operative barebox threads Ahmad Fatoum
2021-03-01 11:00 ` [PATCH v2 02/11] " Ahmad Fatoum
` (10 subsequent siblings)
11 siblings, 1 reply; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-01 11:00 UTC (permalink / raw)
To: barebox; +Cc: Jules Maselbas, Stafford Horne, sha
From: Ahmad Fatoum <ahmad@a3f.at>
ctrlc is allowed only after init and reboot mode scripts have run, so
these scripts run uninterruptible. A side effect of this is that all
calls to ctrlc() will immediately return with false without running the
pollers. While init scripts shouldn't run too long, it's still
surprising behavior. Thus call poller_call() first thing in ctrlc().
Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
---
common/console.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/common/console.c b/common/console.c
index 306149c99ea1..974d3de9e483 100644
--- a/common/console.c
+++ b/common/console.c
@@ -579,14 +579,14 @@ int ctrlc(void)
{
int ret = 0;
+ poller_call();
+
if (!ctrlc_allowed)
return 0;
if (ctrlc_abort)
return 1;
- poller_call();
-
#ifdef ARCH_HAS_CTRLC
ret = arch_ctrlc();
#else
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH] fixup! common: introduce bthreads, co-operative barebox threads
2021-03-01 11:00 ` [PATCH v2 01/11] console: unconditionally run poller_call in ctrlc() Ahmad Fatoum
@ 2021-03-03 10:20 ` Ahmad Fatoum
2021-03-04 8:49 ` Sascha Hauer
0 siblings, 1 reply; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-03 10:20 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
commands/bthread.c | 142 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 142 insertions(+)
create mode 100644 commands/bthread.c
diff --git a/commands/bthread.c b/commands/bthread.c
new file mode 100644
index 000000000000..1fd782f03f43
--- /dev/null
+++ b/commands/bthread.c
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#include <bthread.h>
+#include <errno.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <command.h>
+#include <getopt.h>
+#include <clock.h>
+
+static int bthread_time(void)
+{
+ uint64_t start = get_time_ns();
+ int i = 0;
+
+ /*
+ * How many background tasks can we have in one second?
+ *
+ * A low number here may point to problems with bthreads taking too
+ * much time.
+ */
+ while (!is_timeout(start, SECOND))
+ i++;
+
+ return i;
+}
+
+static int bthread_infinite(void *data)
+{
+ while (!bthread_should_stop())
+ ;
+
+ return 0;
+}
+
+static int bthread_isolated_time(void)
+{
+ uint64_t start = get_time_ns();
+ struct bthread *bthread;
+ int i = 0;
+
+ bthread = bthread_create(bthread_infinite, NULL, "infinite");
+ if (!bthread)
+ return -ENOMEM;
+
+ bthread_wake(bthread);
+
+ /*
+ * How many context switches can we do in one second?
+ *
+ * A low number here may point to problems with bthreads taking too
+ * much time.
+ */
+ while (!is_timeout_non_interruptible(start, SECOND)) {
+ bthread_schedule(bthread);
+ i += 2;
+ }
+
+ bthread_stop(bthread);
+ bthread_free(bthread);
+
+ return i;
+}
+
+static int bthread_printer(void *arg)
+{
+ volatile u64 start;
+ volatile int i = 0;
+ start = get_time_ns();
+
+ while (!bthread_should_stop()) {
+ if (!is_timeout_non_interruptible(start, 225 * MSECOND))
+ continue;
+
+ printf("%s yield #%d\n", __func__, ++i);
+ start = get_time_ns();
+ }
+
+ return i;
+}
+
+BAREBOX_CMD_HELP_START(bthread)
+ BAREBOX_CMD_HELP_TEXT("print info about registered barebox threads")
+ BAREBOX_CMD_HELP_TEXT("")
+ BAREBOX_CMD_HELP_TEXT("Options:")
+ BAREBOX_CMD_HELP_OPT ("-i", "Print information about registered bthreads")
+ BAREBOX_CMD_HELP_OPT ("-t", "measure how many bthreads we currently run in 1s")
+ BAREBOX_CMD_HELP_OPT ("-c", "count maximum context switches in 1s")
+ BAREBOX_CMD_HELP_OPT ("-v", "verify correct bthread operation")
+ BAREBOX_CMD_HELP_END
+
+static int do_bthread(int argc, char *argv[])
+{
+ struct bthread *bthread = NULL;
+ int ret, opt;
+ int yields;
+
+ while ((opt = getopt(argc, argv, "itcv")) > 0) {
+ switch (opt) {
+ case 'i':
+ bthread_info();
+ return 0;
+ case 'c':
+ yields = bthread_isolated_time();
+ printf("%d bthread context switches possible in 1s\n", yields);
+ break;
+ case 'v':
+ bthread = bthread_create(bthread_printer, NULL, "bthread");
+ if (!bthread)
+ return -ENOMEM;
+
+ bthread_wake(bthread);
+
+ /* fallthrough */
+ case 't':
+ yields = bthread_time();
+ printf("%d bthread yield calls in 1s\n", yields);
+ }
+
+ if (bthread) {
+ ret = bthread_stop(bthread);
+ bthread_free(bthread);
+
+ if (ret != 4 || yields < ret)
+ return COMMAND_ERROR;
+ }
+
+ return 0;
+ }
+
+ return COMMAND_ERROR_USAGE;
+}
+
+BAREBOX_CMD_START(bthread)
+ .cmd = do_bthread,
+ BAREBOX_CMD_DESC("print info about registered bthreads")
+ BAREBOX_CMD_GROUP(CMD_GRP_MISC)
+ BAREBOX_CMD_HELP(cmd_bthread_help)
+BAREBOX_CMD_END
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] fixup! common: introduce bthreads, co-operative barebox threads
2021-03-03 10:20 ` [PATCH] fixup! common: introduce bthreads, co-operative barebox threads Ahmad Fatoum
@ 2021-03-04 8:49 ` Sascha Hauer
2021-03-04 9:17 ` Ahmad Fatoum
0 siblings, 1 reply; 27+ messages in thread
From: Sascha Hauer @ 2021-03-04 8:49 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox
On Wed, Mar 03, 2021 at 11:20:48AM +0100, Ahmad Fatoum wrote:
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> commands/bthread.c | 142 +++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 142 insertions(+)
> create mode 100644 commands/bthread.c
>
> diff --git a/commands/bthread.c b/commands/bthread.c
> new file mode 100644
> index 000000000000..1fd782f03f43
> --- /dev/null
> +++ b/commands/bthread.c
> @@ -0,0 +1,142 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
> + */
> +
> +#include <bthread.h>
> +#include <errno.h>
> +#include <malloc.h>
> +#include <stdio.h>
> +#include <command.h>
> +#include <getopt.h>
> +#include <clock.h>
> +
> +static int bthread_time(void)
> +{
> + uint64_t start = get_time_ns();
> + int i = 0;
> +
> + /*
> + * How many background tasks can we have in one second?
> + *
> + * A low number here may point to problems with bthreads taking too
> + * much time.
> + */
> + while (!is_timeout(start, SECOND))
> + i++;
> +
> + return i;
> +}
> +
> +static int bthread_infinite(void *data)
> +{
> + while (!bthread_should_stop())
> + ;
> +
> + return 0;
> +}
> +
> +static int bthread_isolated_time(void)
> +{
> + uint64_t start = get_time_ns();
> + struct bthread *bthread;
> + int i = 0;
> +
> + bthread = bthread_create(bthread_infinite, NULL, "infinite");
> + if (!bthread)
> + return -ENOMEM;
> +
> + bthread_wake(bthread);
> +
> + /*
> + * How many context switches can we do in one second?
> + *
> + * A low number here may point to problems with bthreads taking too
> + * much time.
> + */
> + while (!is_timeout_non_interruptible(start, SECOND)) {
> + bthread_schedule(bthread);
> + i += 2;
> + }
> +
> + bthread_stop(bthread);
> + bthread_free(bthread);
> +
> + return i;
> +}
> +
> +static int bthread_printer(void *arg)
> +{
> + volatile u64 start;
> + volatile int i = 0;
> + start = get_time_ns();
> +
> + while (!bthread_should_stop()) {
> + if (!is_timeout_non_interruptible(start, 225 * MSECOND))
> + continue;
> +
> + printf("%s yield #%d\n", __func__, ++i);
> + start = get_time_ns();
> + }
> +
> + return i;
> +}
> +
> +BAREBOX_CMD_HELP_START(bthread)
> + BAREBOX_CMD_HELP_TEXT("print info about registered barebox threads")
> + BAREBOX_CMD_HELP_TEXT("")
> + BAREBOX_CMD_HELP_TEXT("Options:")
> + BAREBOX_CMD_HELP_OPT ("-i", "Print information about registered bthreads")
> + BAREBOX_CMD_HELP_OPT ("-t", "measure how many bthreads we currently run in 1s")
> + BAREBOX_CMD_HELP_OPT ("-c", "count maximum context switches in 1s")
> + BAREBOX_CMD_HELP_OPT ("-v", "verify correct bthread operation")
> + BAREBOX_CMD_HELP_END
> +
> +static int do_bthread(int argc, char *argv[])
> +{
> + struct bthread *bthread = NULL;
> + int ret, opt;
> + int yields;
> +
> + while ((opt = getopt(argc, argv, "itcv")) > 0) {
> + switch (opt) {
> + case 'i':
> + bthread_info();
> + return 0;
> + case 'c':
> + yields = bthread_isolated_time();
> + printf("%d bthread context switches possible in 1s\n", yields);
> + break;
> + case 'v':
> + bthread = bthread_create(bthread_printer, NULL, "bthread");
> + if (!bthread)
> + return -ENOMEM;
> +
> + bthread_wake(bthread);
> +
> + /* fallthrough */
> + case 't':
> + yields = bthread_time();
> + printf("%d bthread yield calls in 1s\n", yields);
> + }
> +
> + if (bthread) {
> + ret = bthread_stop(bthread);
> + bthread_free(bthread);
> +
> + if (ret != 4 || yields < ret)
> + return COMMAND_ERROR;
> + }
> +
> + return 0;
> + }
Could you separate the option parsing from the functionality? The way it
currently is is rather hard to extend.
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 02/11] common: introduce bthreads, co-operative barebox threads
2021-03-01 11:00 [PATCH v2 00/11] common: introduce bthreads, co-operative Ahmad Fatoum
2021-03-01 11:00 ` [PATCH v2 01/11] console: unconditionally run poller_call in ctrlc() Ahmad Fatoum
@ 2021-03-01 11:00 ` Ahmad Fatoum
2021-03-01 12:42 ` Peter Korsgaard
2021-03-02 8:56 ` [PATCH] fixup! " Ahmad Fatoum
2021-03-01 11:00 ` [PATCH v2 03/11] ARM: asm: setjmp: annotate setjmp/longjmp for GCC Ahmad Fatoum
` (9 subsequent siblings)
11 siblings, 2 replies; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-01 11:00 UTC (permalink / raw)
To: barebox; +Cc: Jules Maselbas, Stafford Horne, Ahmad Fatoum, sha
Coroutines generalize subroutines for non-preemptive multitasking,
by allowing execution to be suspended and resumed. We already have very
limited coroutines in the form of pollers. A poller is a function that
is cooperatively scheduled and yields after it has run to completion.
In the next poller_call(), this function is resumed from start.
Proper coroutines allow for the this yielding to happen at any point of
time. The coroutine's state is then saved and execution continues else
where. Later on, execution is resumed by restoring the saved context.
standard C setjmp/longjmp can be used to implement stackless coroutines.
setjmp stores the registers comprising the execution context into a
jmp_buf and longjmp switches to that context and continues execution just
after the setjmp that allocated that jmp_buf.
These coroutines are stackless, because jumping to a setjmp down the
call stack means that the code there will clobber the stack
below it. On resuming the coroutine, it will run with a stack changed
in the interim leading to undefined behavior.
There are ways around that without resorting to Assembly:
- Allocate a buffer on the scheduler's stack, so coroutine can
grow into them
-> Problem: exploits Undefined behavior
- Yield first time on scheduler stack, then patch jmp_buf to point at
another stack
-> Problem: Code switching stacks should not itself use the stack
It thus seems there is no way around adding a new function to initialize
a setjmp with a freshly cloned stack.
This commit adds an implementation for co-operatively scheduled bthreads.
Architectures wishing to use it need to provide setjmp/longjmp/initjmp
and in their arch Kconfig should select CONFIG_HAS_ARCH_SJLJ.
Code wishing to make use of it will need a depends on
CONFIG_HAS_ARCH_SJLJ.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
Documentation/devel/background-execution.rst | 43 +++-
commands/Kconfig | 9 +
commands/Makefile | 1 +
common/Kconfig | 13 ++
common/Makefile | 1 +
common/bthread.c | 214 +++++++++++++++++++
common/clock.c | 5 +-
common/console.c | 2 +
include/bthread.h | 31 +++
include/slice.h | 16 +-
lib/readline.c | 5 +-
11 files changed, 326 insertions(+), 14 deletions(-)
create mode 100644 common/bthread.c
create mode 100644 include/bthread.h
diff --git a/Documentation/devel/background-execution.rst b/Documentation/devel/background-execution.rst
index eadad9d898d0..2fd70934d0b2 100644
--- a/Documentation/devel/background-execution.rst
+++ b/Documentation/devel/background-execution.rst
@@ -1,10 +1,10 @@
Background execution in barebox
===============================
-barebox is single-threaded and doesn't support interrupts. Nevertheless it is
-sometimes desired to execute code "in the background", like for example polling
-for completion of transfers or to regularly blink a heartbeat LED. For these
-scenarios barebox offers the techniques described below.
+barebox does not use interrupts to avoid the associated increase in complexity.
+Nevertheless it is sometimes desired to execute code "in the background",
+like for example polling for completion of transfers or to regularly blink a
+heartbeat LED. For these scenarios barebox offers the techniques described below.
Pollers
-------
@@ -71,6 +71,41 @@ actually queueing a work item on a work queue. This can be called from poller
code. Usually a work item is allocated by the poller and then freed either in
``work_queue.fn()`` or in ``work_queue.cancel()``.
+bthreads
+--------
+
+barebox threads are co-operative green threads, which are scheduled whenever
+``is_timeout()`` is called. This has a few implications. First of all,
+bthreads are not scheduled when ``is_timeout()`` is not called.
+For this and other reasons, loops polling for hardware events should always
+use a timeout, which is best implemented with ``is_timeout()``.
+Another thing to remember is that bthreads can be scheduled anywhere
+in the middle of other device accesses whenever ``is_timeout()`` is
+called. Care must be taken that a green thread doesn't access the very same device
+again itself. See "slices" below on how devices can safely be accessed from
+bthreads.
+
+Unlike pollers, which bthreads are replacing, bthreads are allowed
+access to virtual filesystem. The macro ``assert_command_context()`` is added
+to entry points of the VFS to have the thread yield until it may execute in
+in the correct context. The poller interface is declared in
+``include/bthread.h``. ``bthread_create()`` is used to allocate a bthread
+control block along with its stack. ``bthread_wake()`` can be used to hang
+it into the run queue. From this moment on and until the thread terminates,
+the thread will be switched to regularly as long as someone calls
+``is_timeout()``. bthreads are allowed to call ``is_timeout()``, which will
+arrange for other threads to execute.
+
+barebox threads replace previous the previous pollers and workqueues. Poller
+like behavior can be easily achieved by looping and yielding on every
+iteration. There's ``bthread_should_stop()``, which can be used as condition
+for continuing the loop. Workqueues can be replaced along the same line. On
+first VFS access, the thread will yield until it can run in the same context
+work queues used to execute in.
+
+If you want to add a new barebox thread, check that the devices it accesses
+are correctly using slices for protecting critical sections.
+
Slices
------
diff --git a/commands/Kconfig b/commands/Kconfig
index 520ad4b1dea3..6d84c956e576 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -253,6 +253,15 @@ config CMD_POLLER
is_timeout() or one of the various delay functions. The poller command prints
informations about registered pollers.
+config CMD_BTHREAD
+ tristate
+ prompt "bthread"
+ depends on BTHREAD
+ help
+ barebox threads are cooperatively-scheduled (green) threads that are running in
+ the background whenever code executes is_timeout() or one of the various delay
+ functions. The bthread command prints informations about registered bthreads.
+
config CMD_SLICE
tristate
prompt "slice"
diff --git a/commands/Makefile b/commands/Makefile
index 034c0e6383d3..cdf14a5e1d8d 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -129,6 +129,7 @@ obj-$(CONFIG_CMD_MMC_EXTCSD) += mmc_extcsd.o
obj-$(CONFIG_CMD_NAND_BITFLIP) += nand-bitflip.o
obj-$(CONFIG_CMD_SEED) += seed.o
obj-$(CONFIG_CMD_IP_ROUTE_GET) += ip-route-get.o
+obj-$(CONFIG_CMD_BTHREAD) += bthread.o
obj-$(CONFIG_CMD_UBSAN) += ubsan.o
UBSAN_SANITIZE_ubsan.o := y
diff --git a/common/Kconfig b/common/Kconfig
index edadcc9f4979..0e4a85f102ff 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -20,6 +20,11 @@ config HAS_CACHE
Drivers that depend on a cache implementation can depend on this
config, so that you don't get a compilation error.
+config HAS_ARCH_SJLJ
+ bool
+ help
+ Architecture has support implemented for setjmp()/longjmp()/initjmp()
+
config HAS_DMA
bool
help
@@ -955,6 +960,14 @@ config BAREBOXCRC32_TARGET
config POLLER
bool "generic polling infrastructure"
+config BTHREAD
+ bool "barebox co-operative (green) thread infrastructure"
+ depends on HAS_ARCH_SJLJ
+ help
+ barebox threads are lightweight cooperative (green) threads that are
+ scheduled within delay loops and the console idle to asynchronously
+ execute actions, like checking for link up or feeding a watchdog.
+
config STATE
bool "generic state infrastructure"
select CRC32
diff --git a/common/Makefile b/common/Makefile
index 0e0ba384c9b5..c0b45d263e5b 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_OFTREE) += oftree.o
obj-$(CONFIG_PARTITION_DISK) += partitions.o partitions/
obj-$(CONFIG_PASSWORD) += password.o
obj-$(CONFIG_POLLER) += poller.o
+obj-$(CONFIG_BTHREAD) += bthread.o
obj-$(CONFIG_RESET_SOURCE) += reset_source.o
obj-$(CONFIG_SHELL_HUSH) += hush.o
obj-$(CONFIG_SHELL_SIMPLE) += parser.o
diff --git a/common/bthread.c b/common/bthread.c
new file mode 100644
index 000000000000..399a13d24a1d
--- /dev/null
+++ b/common/bthread.c
@@ -0,0 +1,214 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
+ *
+ * ASAN bookkeeping based on Qemu coroutine-ucontext.c
+ */
+
+/* To avoid future issues; fortify doesn't like longjmp up the call stack */
+#ifndef __NO_FORTIFY
+#define __NO_FORTIFY
+#endif
+
+#include <common.h>
+#include <bthread.h>
+#include <asm/setjmp.h>
+#include <linux/overflow.h>
+
+struct bthread {
+ int (*threadfn)(void *);
+ union {
+ void *data;
+ int ret;
+ };
+ char *name;
+ jmp_buf jmp_buf;
+ void *stack;
+ u32 stack_size;
+ struct list_head list;
+#ifdef CONFIG_ASAN
+ void *fake_stack_save;
+#endif
+ u16 awake :1;
+ u16 should_stop :1;
+ u16 has_stopped :1;
+ u8 stack_space[] __aligned(16);
+} main_thread = {
+ .list = LIST_HEAD_INIT(main_thread.list),
+ .name = "main",
+};
+
+#define next(bthread) list_next_entry(bthread, list)
+#define prev(bthread) list_prev_entry(bthread, list)
+#define empty(bthread) list_empty(&(bthread)->list)
+
+static struct bthread *current = &main_thread;
+
+/*
+ * When using ASAN, it needs to be told when we switch stacks.
+ */
+static void start_switch_fiber(struct bthread *, bool terminate_old);
+static void finish_switch_fiber(struct bthread *);
+
+static void __noreturn bthread_trampoline(void)
+{
+ finish_switch_fiber(current);
+ bthread_schedule(&main_thread);
+
+ current->ret = current->threadfn(current->data);
+
+ current->has_stopped = true;
+ bthread_suspend(current);
+
+ current = &main_thread;
+ start_switch_fiber(&main_thread, true);
+ longjmp(main_thread.jmp_buf, 1);
+}
+
+void bthread_free(struct bthread *bthread)
+{
+ free(bthread->name);
+ free(bthread);
+}
+
+struct bthread *bthread_create(int (*threadfn)(void *), void *data, const char *name)
+{
+ struct bthread *bthread;
+ int ret;
+
+ bthread = malloc(struct_size(bthread, stack_space, CONFIG_STACK_SIZE));
+ if (!bthread)
+ return NULL;
+
+ memset(bthread, 0, sizeof(*bthread));
+
+ bthread->stack = bthread->stack_space;
+ bthread->stack_size = CONFIG_STACK_SIZE;
+ bthread->threadfn = threadfn;
+ bthread->data = data;
+ bthread->name = strdup(name);
+
+ /* set up bthread context with the new stack */
+ ret = initjmp(bthread->jmp_buf, bthread_trampoline,
+ bthread->stack + CONFIG_STACK_SIZE);
+ if (ret) {
+ bthread_free(bthread);
+ return NULL;
+ }
+
+ return bthread;
+}
+
+void bthread_wake(struct bthread *bthread)
+{
+ if (bthread->awake)
+ return;
+ list_add(&bthread->list, &main_thread.list);
+ bthread->awake = true;
+}
+
+void bthread_suspend(struct bthread *bthread)
+{
+ if (!bthread->awake || bthread == &main_thread)
+ return;
+ bthread->awake = false;
+ list_del(&bthread->list);
+}
+
+int bthread_stop(struct bthread *bthread)
+{
+ bthread->should_stop = true;
+
+ while (!bthread->has_stopped)
+ bthread_reschedule();
+
+ return bthread->ret;
+}
+
+int bthread_should_stop(void)
+{
+ if (current == &main_thread)
+ return -EINTR;
+ bthread_schedule(&main_thread);
+ return current->should_stop;
+}
+
+void bthread_info(void)
+{
+ struct bthread *bthread;
+
+ printf("Registered secondary barebox threads:\n");
+
+ if (empty(&main_thread)) {
+ printf("<none>\n");
+ return;
+ }
+
+ list_for_each_entry(bthread, &main_thread.list, list)
+ printf("%s\n", bthread->name);
+}
+
+void bthread_reschedule(void)
+{
+ struct bthread *to, *tmp;
+
+ if (current != &main_thread) {
+ bthread_schedule(&main_thread);
+ return;
+ }
+
+ list_for_each_entry_safe(to, tmp, &main_thread.list, list)
+ bthread_schedule(to);
+}
+
+void bthread_schedule(struct bthread *to)
+{
+ struct bthread *from = current;
+ int ret;
+
+ start_switch_fiber(to, false);
+
+ ret = setjmp(from->jmp_buf);
+ if (ret == 0) {
+ current = to;
+ longjmp(to->jmp_buf, 1);
+ }
+
+ finish_switch_fiber(from);
+}
+
+#ifdef CONFIG_ASAN
+
+void __sanitizer_start_switch_fiber(void **fake_stack_save, const void *bottom, size_t size);
+void __sanitizer_finish_switch_fiber(void *fake_stack_save, const void **bottom_old, size_t *size_old);
+
+static void finish_switch_fiber(struct bthread *bthread)
+{
+ const void *bottom_old;
+ size_t size_old;
+
+ __sanitizer_finish_switch_fiber(bthread->fake_stack_save, &bottom_old, &size_old);
+
+ if (!main_thread.stack) {
+ main_thread.stack = (void *)bottom_old;
+ main_thread.stack_size = size_old;
+ }
+}
+
+static void start_switch_fiber(struct bthread *to, bool terminate_old)
+{
+ __sanitizer_start_switch_fiber(terminate_old ? &to->fake_stack_save : NULL,
+ to->stack, to->stack_size);
+}
+
+#else
+
+static void finish_switch_fiber(struct bthread *bthread)
+{
+}
+
+static void start_switch_fiber(struct bthread *to, bool terminate_old)
+{
+}
+
+#endif
diff --git a/common/clock.c b/common/clock.c
index 7eeba88317ac..3781268cc796 100644
--- a/common/clock.c
+++ b/common/clock.c
@@ -14,6 +14,7 @@
#include <linux/math64.h>
#include <clock.h>
#include <poller.h>
+#include <bthread.h>
static uint64_t time_ns;
@@ -171,8 +172,10 @@ int is_timeout(uint64_t start_ns, uint64_t time_offset_ns)
{
int ret = is_timeout_non_interruptible(start_ns, time_offset_ns);
- if (time_offset_ns >= 100 * USECOND)
+ if (time_offset_ns >= 100 * USECOND) {
poller_call();
+ bthread_reschedule();
+ }
return ret;
}
diff --git a/common/console.c b/common/console.c
index 974d3de9e483..a1d7c1eb54a0 100644
--- a/common/console.c
+++ b/common/console.c
@@ -18,6 +18,7 @@
#include <kfifo.h>
#include <module.h>
#include <poller.h>
+#include <bthread.h>
#include <ratp_bb.h>
#include <magicvar.h>
#include <globalvar.h>
@@ -580,6 +581,7 @@ int ctrlc(void)
int ret = 0;
poller_call();
+ bthread_reschedule();
if (!ctrlc_allowed)
return 0;
diff --git a/include/bthread.h b/include/bthread.h
new file mode 100644
index 000000000000..2935852f68cf
--- /dev/null
+++ b/include/bthread.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#ifndef __BTHREAD_H_
+#define __BTHREAD_H_
+
+#include <linux/stddef.h>
+
+struct bthread;
+
+struct bthread *bthread_create(int (*threadfn)(void *), void *data, const char *name);
+void bthread_free(struct bthread *bthread);
+
+void bthread_schedule(struct bthread *);
+void bthread_wake(struct bthread *bthread);
+void bthread_suspend(struct bthread *bthread);
+int bthread_should_stop(void);
+int bthread_stop(struct bthread *bthread);
+void bthread_info(void);
+
+#ifdef CONFIG_BTHREAD
+void bthread_reschedule(void);
+#else
+static inline void bthread_reschedule(void)
+{
+}
+#endif
+
+#endif
diff --git a/include/slice.h b/include/slice.h
index b2d65b80cd69..4916263d1b8b 100644
--- a/include/slice.h
+++ b/include/slice.h
@@ -1,6 +1,8 @@
#ifndef __SLICE_H
#define __SLICE_H
+#include <bthread.h>
+
enum slice_action {
SLICE_ACQUIRE = 1,
SLICE_RELEASE = -1,
@@ -35,12 +37,10 @@ void command_slice_release(void);
extern int poller_active;
-#ifdef CONFIG_POLLER
-#define assert_command_context() ({ \
- WARN_ONCE(poller_active, "%s called in poller\n", __func__); \
-})
-#else
-#define assert_command_context() do { } while (0)
-#endif
+#define assert_command_context() do { \
+ WARN_ONCE(IS_ENABLED(CONFIG_POLLER) && poller_active, "%s called in poller\n", __func__); \
+ while (IS_ENABLED(CONFIG_BTHREAD) && !slice_acquired(&command_slice)) \
+ bthread_reschedule(); \
+} while (0)
-#endif /* __SLICE_H */
+#endif
diff --git a/lib/readline.c b/lib/readline.c
index e5370f9c7b6e..87f3e715c129 100644
--- a/lib/readline.c
+++ b/lib/readline.c
@@ -3,6 +3,7 @@
#include <init.h>
#include <libbb.h>
#include <poller.h>
+#include <bthread.h>
#include <xfuncs.h>
#include <complete.h>
#include <linux/ctype.h>
@@ -199,8 +200,10 @@ int readline(const char *prompt, char *buf, int len)
puts (prompt);
while (1) {
- while (!tstc())
+ while (!tstc()) {
poller_call();
+ bthread_reschedule();
+ }
ichar = read_key();
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2 02/11] common: introduce bthreads, co-operative barebox threads
2021-03-01 11:00 ` [PATCH v2 02/11] " Ahmad Fatoum
@ 2021-03-01 12:42 ` Peter Korsgaard
2021-03-02 8:56 ` Ahmad Fatoum
2021-03-02 8:56 ` [PATCH] fixup! " Ahmad Fatoum
1 sibling, 1 reply; 27+ messages in thread
From: Peter Korsgaard @ 2021-03-01 12:42 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox, Stafford Horne, sha, Jules Maselbas
>>>>> "Ahmad" == Ahmad Fatoum <a.fatoum@pengutronix.de> writes:
Hi,
> +bthreads
> +--------
> +
> +barebox threads are co-operative green threads, which are scheduled whenever
> +``is_timeout()`` is called. This has a few implications. First of all,
> +bthreads are not scheduled when ``is_timeout()`` is not called.
> +For this and other reasons, loops polling for hardware events should always
> +use a timeout, which is best implemented with ``is_timeout()``.
> +Another thing to remember is that bthreads can be scheduled anywhere
> +in the middle of other device accesses whenever ``is_timeout()`` is
> +called. Care must be taken that a green thread doesn't access the very same device
> +again itself. See "slices" below on how devices can safely be accessed from
> +bthreads.
> +
> +Unlike pollers, which bthreads are replacing, bthreads are allowed
> +access to virtual filesystem. The macro ``assert_command_context()`` is added
> +to entry points of the VFS to have the thread yield until it may execute in
> +in the correct context. The poller interface is declared in
s/poller/bthread/
> +``include/bthread.h``. ``bthread_create()`` is used to allocate a bthread
> +control block along with its stack. ``bthread_wake()`` can be used to hang
> +it into the run queue. From this moment on and until the thread terminates,
s/hang it into/add/
> +the thread will be switched to regularly as long as someone calls
> +``is_timeout()``. bthreads are allowed to call ``is_timeout()``, which will
> +arrange for other threads to execute.
> +
> +barebox threads replace previous the previous pollers and workqueues. Poller
s/previous the previous/the previous infrastructure,/
--
Bye, Peter Korsgaard
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2 02/11] common: introduce bthreads, co-operative barebox threads
2021-03-01 12:42 ` Peter Korsgaard
@ 2021-03-02 8:56 ` Ahmad Fatoum
0 siblings, 0 replies; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-02 8:56 UTC (permalink / raw)
To: Peter Korsgaard; +Cc: barebox, Stafford Horne, sha, Jules Maselbas
Hello Peter,
On 01.03.21 13:42, Peter Korsgaard wrote:
>>>>>> "Ahmad" == Ahmad Fatoum <a.fatoum@pengutronix.de> writes:
>
> Hi,
>
> > +bthreads
> > +--------
> > +
> > +barebox threads are co-operative green threads, which are scheduled whenever
> > +``is_timeout()`` is called. This has a few implications. First of all,
> > +bthreads are not scheduled when ``is_timeout()`` is not called.
> > +For this and other reasons, loops polling for hardware events should always
> > +use a timeout, which is best implemented with ``is_timeout()``.
> > +Another thing to remember is that bthreads can be scheduled anywhere
> > +in the middle of other device accesses whenever ``is_timeout()`` is
> > +called. Care must be taken that a green thread doesn't access the very same device
> > +again itself. See "slices" below on how devices can safely be accessed from
> > +bthreads.
> > +
> > +Unlike pollers, which bthreads are replacing, bthreads are allowed
> > +access to virtual filesystem. The macro ``assert_command_context()`` is added
> > +to entry points of the VFS to have the thread yield until it may execute in
> > +in the correct context. The poller interface is declared in
>
> s/poller/bthread/
>
> > +``include/bthread.h``. ``bthread_create()`` is used to allocate a bthread
> > +control block along with its stack. ``bthread_wake()`` can be used to hang
> > +it into the run queue. From this moment on and until the thread terminates,
>
> s/hang it into/add/
>
> > +the thread will be switched to regularly as long as someone calls
> > +``is_timeout()``. bthreads are allowed to call ``is_timeout()``, which will
> > +arrange for other threads to execute.
> > +
> > +barebox threads replace previous the previous pollers and workqueues. Poller
>
> s/previous the previous/the previous infrastructure,/
Thanks! Just sent out a fixup.
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH] fixup! common: introduce bthreads, co-operative barebox threads
2021-03-01 11:00 ` [PATCH v2 02/11] " Ahmad Fatoum
2021-03-01 12:42 ` Peter Korsgaard
@ 2021-03-02 8:56 ` Ahmad Fatoum
1 sibling, 0 replies; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-02 8:56 UTC (permalink / raw)
To: barebox; +Cc: Peter Korsgaard, Ahmad Fatoum
Fix copy-paste left-overs and an instance of Denglish.
Suggested-by: Peter Korsgaard <peter@korsgaard.com>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
Documentation/devel/background-execution.rst | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Documentation/devel/background-execution.rst b/Documentation/devel/background-execution.rst
index 2fd70934d0b2..b9daaa135ccb 100644
--- a/Documentation/devel/background-execution.rst
+++ b/Documentation/devel/background-execution.rst
@@ -88,15 +88,15 @@ bthreads.
Unlike pollers, which bthreads are replacing, bthreads are allowed
access to virtual filesystem. The macro ``assert_command_context()`` is added
to entry points of the VFS to have the thread yield until it may execute in
-in the correct context. The poller interface is declared in
+in the correct context. The bthread interface is declared in
``include/bthread.h``. ``bthread_create()`` is used to allocate a bthread
-control block along with its stack. ``bthread_wake()`` can be used to hang
+control block along with its stack. ``bthread_wake()`` can be used to add
it into the run queue. From this moment on and until the thread terminates,
the thread will be switched to regularly as long as someone calls
``is_timeout()``. bthreads are allowed to call ``is_timeout()``, which will
arrange for other threads to execute.
-barebox threads replace previous the previous pollers and workqueues. Poller
+barebox threads replace the previous infrastructure, pollers and workqueues. Poller
like behavior can be easily achieved by looping and yielding on every
iteration. There's ``bthread_should_stop()``, which can be used as condition
for continuing the loop. Workqueues can be replaced along the same line. On
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 03/11] ARM: asm: setjmp: annotate setjmp/longjmp for GCC
2021-03-01 11:00 [PATCH v2 00/11] common: introduce bthreads, co-operative Ahmad Fatoum
2021-03-01 11:00 ` [PATCH v2 01/11] console: unconditionally run poller_call in ctrlc() Ahmad Fatoum
2021-03-01 11:00 ` [PATCH v2 02/11] " Ahmad Fatoum
@ 2021-03-01 11:00 ` Ahmad Fatoum
2021-03-01 11:00 ` [PATCH v2 04/11] ARM: asm: setjmp: implement coroutine dependency initjmp() Ahmad Fatoum
` (8 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-01 11:00 UTC (permalink / raw)
To: barebox; +Cc: Jules Maselbas, Stafford Horne, Ahmad Fatoum, sha
To avoid invalid optimizations and to enable warnings, GCC must be told
that setjmp and longjmp are to be handled specially. Add the missing
attributes.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/include/asm/setjmp.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/include/asm/setjmp.h b/arch/arm/include/asm/setjmp.h
index 62bac613d6e1..538d9cd50651 100644
--- a/arch/arm/include/asm/setjmp.h
+++ b/arch/arm/include/asm/setjmp.h
@@ -23,7 +23,7 @@ struct jmp_buf_data {
typedef struct jmp_buf_data jmp_buf[1];
-int setjmp(jmp_buf jmp);
-void longjmp(jmp_buf jmp, int ret);
+int setjmp(jmp_buf jmp) __attribute__((returns_twice));
+void longjmp(jmp_buf jmp, int ret) __attribute__((noreturn));
#endif /* _SETJMP_H_ */
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 04/11] ARM: asm: setjmp: implement coroutine dependency initjmp()
2021-03-01 11:00 [PATCH v2 00/11] common: introduce bthreads, co-operative Ahmad Fatoum
` (2 preceding siblings ...)
2021-03-01 11:00 ` [PATCH v2 03/11] ARM: asm: setjmp: annotate setjmp/longjmp for GCC Ahmad Fatoum
@ 2021-03-01 11:00 ` Ahmad Fatoum
2021-03-01 11:01 ` [PATCH v2 05/11] sandbox: asm: implement setjmp/longjmp/initjmp Ahmad Fatoum
` (7 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-01 11:00 UTC (permalink / raw)
To: barebox; +Cc: Jules Maselbas, Stafford Horne, Ahmad Fatoum, sha
Implement initjmp() for use with the coroutine implementation.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/Kconfig | 1 +
arch/arm/include/asm/setjmp.h | 2 ++
arch/arm/lib32/setjmp.S | 8 ++++++++
arch/arm/lib64/setjmp.S | 9 +++++++++
4 files changed, 20 insertions(+)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ab0bf030131c..cdb934136e34 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -5,6 +5,7 @@ config ARM
select HAVE_CONFIGURABLE_TEXT_BASE if !RELOCATABLE
select HAVE_IMAGE_COMPRESSION
select HAVE_ARCH_KASAN
+ select HAS_ARCH_SJLJ
select ARM_OPTIMZED_STRING_FUNCTIONS if KASAN
default y
diff --git a/arch/arm/include/asm/setjmp.h b/arch/arm/include/asm/setjmp.h
index 538d9cd50651..4877e4312411 100644
--- a/arch/arm/include/asm/setjmp.h
+++ b/arch/arm/include/asm/setjmp.h
@@ -26,4 +26,6 @@ typedef struct jmp_buf_data jmp_buf[1];
int setjmp(jmp_buf jmp) __attribute__((returns_twice));
void longjmp(jmp_buf jmp, int ret) __attribute__((noreturn));
+int initjmp(jmp_buf jmp, void __noreturn (*func)(void), void *stack_top);
+
#endif /* _SETJMP_H_ */
diff --git a/arch/arm/lib32/setjmp.S b/arch/arm/lib32/setjmp.S
index f0606a7f6659..626d915da183 100644
--- a/arch/arm/lib32/setjmp.S
+++ b/arch/arm/lib32/setjmp.S
@@ -33,4 +33,12 @@ ENTRY(longjmp)
1:
bx lr
ENDPROC(longjmp)
+
+.pushsection .text.initjmp, "ax"
+ENTRY(initjmp)
+ str a3, [a1, #32] /* stack pointer */
+ str a2, [a1, #36] /* return address */
+ mov a1, #0
+ bx lr
+ENDPROC(initjmp)
.popsection
diff --git a/arch/arm/lib64/setjmp.S b/arch/arm/lib64/setjmp.S
index 0910e2f5a6c3..80be8cb0f201 100644
--- a/arch/arm/lib64/setjmp.S
+++ b/arch/arm/lib64/setjmp.S
@@ -36,3 +36,12 @@ ENTRY(longjmp)
ret
ENDPROC(longjmp)
.popsection
+
+.pushsection .text.initjmp, "ax"
+ENTRY(initjmp)
+ str x2, [x0, #96] /* stack pointer */
+ str x1, [x0, #88] /* return address */
+ mov x0, #0
+ ret
+ENDPROC(initjmp)
+.popsection
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 05/11] sandbox: asm: implement setjmp/longjmp/initjmp
2021-03-01 11:00 [PATCH v2 00/11] common: introduce bthreads, co-operative Ahmad Fatoum
` (3 preceding siblings ...)
2021-03-01 11:00 ` [PATCH v2 04/11] ARM: asm: setjmp: implement coroutine dependency initjmp() Ahmad Fatoum
@ 2021-03-01 11:01 ` Ahmad Fatoum
2021-03-01 11:01 ` [PATCH v2 06/11] riscv: Add asm/asm.h Ahmad Fatoum
` (6 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-01 11:01 UTC (permalink / raw)
To: barebox; +Cc: Jules Maselbas, Stafford Horne, Ahmad Fatoum, sha
To extend yielding poller support to sandbox, implement setjmp, longjmp
and initjmp. Unlike bare metal platforms, setjmp() and longjmp() are
readily provided on standard-conforming hosted platforms. initjmp() on
the other hand requires us to be able to invoke a function with a
user-supplied stack pointer, which isn't possible in standard C.
For POSIX systems, there are two methods to portably achieve this
though:
- Use makecontext(2) to set up a new context. makecontext(2) was however
removed in POSIX.1-2008 and at least GCC 10.2.1 ASan complains that it
"doesn't fully support makecontext/swapcontext functions and may
produce false positives in some cases!"
- Use sigaltstack to set a new signal stack, call setjmp there to
store the stack pointer, return regularly from signal handler and then
longjmp back and invoke the coroutine.
Both methods are implemented in QEMU. While QEMU uses the makecontext
method by default, for the reasons described, import the second implementation
and use it implement initjmp.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/sandbox/Kconfig | 1 +
arch/sandbox/Makefile | 5 +-
arch/sandbox/include/asm/setjmp.h | 17 +++
arch/sandbox/os/Makefile | 5 +-
arch/sandbox/os/setjmp.c | 180 ++++++++++++++++++++++++++++++
5 files changed, 204 insertions(+), 4 deletions(-)
create mode 100644 arch/sandbox/include/asm/setjmp.h
create mode 100644 arch/sandbox/os/setjmp.c
diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig
index 1a4e3bacf66d..cef8e9fb7ab4 100644
--- a/arch/sandbox/Kconfig
+++ b/arch/sandbox/Kconfig
@@ -13,6 +13,7 @@ config SANDBOX
select PARTITION_DISK
select ARCH_HAS_STACK_DUMP if ASAN
select GENERIC_FIND_NEXT_BIT
+ select HAS_ARCH_SJLJ
default y
config ARCH_TEXT_BASE
diff --git a/arch/sandbox/Makefile b/arch/sandbox/Makefile
index ea594944e4eb..5fc7e227be67 100644
--- a/arch/sandbox/Makefile
+++ b/arch/sandbox/Makefile
@@ -27,7 +27,8 @@ KBUILD_CFLAGS += -Dmalloc=barebox_malloc -Dcalloc=barebox_calloc \
-Dftruncate=barebox_ftruncate -Dasprintf=barebox_asprintf \
-Dopendir=barebox_opendir -Dreaddir=barebox_readdir \
-Dclosedir=barebox_closedir -Dreadlink=barebox_readlink \
- -Doptarg=barebox_optarg -Doptind=barebox_optind
+ -Doptarg=barebox_optarg -Doptind=barebox_optind \
+ -Dsetjmp=barebox_setjmp -Dlongjmp=barebox_longjmp
machdirs := $(patsubst %,arch/sandbox/mach-%/,$(machine-y))
@@ -64,7 +65,7 @@ endif
BAREBOX_LDFLAGS += \
-Wl,-T,$(BAREBOX_LDS) \
-Wl,--whole-archive $(BAREBOX_OBJS) -Wl,--no-whole-archive \
- -lrt $(SDL_LIBS) $(FTDI1_LIBS) \
+ -lrt -pthread $(SDL_LIBS) $(FTDI1_LIBS) \
$(SANITIZER_LIBS)
cmd_barebox__ = $(CC) -o $@ $(BAREBOX_LDFLAGS)
diff --git a/arch/sandbox/include/asm/setjmp.h b/arch/sandbox/include/asm/setjmp.h
new file mode 100644
index 000000000000..f085a9079dd7
--- /dev/null
+++ b/arch/sandbox/include/asm/setjmp.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __SETJMP_H_
+#define __SETJMP_H_
+
+struct jmp_buf_data {
+ unsigned char opaque[512] __aligned(16);
+};
+
+typedef struct jmp_buf_data jmp_buf[1];
+
+int setjmp(jmp_buf jmp) __attribute__((returns_twice));
+void longjmp(jmp_buf jmp, int ret) __attribute__((noreturn));
+
+int initjmp(jmp_buf jmp, void __noreturn (*func)(void), void *stack_top);
+
+#endif
diff --git a/arch/sandbox/os/Makefile b/arch/sandbox/os/Makefile
index fb2c3cfd8632..5d0c938ce68c 100644
--- a/arch/sandbox/os/Makefile
+++ b/arch/sandbox/os/Makefile
@@ -4,7 +4,8 @@ machdirs := $(patsubst %,arch/sandbox/mach-%/,$(machine-y))
KBUILD_CPPFLAGS = $(patsubst %,-I$(srctree)/%include,$(machdirs))
-KBUILD_CPPFLAGS += -DCONFIG_MALLOC_SIZE=$(CONFIG_MALLOC_SIZE) -D_FILE_OFFSET_BITS=64
+KBUILD_CPPFLAGS += -DCONFIG_MALLOC_SIZE=$(CONFIG_MALLOC_SIZE) -D_FILE_OFFSET_BITS=64 \
+ -DCONFIG_STACK_SIZE=$(CONFIG_STACK_SIZE)
KBUILD_CFLAGS := -Wall
@@ -14,7 +15,7 @@ ifeq ($(CONFIG_SANDBOX_LINUX_I386),y)
KBUILD_CFLAGS += -m32
endif
-obj-y = common.o tap.o
+obj-y = common.o tap.o setjmp.o
obj-$(CONFIG_MALLOC_LIBC) += libc_malloc.o
CFLAGS_sdl.o = $(shell pkg-config sdl2 --cflags)
diff --git a/arch/sandbox/os/setjmp.c b/arch/sandbox/os/setjmp.c
new file mode 100644
index 000000000000..7f686b0fc6e9
--- /dev/null
+++ b/arch/sandbox/os/setjmp.c
@@ -0,0 +1,180 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ * sigaltstack coroutine initialization code
+ *
+ * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
+ * Copyright (C) 2011 Kevin Wolf <kwolf@redhat.com>
+ * Copyright (C) 2012 Alex Barcelo <abarcelo@ac.upc.edu>
+ * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
+ * This file is partly based on pth_mctx.c, from the GNU Portable Threads
+ * Copyright (c) 1999-2006 Ralf S. Engelschall <rse@engelschall.com>
+ */
+
+/* XXX Is there a nicer way to disable glibc's stack check for longjmp? */
+#ifdef _FORTIFY_SOURCE
+#undef _FORTIFY_SOURCE
+#endif
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <setjmp.h>
+#include <signal.h>
+
+typedef sigjmp_buf _jmp_buf __attribute__((aligned((16))));
+_Static_assert(sizeof(_jmp_buf) <= 512, "sigjmp_buf size exceeds expectation");
+
+/*
+ * Information for the signal handler (trampoline)
+ */
+static struct {
+ _jmp_buf *reenter;
+ void (*entry)(void);
+ volatile sig_atomic_t called;
+} tr_state;
+
+/*
+ * "boot" function
+ * This is what starts the coroutine, is called from the trampoline
+ * (from the signal handler when it is not signal handling, read ahead
+ * for more information).
+ */
+static void __attribute__((noinline, noreturn))
+coroutine_bootstrap(void (*entry)(void))
+{
+ for (;;)
+ entry();
+}
+
+/*
+ * This is used as the signal handler. This is called with the brand new stack
+ * (thanks to sigaltstack). We have to return, given that this is a signal
+ * handler and the sigmask and some other things are changed.
+ */
+static void coroutine_trampoline(int signal)
+{
+ /* Get the thread specific information */
+ tr_state.called = 1;
+
+ /*
+ * Here we have to do a bit of a ping pong between the caller, given that
+ * this is a signal handler and we have to do a return "soon". Then the
+ * caller can reestablish everything and do a siglongjmp here again.
+ */
+ if (!sigsetjmp(*tr_state.reenter, 0)) {
+ return;
+ }
+
+ /*
+ * Ok, the caller has siglongjmp'ed back to us, so now prepare
+ * us for the real machine state switching. We have to jump
+ * into another function here to get a new stack context for
+ * the auto variables (which have to be auto-variables
+ * because the start of the thread happens later). Else with
+ * PIC (i.e. Position Independent Code which is used when PTH
+ * is built as a shared library) most platforms would
+ * horrible core dump as experience showed.
+ */
+ coroutine_bootstrap(tr_state.entry);
+}
+
+int initjmp(_jmp_buf jmp, void (*func)(void), void *stack_top)
+{
+ struct sigaction sa;
+ struct sigaction osa;
+ stack_t ss;
+ stack_t oss;
+ sigset_t sigs;
+ sigset_t osigs;
+
+ /* The way to manipulate stack is with the sigaltstack function. We
+ * prepare a stack, with it delivering a signal to ourselves and then
+ * put sigsetjmp/siglongjmp where needed.
+ * This has been done keeping coroutine-ucontext (from the QEMU project)
+ * as a model and with the pth ideas (GNU Portable Threads).
+ * See coroutine-ucontext for the basics of the coroutines and see
+ * pth_mctx.c (from the pth project) for the
+ * sigaltstack way of manipulating stacks.
+ */
+
+ tr_state.entry = func;
+ tr_state.reenter = (void *)jmp;
+
+ /*
+ * Preserve the SIGUSR2 signal state, block SIGUSR2,
+ * and establish our signal handler. The signal will
+ * later transfer control onto the signal stack.
+ */
+ sigemptyset(&sigs);
+ sigaddset(&sigs, SIGUSR2);
+ pthread_sigmask(SIG_BLOCK, &sigs, &osigs);
+ sa.sa_handler = coroutine_trampoline;
+ sigfillset(&sa.sa_mask);
+ sa.sa_flags = SA_ONSTACK;
+ if (sigaction(SIGUSR2, &sa, &osa) != 0) {
+ return -1;
+ }
+
+ /*
+ * Set the new stack.
+ */
+ ss.ss_sp = stack_top - CONFIG_STACK_SIZE;
+ ss.ss_size = CONFIG_STACK_SIZE;
+ ss.ss_flags = 0;
+ if (sigaltstack(&ss, &oss) < 0) {
+ return -1;
+ }
+
+ /*
+ * Now transfer control onto the signal stack and set it up.
+ * It will return immediately via "return" after the sigsetjmp()
+ * was performed. Be careful here with race conditions. The
+ * signal can be delivered the first time sigsuspend() is
+ * called.
+ */
+ tr_state.called = 0;
+ pthread_kill(pthread_self(), SIGUSR2);
+ sigfillset(&sigs);
+ sigdelset(&sigs, SIGUSR2);
+ while (!tr_state.called) {
+ sigsuspend(&sigs);
+ }
+
+ /*
+ * Inform the system that we are back off the signal stack by
+ * removing the alternative signal stack. Be careful here: It
+ * first has to be disabled, before it can be removed.
+ */
+ sigaltstack(NULL, &ss);
+ ss.ss_flags = SS_DISABLE;
+ if (sigaltstack(&ss, NULL) < 0) {
+ return -1;
+ }
+ sigaltstack(NULL, &ss);
+ if (!(oss.ss_flags & SS_DISABLE)) {
+ sigaltstack(&oss, NULL);
+ }
+
+ /*
+ * Restore the old SIGUSR2 signal handler and mask
+ */
+ sigaction(SIGUSR2, &osa, NULL);
+ pthread_sigmask(SIG_SETMASK, &osigs, NULL);
+
+ /*
+ * jmp can now be used to enter the trampoline again, but not as a
+ * signal handler. Instead it's longjmp'd to directly.
+ */
+
+ return 0;
+}
+
+int __attribute__((returns_twice)) barebox_setjmp(_jmp_buf jmp)
+{
+ return sigsetjmp(jmp, 0);
+}
+
+void __attribute((noreturn)) barebox_longjmp(_jmp_buf jmp, int ret)
+{
+ siglongjmp(jmp, ret);
+}
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 06/11] riscv: Add asm/asm.h
2021-03-01 11:00 [PATCH v2 00/11] common: introduce bthreads, co-operative Ahmad Fatoum
` (4 preceding siblings ...)
2021-03-01 11:01 ` [PATCH v2 05/11] sandbox: asm: implement setjmp/longjmp/initjmp Ahmad Fatoum
@ 2021-03-01 11:01 ` Ahmad Fatoum
2021-03-01 11:01 ` [PATCH v2 07/11] riscv: Add asm/linkage.h Ahmad Fatoum
` (5 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-01 11:01 UTC (permalink / raw)
To: barebox; +Cc: Jules Maselbas, Stafford Horne, Ahmad Fatoum, sha
From: Sascha Hauer <s.hauer@pengutronix.de>
Various definitions for assembly code, taken as-is from Linux.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/riscv/include/asm/asm.h | 69 ++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
create mode 100644 arch/riscv/include/asm/asm.h
diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
new file mode 100644
index 000000000000..9c992a88d858
--- /dev/null
+++ b/arch/riscv/include/asm/asm.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2015 Regents of the University of California
+ */
+
+#ifndef _ASM_RISCV_ASM_H
+#define _ASM_RISCV_ASM_H
+
+#ifdef __ASSEMBLY__
+#define __ASM_STR(x) x
+#else
+#define __ASM_STR(x) #x
+#endif
+
+#if __riscv_xlen == 64
+#define __REG_SEL(a, b) __ASM_STR(a)
+#elif __riscv_xlen == 32
+#define __REG_SEL(a, b) __ASM_STR(b)
+#else
+#error "Unexpected __riscv_xlen"
+#endif
+
+#define REG_L __REG_SEL(ld, lw)
+#define REG_S __REG_SEL(sd, sw)
+#define REG_SC __REG_SEL(sc.d, sc.w)
+#define SZREG __REG_SEL(8, 4)
+#define LGREG __REG_SEL(3, 2)
+
+#if __SIZEOF_POINTER__ == 8
+#ifdef __ASSEMBLY__
+#define RISCV_PTR .dword
+#define RISCV_SZPTR 8
+#define RISCV_LGPTR 3
+#else
+#define RISCV_PTR ".dword"
+#define RISCV_SZPTR "8"
+#define RISCV_LGPTR "3"
+#endif
+#elif __SIZEOF_POINTER__ == 4
+#ifdef __ASSEMBLY__
+#define RISCV_PTR .word
+#define RISCV_SZPTR 4
+#define RISCV_LGPTR 2
+#else
+#define RISCV_PTR ".word"
+#define RISCV_SZPTR "4"
+#define RISCV_LGPTR "2"
+#endif
+#else
+#error "Unexpected __SIZEOF_POINTER__"
+#endif
+
+#if (__SIZEOF_INT__ == 4)
+#define RISCV_INT __ASM_STR(.word)
+#define RISCV_SZINT __ASM_STR(4)
+#define RISCV_LGINT __ASM_STR(2)
+#else
+#error "Unexpected __SIZEOF_INT__"
+#endif
+
+#if (__SIZEOF_SHORT__ == 2)
+#define RISCV_SHORT __ASM_STR(.half)
+#define RISCV_SZSHORT __ASM_STR(2)
+#define RISCV_LGSHORT __ASM_STR(1)
+#else
+#error "Unexpected __SIZEOF_SHORT__"
+#endif
+
+#endif /* _ASM_RISCV_ASM_H */
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 07/11] riscv: Add asm/linkage.h
2021-03-01 11:00 [PATCH v2 00/11] common: introduce bthreads, co-operative Ahmad Fatoum
` (5 preceding siblings ...)
2021-03-01 11:01 ` [PATCH v2 06/11] riscv: Add asm/asm.h Ahmad Fatoum
@ 2021-03-01 11:01 ` Ahmad Fatoum
2021-03-01 11:01 ` [PATCH v2 08/11] riscv: Implement setjmp/longjmp/initjmp Ahmad Fatoum
` (4 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-01 11:01 UTC (permalink / raw)
To: barebox; +Cc: Jules Maselbas, Stafford Horne, Ahmad Fatoum, sha
From: Sascha Hauer <s.hauer@pengutronix.de>
Needed to include linux/linkage.h on riscv
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/riscv/include/asm/linkage.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
create mode 100644 arch/riscv/include/asm/linkage.h
diff --git a/arch/riscv/include/asm/linkage.h b/arch/riscv/include/asm/linkage.h
new file mode 100644
index 000000000000..9e88ba23cd2b
--- /dev/null
+++ b/arch/riscv/include/asm/linkage.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2015 Regents of the University of California
+ */
+
+#ifndef _ASM_RISCV_LINKAGE_H
+#define _ASM_RISCV_LINKAGE_H
+
+#define __ALIGN .balign 4
+#define __ALIGN_STR ".balign 4"
+
+#endif /* _ASM_RISCV_LINKAGE_H */
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 08/11] riscv: Implement setjmp/longjmp/initjmp
2021-03-01 11:00 [PATCH v2 00/11] common: introduce bthreads, co-operative Ahmad Fatoum
` (6 preceding siblings ...)
2021-03-01 11:01 ` [PATCH v2 07/11] riscv: Add asm/linkage.h Ahmad Fatoum
@ 2021-03-01 11:01 ` Ahmad Fatoum
2021-03-01 11:01 ` [PATCH v2 09/11] mips: Add linkage.h Ahmad Fatoum
` (3 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-01 11:01 UTC (permalink / raw)
To: barebox; +Cc: Jules Maselbas, Stafford Horne, Ahmad Fatoum, sha
From: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/riscv/Kconfig | 1 +
arch/riscv/include/asm/setjmp.h | 27 +++++++++++++++++++++++++
arch/riscv/lib/Makefile | 2 +-
arch/riscv/lib/longjmp.S | 28 ++++++++++++++++++++++++++
arch/riscv/lib/setjmp.S | 35 +++++++++++++++++++++++++++++++++
5 files changed, 92 insertions(+), 1 deletion(-)
create mode 100644 arch/riscv/include/asm/setjmp.h
create mode 100644 arch/riscv/lib/longjmp.S
create mode 100644 arch/riscv/lib/setjmp.S
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 16c3eecce6f8..107c24a66d3d 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -8,6 +8,7 @@ config RISCV
select COMMON_CLK
select COMMON_CLK_OF_PROVIDER
select CLKDEV_LOOKUP
+ select HAS_ARCH_SJLJ
config ARCH_TEXT_BASE
hex
diff --git a/arch/riscv/include/asm/setjmp.h b/arch/riscv/include/asm/setjmp.h
new file mode 100644
index 000000000000..7516f6825841
--- /dev/null
+++ b/arch/riscv/include/asm/setjmp.h
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
+ * (C) Copyright 2016 Alexander Graf <agraf@suse.de>
+ */
+
+#ifndef _SETJMP_H_
+#define _SETJMP_H_ 1
+
+#include <asm/types.h>
+
+typedef struct __jmp_buf_internal_tag
+ {
+ /* Program counter. */
+ long int __pc;
+ /* Callee-saved registers. */
+ long int __regs[12];
+ /* Stack pointer. */
+ long int __sp;
+} jmp_buf[1];
+
+int setjmp(jmp_buf jmp) __attribute__((returns_twice));
+void longjmp(jmp_buf jmp, int ret) __attribute__((noreturn));
+
+int initjmp(jmp_buf jmp, void __noreturn (*func)(void), void *stack_top);
+
+#endif /* _SETJMP_H_ */
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index a1df0b7dc78c..ff5751a812c2 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -1,3 +1,3 @@
extra-y += barebox.lds
-obj-y += riscv_timer.o
+obj-y += riscv_timer.o setjmp.o longjmp.o
diff --git a/arch/riscv/lib/longjmp.S b/arch/riscv/lib/longjmp.S
new file mode 100644
index 000000000000..7bcb5b30495d
--- /dev/null
+++ b/arch/riscv/lib/longjmp.S
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+/* longjmp, RISC-V version. */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+
+ENTRY (longjmp)
+ REG_L ra, 0*SZREG(a0)
+ REG_L s0, 1*SZREG(a0)
+ REG_L s1, 2*SZREG(a0)
+ REG_L s2, 3*SZREG(a0)
+ REG_L s3, 4*SZREG(a0)
+ REG_L s4, 5*SZREG(a0)
+ REG_L s5, 6*SZREG(a0)
+ REG_L s6, 7*SZREG(a0)
+ REG_L s7, 8*SZREG(a0)
+ REG_L s8, 9*SZREG(a0)
+ REG_L s9, 10*SZREG(a0)
+ REG_L s10,11*SZREG(a0)
+ REG_L s11,12*SZREG(a0)
+ REG_L sp, 13*SZREG(a0)
+
+ seqz a0, a1
+ add a0, a0, a1 # a0 = (a1 == 0) ? 1 : a1
+ ret
+
+END (longjmp)
diff --git a/arch/riscv/lib/setjmp.S b/arch/riscv/lib/setjmp.S
new file mode 100644
index 000000000000..e8ad01635dd3
--- /dev/null
+++ b/arch/riscv/lib/setjmp.S
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+/* setjmp for RISC-V. */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+
+ENTRY (setjmp)
+ REG_S ra, 0*SZREG(a0)
+ REG_S s0, 1*SZREG(a0)
+ REG_S s1, 2*SZREG(a0)
+ REG_S s2, 3*SZREG(a0)
+ REG_S s3, 4*SZREG(a0)
+ REG_S s4, 5*SZREG(a0)
+ REG_S s5, 6*SZREG(a0)
+ REG_S s6, 7*SZREG(a0)
+ REG_S s7, 8*SZREG(a0)
+ REG_S s8, 9*SZREG(a0)
+ REG_S s9, 10*SZREG(a0)
+ REG_S s10,11*SZREG(a0)
+ REG_S s11,12*SZREG(a0)
+ REG_S sp, 13*SZREG(a0)
+
+ li a0, 0
+ ret
+
+END (setjmp)
+
+ENTRY (initjmp)
+ REG_S a1, 0*SZREG(a0)
+ REG_S a2, 13*SZREG(a0)
+ li a0, 0
+ ret
+
+END (initjmp)
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 09/11] mips: Add linkage.h
2021-03-01 11:00 [PATCH v2 00/11] common: introduce bthreads, co-operative Ahmad Fatoum
` (7 preceding siblings ...)
2021-03-01 11:01 ` [PATCH v2 08/11] riscv: Implement setjmp/longjmp/initjmp Ahmad Fatoum
@ 2021-03-01 11:01 ` Ahmad Fatoum
2021-03-01 11:01 ` [PATCH v2 10/11] mips: Implement setjmp/longjmp/initjmp Ahmad Fatoum
` (2 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-01 11:01 UTC (permalink / raw)
To: barebox; +Cc: Jules Maselbas, Stafford Horne, Ahmad Fatoum, sha
From: Sascha Hauer <s.hauer@pengutronix.de>
Taken from Linux Kernel with unnecessary bits removed.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/mips/include/asm/linkage.h | 9 +++++++++
1 file changed, 9 insertions(+)
create mode 100644 arch/mips/include/asm/linkage.h
diff --git a/arch/mips/include/asm/linkage.h b/arch/mips/include/asm/linkage.h
new file mode 100644
index 000000000000..14835f513961
--- /dev/null
+++ b/arch/mips/include/asm/linkage.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#ifdef __ASSEMBLY__
+#include <asm/asm.h>
+#endif
+
+#endif
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 10/11] mips: Implement setjmp/longjmp/initjmp
2021-03-01 11:00 [PATCH v2 00/11] common: introduce bthreads, co-operative Ahmad Fatoum
` (8 preceding siblings ...)
2021-03-01 11:01 ` [PATCH v2 09/11] mips: Add linkage.h Ahmad Fatoum
@ 2021-03-01 11:01 ` Ahmad Fatoum
2021-03-02 22:19 ` Peter Mamonov
2021-03-01 11:01 ` [PATCH v2 11/11] powerpc: Implement initjmp/setjmp/longjmp Ahmad Fatoum
2021-03-03 12:15 ` [PATCH v2 00/11] common: introduce bthreads, co-operative Stafford Horne
11 siblings, 1 reply; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-01 11:01 UTC (permalink / raw)
To: barebox; +Cc: Jules Maselbas, Stafford Horne, Ahmad Fatoum, sha
From: Sascha Hauer <s.hauer@pengutronix.de>
The header has been taken from glibc, the implementation itself is based
on the newlib implementation.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/mips/Kconfig | 1 +
arch/mips/include/asm/setjmp.h | 32 ++++++++++++++++++++++
arch/mips/lib/Makefile | 1 +
arch/mips/lib/setjmp.S | 50 ++++++++++++++++++++++++++++++++++
4 files changed, 84 insertions(+)
create mode 100644 arch/mips/include/asm/setjmp.h
create mode 100644 arch/mips/lib/setjmp.S
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 48f97c4bbf30..e77c9279ead3 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -12,6 +12,7 @@ config MIPS
select HAS_DMA
select ARCH_HAS_DATA_ABORT_MASK
select ELF
+ select HAS_ARCH_SJLJ
default y
config SYS_SUPPORTS_BIG_ENDIAN
diff --git a/arch/mips/include/asm/setjmp.h b/arch/mips/include/asm/setjmp.h
new file mode 100644
index 000000000000..5a9af7773a5f
--- /dev/null
+++ b/arch/mips/include/asm/setjmp.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+/*
+ * Define the machine-dependent type `jmp_buf'. MIPS version.
+ * Copyright (C) 1992-2021 Free Software Foundation, Inc.
+ * This file is part of the GNU C Library.
+ */
+
+#ifndef _MIPS_BITS_SETJMP_H
+#define _MIPS_BITS_SETJMP_H 1
+
+#include <asm/sgidefs.h>
+
+typedef struct __jmp_buf_internal_tag {
+ /* Program counter. */
+ void *__pc;
+
+ /* Stack pointer. */
+ void *__sp;
+
+ /* Callee-saved registers s0 through s7. */
+ int __regs[8];
+
+ /* The frame pointer. */
+ void *__fp;
+} jmp_buf[1];
+
+int setjmp(jmp_buf jmp) __attribute__((returns_twice));
+void longjmp(jmp_buf jmp, int ret) __attribute__((noreturn));
+int initjmp(jmp_buf jmp, void __noreturn (*func)(void), void *stack_top);
+
+#endif /* _MIPS_BITS_SETJMP_H */
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 0761588ae865..f869ac088a7d 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -8,6 +8,7 @@ obj-y += reloc.o
obj-y += sections.o
obj-y += shutdown.o
obj-y += dma-default.o
+obj-y += setjmp.o
obj-$(CONFIG_MIPS_OPTIMIZED_STRING_FUNCTIONS) += memcpy.o
obj-$(CONFIG_MIPS_OPTIMIZED_STRING_FUNCTIONS) += memset.o
diff --git a/arch/mips/lib/setjmp.S b/arch/mips/lib/setjmp.S
new file mode 100644
index 000000000000..b09a7c55293c
--- /dev/null
+++ b/arch/mips/lib/setjmp.S
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <asm/regdef.h>
+#include <asm/asm.h>
+#include <linux/linkage.h>
+
+/* int setjmp (jmp_buf); */
+LEAF(setjmp)
+ sw ra, (0 * 4)(a0)
+ sw sp, (1 * 4)(a0)
+ sw s0, (2 * 4)(a0)
+ sw s1, (3 * 4)(a0)
+ sw s2, (4 * 4)(a0)
+ sw s3, (5 * 4)(a0)
+ sw s4, (6 * 4)(a0)
+ sw s5, (7 * 4)(a0)
+ sw s6, (8 * 4)(a0)
+ sw s7, (9 * 4)(a0)
+ sw fp, (10 * 4)(a0)
+ move v0, zero
+ j ra
+END(setjmp)
+
+/* volatile void longjmp (jmp_buf, int); */
+LEAF(longjmp)
+ lw ra, (0 * 4)(a0)
+ lw sp, (1 * 4)(a0)
+ lw s0, (2 * 4)(a0)
+ lw s1, (3 * 4)(a0)
+ lw s2, (4 * 4)(a0)
+ lw s3, (5 * 4)(a0)
+ lw s4, (6 * 4)(a0)
+ lw s5, (7 * 4)(a0)
+ lw s6, (8 * 4)(a0)
+ lw s7, (9 * 4)(a0)
+ lw fp, (10 * 4)(a0)
+ bne a1, zero, 1f
+ li a1, 1
+1:
+ move v0, a1
+ j ra
+END(longjmp)
+
+/* int initjmp(jmp_buf jmp, void __noreturn (*func)(void), void *stack_top); */
+LEAF(initjmp)
+ sw a1, (0 * 4)(a0)
+ sw a2, (1 * 4)(a0)
+ move v0, zero
+ j ra
+END(initjmp)
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2 10/11] mips: Implement setjmp/longjmp/initjmp
2021-03-01 11:01 ` [PATCH v2 10/11] mips: Implement setjmp/longjmp/initjmp Ahmad Fatoum
@ 2021-03-02 22:19 ` Peter Mamonov
2021-03-04 8:38 ` Sascha Hauer
0 siblings, 1 reply; 27+ messages in thread
From: Peter Mamonov @ 2021-03-02 22:19 UTC (permalink / raw)
To: Ahmad Fatoum, s.hauer; +Cc: barebox, Jules Maselbas, Stafford Horne, sha
Hi, Sascha and Ahmad,
On Mon, Mar 01, 2021 at 12:01:05PM +0100, Ahmad Fatoum wrote:
> From: Sascha Hauer <s.hauer@pengutronix.de>
>
> The header has been taken from glibc, the implementation itself is based
> on the newlib implementation.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> arch/mips/Kconfig | 1 +
> arch/mips/include/asm/setjmp.h | 32 ++++++++++++++++++++++
> arch/mips/lib/Makefile | 1 +
> arch/mips/lib/setjmp.S | 50 ++++++++++++++++++++++++++++++++++
> 4 files changed, 84 insertions(+)
> create mode 100644 arch/mips/include/asm/setjmp.h
> create mode 100644 arch/mips/lib/setjmp.S
>
> ...
>
> diff --git a/arch/mips/lib/setjmp.S b/arch/mips/lib/setjmp.S
> new file mode 100644
> index 000000000000..b09a7c55293c
> --- /dev/null
> +++ b/arch/mips/lib/setjmp.S
> @@ -0,0 +1,50 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#include <asm/regdef.h>
> +#include <asm/asm.h>
> +#include <linux/linkage.h>
> +
> +/* int setjmp (jmp_buf); */
> +LEAF(setjmp)
> + sw ra, (0 * 4)(a0)
> + sw sp, (1 * 4)(a0)
> + sw s0, (2 * 4)(a0)
> + sw s1, (3 * 4)(a0)
> + sw s2, (4 * 4)(a0)
> + sw s3, (5 * 4)(a0)
> + sw s4, (6 * 4)(a0)
> + sw s5, (7 * 4)(a0)
> + sw s6, (8 * 4)(a0)
> + sw s7, (9 * 4)(a0)
> + sw fp, (10 * 4)(a0)
> + move v0, zero
> + j ra
> +END(setjmp)
> +
> +/* volatile void longjmp (jmp_buf, int); */
> +LEAF(longjmp)
> + lw ra, (0 * 4)(a0)
> + lw sp, (1 * 4)(a0)
> + lw s0, (2 * 4)(a0)
> + lw s1, (3 * 4)(a0)
> + lw s2, (4 * 4)(a0)
> + lw s3, (5 * 4)(a0)
> + lw s4, (6 * 4)(a0)
> + lw s5, (7 * 4)(a0)
> + lw s6, (8 * 4)(a0)
> + lw s7, (9 * 4)(a0)
> + lw fp, (10 * 4)(a0)
> + bne a1, zero, 1f
> + li a1, 1
> +1:
> + move v0, a1
> + j ra
> +END(longjmp)
> +
> +/* int initjmp(jmp_buf jmp, void __noreturn (*func)(void), void *stack_top); */
> +LEAF(initjmp)
> + sw a1, (0 * 4)(a0)
> + sw a2, (1 * 4)(a0)
> + move v0, zero
> + j ra
> +END(initjmp)
I would suggest using `REG_S/REG_L r, (n * SZREG)(a0)` here for the sake of
MIPS64 targets. See arch/mips/include/asm/asm.h:272.
Regards,
Peter
> --
> 2.29.2
>
>
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2 10/11] mips: Implement setjmp/longjmp/initjmp
2021-03-02 22:19 ` Peter Mamonov
@ 2021-03-04 8:38 ` Sascha Hauer
2021-03-07 12:00 ` Peter Mamonov
0 siblings, 1 reply; 27+ messages in thread
From: Sascha Hauer @ 2021-03-04 8:38 UTC (permalink / raw)
To: Peter Mamonov; +Cc: Ahmad Fatoum, barebox, Jules Maselbas, Stafford Horne
Hi Peter,
On Wed, Mar 03, 2021 at 01:19:26AM +0300, Peter Mamonov wrote:
> Hi, Sascha and Ahmad,
>
> On Mon, Mar 01, 2021 at 12:01:05PM +0100, Ahmad Fatoum wrote:
> > From: Sascha Hauer <s.hauer@pengutronix.de>
> >
> > The header has been taken from glibc, the implementation itself is based
> > on the newlib implementation.
> >
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> > ---
> > arch/mips/Kconfig | 1 +
> > arch/mips/include/asm/setjmp.h | 32 ++++++++++++++++++++++
> > arch/mips/lib/Makefile | 1 +
> > arch/mips/lib/setjmp.S | 50 ++++++++++++++++++++++++++++++++++
> > 4 files changed, 84 insertions(+)
> > create mode 100644 arch/mips/include/asm/setjmp.h
> > create mode 100644 arch/mips/lib/setjmp.S
> >
> > ...
> >
> > diff --git a/arch/mips/lib/setjmp.S b/arch/mips/lib/setjmp.S
> > new file mode 100644
> > index 000000000000..b09a7c55293c
> > --- /dev/null
> > +++ b/arch/mips/lib/setjmp.S
> > @@ -0,0 +1,50 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +
> > +#include <asm/regdef.h>
> > +#include <asm/asm.h>
> > +#include <linux/linkage.h>
> > +
> > +/* int setjmp (jmp_buf); */
> > +LEAF(setjmp)
> > + sw ra, (0 * 4)(a0)
> > + sw sp, (1 * 4)(a0)
> > + sw s0, (2 * 4)(a0)
> > + sw s1, (3 * 4)(a0)
> > + sw s2, (4 * 4)(a0)
> > + sw s3, (5 * 4)(a0)
> > + sw s4, (6 * 4)(a0)
> > + sw s5, (7 * 4)(a0)
> > + sw s6, (8 * 4)(a0)
> > + sw s7, (9 * 4)(a0)
> > + sw fp, (10 * 4)(a0)
> > + move v0, zero
> > + j ra
> > +END(setjmp)
> > +
> > +/* volatile void longjmp (jmp_buf, int); */
> > +LEAF(longjmp)
> > + lw ra, (0 * 4)(a0)
> > + lw sp, (1 * 4)(a0)
> > + lw s0, (2 * 4)(a0)
> > + lw s1, (3 * 4)(a0)
> > + lw s2, (4 * 4)(a0)
> > + lw s3, (5 * 4)(a0)
> > + lw s4, (6 * 4)(a0)
> > + lw s5, (7 * 4)(a0)
> > + lw s6, (8 * 4)(a0)
> > + lw s7, (9 * 4)(a0)
> > + lw fp, (10 * 4)(a0)
> > + bne a1, zero, 1f
> > + li a1, 1
> > +1:
> > + move v0, a1
> > + j ra
> > +END(longjmp)
> > +
> > +/* int initjmp(jmp_buf jmp, void __noreturn (*func)(void), void *stack_top); */
> > +LEAF(initjmp)
> > + sw a1, (0 * 4)(a0)
> > + sw a2, (1 * 4)(a0)
> > + move v0, zero
> > + j ra
> > +END(initjmp)
>
> I would suggest using `REG_S/REG_L r, (n * SZREG)(a0)` here for the sake of
> MIPS64 targets. See arch/mips/include/asm/asm.h:272.
I agree with you, but barebox doesn't support MIPS64 currently and I
wasn't confident enough to add such things when I can't test them.
Maybe we can add a
#if SZREG != 4
#error setjmp/longjmp currently only supports 32bit targets
#endif
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2 10/11] mips: Implement setjmp/longjmp/initjmp
2021-03-04 8:38 ` Sascha Hauer
@ 2021-03-07 12:00 ` Peter Mamonov
2021-03-10 8:17 ` Ahmad Fatoum
0 siblings, 1 reply; 27+ messages in thread
From: Peter Mamonov @ 2021-03-07 12:00 UTC (permalink / raw)
To: Sascha Hauer; +Cc: Ahmad Fatoum, barebox, Jules Maselbas, Stafford Horne
On Thu, Mar 04, 2021 at 09:38:11AM +0100, Sascha Hauer wrote:
> Hi Peter,
>
> On Wed, Mar 03, 2021 at 01:19:26AM +0300, Peter Mamonov wrote:
> > Hi, Sascha and Ahmad,
> >
> > On Mon, Mar 01, 2021 at 12:01:05PM +0100, Ahmad Fatoum wrote:
> > > From: Sascha Hauer <s.hauer@pengutronix.de>
> > >
> > > The header has been taken from glibc, the implementation itself is based
> > > on the newlib implementation.
> > >
> > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > > Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> > > ---
> > > arch/mips/Kconfig | 1 +
> > > arch/mips/include/asm/setjmp.h | 32 ++++++++++++++++++++++
> > > arch/mips/lib/Makefile | 1 +
> > > arch/mips/lib/setjmp.S | 50 ++++++++++++++++++++++++++++++++++
> > > 4 files changed, 84 insertions(+)
> > > create mode 100644 arch/mips/include/asm/setjmp.h
> > > create mode 100644 arch/mips/lib/setjmp.S
> > >
> > > ...
> > >
> > > diff --git a/arch/mips/lib/setjmp.S b/arch/mips/lib/setjmp.S
> > > new file mode 100644
> > > index 000000000000..b09a7c55293c
> > > --- /dev/null
> > > +++ b/arch/mips/lib/setjmp.S
> > > @@ -0,0 +1,50 @@
> > > +/* SPDX-License-Identifier: GPL-2.0-only */
> > > +
> > > +#include <asm/regdef.h>
> > > +#include <asm/asm.h>
> > > +#include <linux/linkage.h>
> > > +
> > > +/* int setjmp (jmp_buf); */
> > > +LEAF(setjmp)
> > > + sw ra, (0 * 4)(a0)
> > > + sw sp, (1 * 4)(a0)
> > > + sw s0, (2 * 4)(a0)
> > > + sw s1, (3 * 4)(a0)
> > > + sw s2, (4 * 4)(a0)
> > > + sw s3, (5 * 4)(a0)
> > > + sw s4, (6 * 4)(a0)
> > > + sw s5, (7 * 4)(a0)
> > > + sw s6, (8 * 4)(a0)
> > > + sw s7, (9 * 4)(a0)
> > > + sw fp, (10 * 4)(a0)
> > > + move v0, zero
> > > + j ra
> > > +END(setjmp)
> > > +
> > > +/* volatile void longjmp (jmp_buf, int); */
> > > +LEAF(longjmp)
> > > + lw ra, (0 * 4)(a0)
> > > + lw sp, (1 * 4)(a0)
> > > + lw s0, (2 * 4)(a0)
> > > + lw s1, (3 * 4)(a0)
> > > + lw s2, (4 * 4)(a0)
> > > + lw s3, (5 * 4)(a0)
> > > + lw s4, (6 * 4)(a0)
> > > + lw s5, (7 * 4)(a0)
> > > + lw s6, (8 * 4)(a0)
> > > + lw s7, (9 * 4)(a0)
> > > + lw fp, (10 * 4)(a0)
> > > + bne a1, zero, 1f
> > > + li a1, 1
> > > +1:
> > > + move v0, a1
> > > + j ra
> > > +END(longjmp)
> > > +
> > > +/* int initjmp(jmp_buf jmp, void __noreturn (*func)(void), void *stack_top); */
> > > +LEAF(initjmp)
> > > + sw a1, (0 * 4)(a0)
> > > + sw a2, (1 * 4)(a0)
> > > + move v0, zero
> > > + j ra
> > > +END(initjmp)
> >
> > I would suggest using `REG_S/REG_L r, (n * SZREG)(a0)` here for the sake of
> > MIPS64 targets. See arch/mips/include/asm/asm.h:272.
>
> I agree with you, but barebox doesn't support MIPS64 currently and I
> wasn't confident enough to add such things when I can't test them.
Well, what can possibly go wrong? =) Actually you've used this approach for RV:
http://lists.infradead.org/pipermail/barebox/2021-March/035173.html.
> Maybe we can add a
>
> #if SZREG != 4
> #error setjmp/longjmp currently only supports 32bit targets
> #endif
Definitely it's better than random fails after context switch in runtime.
Regards,
Peter
> Sascha
> > -- > Pengutronix e.K. |
|
> Steuerwalder Str. 21 | http://www.pengutronix.de/ |
> 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2 10/11] mips: Implement setjmp/longjmp/initjmp
2021-03-07 12:00 ` Peter Mamonov
@ 2021-03-10 8:17 ` Ahmad Fatoum
2021-03-14 12:40 ` Ahmad Fatoum
0 siblings, 1 reply; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-10 8:17 UTC (permalink / raw)
To: Peter Mamonov, Sascha Hauer; +Cc: barebox, Jules Maselbas, Stafford Horne
Hello Peter,
On 07.03.21 13:00, Peter Mamonov wrote:
> On Thu, Mar 04, 2021 at 09:38:11AM +0100, Sascha Hauer wrote:
>> Hi Peter,
>>
>> On Wed, Mar 03, 2021 at 01:19:26AM +0300, Peter Mamonov wrote:
>>> Hi, Sascha and Ahmad,
>>>
>>> On Mon, Mar 01, 2021 at 12:01:05PM +0100, Ahmad Fatoum wrote:
>>>> From: Sascha Hauer <s.hauer@pengutronix.de>
>>>>
>>>> The header has been taken from glibc, the implementation itself is based
>>>> on the newlib implementation.
>>>>
>>>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
>>>> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
>>>> ---
>>>> arch/mips/Kconfig | 1 +
>>>> arch/mips/include/asm/setjmp.h | 32 ++++++++++++++++++++++
>>>> arch/mips/lib/Makefile | 1 +
>>>> arch/mips/lib/setjmp.S | 50 ++++++++++++++++++++++++++++++++++
>>>> 4 files changed, 84 insertions(+)
>>>> create mode 100644 arch/mips/include/asm/setjmp.h
>>>> create mode 100644 arch/mips/lib/setjmp.S
>>>>
>>>> ...
>>>>
>>>> diff --git a/arch/mips/lib/setjmp.S b/arch/mips/lib/setjmp.S
>>>> new file mode 100644
>>>> index 000000000000..b09a7c55293c
>>>> --- /dev/null
>>>> +++ b/arch/mips/lib/setjmp.S
>>>> @@ -0,0 +1,50 @@
>>>> +/* SPDX-License-Identifier: GPL-2.0-only */
>>>> +
>>>> +#include <asm/regdef.h>
>>>> +#include <asm/asm.h>
>>>> +#include <linux/linkage.h>
>>>> +
>>>> +/* int setjmp (jmp_buf); */
>>>> +LEAF(setjmp)
>>>> + sw ra, (0 * 4)(a0)
>>>> + sw sp, (1 * 4)(a0)
>>>> + sw s0, (2 * 4)(a0)
>>>> + sw s1, (3 * 4)(a0)
>>>> + sw s2, (4 * 4)(a0)
>>>> + sw s3, (5 * 4)(a0)
>>>> + sw s4, (6 * 4)(a0)
>>>> + sw s5, (7 * 4)(a0)
>>>> + sw s6, (8 * 4)(a0)
>>>> + sw s7, (9 * 4)(a0)
>>>> + sw fp, (10 * 4)(a0)
>>>> + move v0, zero
>>>> + j ra
>>>> +END(setjmp)
>>>> +
>>>> +/* volatile void longjmp (jmp_buf, int); */
>>>> +LEAF(longjmp)
>>>> + lw ra, (0 * 4)(a0)
>>>> + lw sp, (1 * 4)(a0)
>>>> + lw s0, (2 * 4)(a0)
>>>> + lw s1, (3 * 4)(a0)
>>>> + lw s2, (4 * 4)(a0)
>>>> + lw s3, (5 * 4)(a0)
>>>> + lw s4, (6 * 4)(a0)
>>>> + lw s5, (7 * 4)(a0)
>>>> + lw s6, (8 * 4)(a0)
>>>> + lw s7, (9 * 4)(a0)
>>>> + lw fp, (10 * 4)(a0)
>>>> + bne a1, zero, 1f
>>>> + li a1, 1
>>>> +1:
>>>> + move v0, a1
>>>> + j ra
>>>> +END(longjmp)
>>>> +
>>>> +/* int initjmp(jmp_buf jmp, void __noreturn (*func)(void), void *stack_top); */
>>>> +LEAF(initjmp)
>>>> + sw a1, (0 * 4)(a0)
>>>> + sw a2, (1 * 4)(a0)
>>>> + move v0, zero
>>>> + j ra
>>>> +END(initjmp)
>>>
>>> I would suggest using `REG_S/REG_L r, (n * SZREG)(a0)` here for the sake of
>>> MIPS64 targets. See arch/mips/include/asm/asm.h:272.
>>
>> I agree with you, but barebox doesn't support MIPS64 currently and I
>> wasn't confident enough to add such things when I can't test them.
>
> Well, what can possibly go wrong? =) Actually you've used this approach for RV:
> http://lists.infradead.org/pipermail/barebox/2021-March/035173.html.
>
>> Maybe we can add a
>>
>> #if SZREG != 4
>> #error setjmp/longjmp currently only supports 32bit targets
>> #endif
>
> Definitely it's better than random fails after context switch in runtime.
I changed the select to happen only from the 32-bit symbols for RISC-V and MIPS.
>
> Regards,
> Peter
>
>> Sascha
>>> -- > Pengutronix e.K. |
> |
>> Steuerwalder Str. 21 | http://www.pengutronix.de/ |
>> 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
>> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2 10/11] mips: Implement setjmp/longjmp/initjmp
2021-03-10 8:17 ` Ahmad Fatoum
@ 2021-03-14 12:40 ` Ahmad Fatoum
0 siblings, 0 replies; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-14 12:40 UTC (permalink / raw)
To: Peter Mamonov, Sascha Hauer; +Cc: barebox, Jules Maselbas, Stafford Horne
Hello,
On 10.03.21 09:17, Ahmad Fatoum wrote:
> Hello Peter,
>
>>> I agree with you, but barebox doesn't support MIPS64 currently and I
>>> wasn't confident enough to add such things when I can't test them.
>>
>> Well, what can possibly go wrong? =) Actually you've used this approach for RV:
>> http://lists.infradead.org/pipermail/barebox/2021-March/035173.html.
>>
>>> Maybe we can add a
>>>
>>> #if SZREG != 4
>>> #error setjmp/longjmp currently only supports 32bit targets
>>> #endif
>>
>> Definitely it's better than random fails after context switch in runtime.
>
> I changed the select to happen only from the 32-bit symbols for RISC-V and MIPS.
Ah, I didn't understand at first that the assembly is safe for both 32-bit and 64-bit.
I tested it and it works on both. Will fix this with the RISC-V 64-bit series.
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 11/11] powerpc: Implement initjmp/setjmp/longjmp
2021-03-01 11:00 [PATCH v2 00/11] common: introduce bthreads, co-operative Ahmad Fatoum
` (9 preceding siblings ...)
2021-03-01 11:01 ` [PATCH v2 10/11] mips: Implement setjmp/longjmp/initjmp Ahmad Fatoum
@ 2021-03-01 11:01 ` Ahmad Fatoum
2021-03-03 12:15 ` [PATCH v2 00/11] common: introduce bthreads, co-operative Stafford Horne
11 siblings, 0 replies; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-01 11:01 UTC (permalink / raw)
To: barebox; +Cc: Jules Maselbas, Stafford Horne, Ahmad Fatoum, sha
From: Sascha Hauer <s.hauer@pengutronix.de>
Implementation has been taken from newlib as this is much simpler than
the glibc version.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/setjmp.h | 21 ++++++++
arch/powerpc/lib/Makefile | 2 +-
arch/powerpc/lib/setjmp.S | 86 +++++++++++++++++++++++++++++++
4 files changed, 109 insertions(+), 1 deletion(-)
create mode 100644 arch/powerpc/include/asm/setjmp.h
create mode 100644 arch/powerpc/lib/setjmp.S
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 90ec7b1702e9..376c1bf42b5e 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -6,6 +6,7 @@ config PPC
select HAS_CACHE
select GENERIC_FIND_NEXT_BIT
select OFTREE
+ select HAS_ARCH_SJLJ
default y
choice
diff --git a/arch/powerpc/include/asm/setjmp.h b/arch/powerpc/include/asm/setjmp.h
new file mode 100644
index 000000000000..c558415c99d9
--- /dev/null
+++ b/arch/powerpc/include/asm/setjmp.h
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
+ * (C) Copyright 2016 Alexander Graf <agraf@suse.de>
+ */
+
+#ifndef _SETJMP_H_
+#define _SETJMP_H_ 1
+
+#include <asm/types.h>
+
+typedef struct __jmp_buf_internal_tag {
+ long int __regs[24];
+} jmp_buf[1];
+
+int setjmp(jmp_buf jmp) __attribute__((returns_twice));
+void longjmp(jmp_buf jmp, int ret) __attribute__((noreturn));
+
+int initjmp(jmp_buf jmp, void __noreturn (*func)(void), void *stack_top);
+
+#endif /* _SETJMP_H_ */
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index ba2f078b6277..405351c19929 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -9,4 +9,4 @@ obj-$(CONFIG_CMD_BOOTM) += ppclinux.o
obj-$(CONFIG_MODULES) += module.o
obj-y += crtsavres.o
obj-y += reloc.o
-
+obj-y += setjmp.o
diff --git a/arch/powerpc/lib/setjmp.S b/arch/powerpc/lib/setjmp.S
new file mode 100644
index 000000000000..021a57eebc3c
--- /dev/null
+++ b/arch/powerpc/lib/setjmp.S
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/*
+ * This is a simple version of setjmp and longjmp for the PowerPC.
+ * Ian Lance Taylor, Cygnus Support, 9 Feb 1994.
+ */
+
+#include <linux/linkage.h>
+#include <asm/ppc_asm.tmpl>
+
+ENTRY(setjmp)
+ addi r3,r3,7 # align to 8 byte boundary
+ rlwinm r3,r3,0,0,28
+ stw r1,0(r3) # offset 0
+ stwu r2,4(r3) # offset 4
+ stwu r13,4(r3) # offset 8
+ stwu r14,4(r3) # offset 12
+ stwu r15,4(r3) # offset 16
+ stwu r16,4(r3) # offset 20
+ stwu r17,4(r3) # offset 24
+ stwu r18,4(r3) # offset 28
+ stwu r19,4(r3) # offset 32
+ stwu r20,4(r3) # offset 36
+ stwu r21,4(r3) # offset 40
+ stwu r22,4(r3) # offset 44
+ stwu r23,4(r3) # offset 48
+ stwu r24,4(r3) # offset 52
+ stwu r25,4(r3) # offset 56
+ stwu r26,4(r3) # offset 60
+ stwu r27,4(r3) # offset 64
+ stwu r28,4(r3) # offset 68
+ stwu r29,4(r3) # offset 72
+ stwu r30,4(r3) # offset 76
+ stwu r31,4(r3) # offset 80
+ mflr r4
+ stwu r4,4(r3) # offset 84
+ mfcr r4
+ stwu r4,4(r3) # offset 88
+
+ li r3,0
+ blr
+END(setjmp)
+
+ENTRY(longjmp)
+ addi r3,r3,7 # align to 8 byte boundary
+ rlwinm r3,r3,0,0,28
+ lwz r1,0(r3) # offset 0
+ lwzu r2,4(r3) # offset 4
+ lwzu r13,4(r3) # offset 8
+ lwzu r14,4(r3) # offset 12
+ lwzu r15,4(r3) # offset 16
+ lwzu r16,4(r3) # offset 20
+ lwzu r17,4(r3) # offset 24
+ lwzu r18,4(r3) # offset 28
+ lwzu r19,4(r3) # offset 32
+ lwzu r20,4(r3) # offset 36
+ lwzu r21,4(r3) # offset 40
+ lwzu r22,4(r3) # offset 44
+ lwzu r23,4(r3) # offset 48
+ lwzu r24,4(r3) # offset 52
+ lwzu r25,4(r3) # offset 56
+ lwzu r26,4(r3) # offset 60
+ lwzu r27,4(r3) # offset 64
+ lwzu r28,4(r3) # offset 68
+ lwzu r29,4(r3) # offset 72
+ lwzu r30,4(r3) # offset 76
+ lwzu r31,4(r3) # offset 80
+ lwzu r5,4(r3) # offset 84
+ mtlr r5
+ lwzu r5,4(r3) # offset 88
+ mtcrf 255,r5
+
+ mr. r3,r4
+ bclr+ 4,2
+ li r3,1
+ blr
+END(longjmp)
+
+ENTRY(initjmp)
+ addi r3,r3,7 # align to 8 byte boundary
+ rlwinm r3,r3,0,0,28
+ stw r5,0(r3) # offset 0
+ stwu r4,88(r3) # offset 88
+ li r3,0
+ blr
+END(initjmp)
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2 00/11] common: introduce bthreads, co-operative
2021-03-01 11:00 [PATCH v2 00/11] common: introduce bthreads, co-operative Ahmad Fatoum
` (10 preceding siblings ...)
2021-03-01 11:01 ` [PATCH v2 11/11] powerpc: Implement initjmp/setjmp/longjmp Ahmad Fatoum
@ 2021-03-03 12:15 ` Stafford Horne
2021-03-03 13:35 ` Stafford Horne
` (2 more replies)
11 siblings, 3 replies; 27+ messages in thread
From: Stafford Horne @ 2021-03-03 12:15 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox, sha, Jules Maselbas
On Mon, Mar 01, 2021 at 12:00:55PM +0100, Ahmad Fatoum wrote:
> Hello,
>
> This is v2 of barebox coroutine support:
> https://lists.infradead.org/pipermail/barebox/2021-February/035032.html
>
> As discussed with Sascha, if this is to be added, this should be added for
> all architectures and not be optional. If we have this as integral part,
> it means we can substitute coroutines for:
> - pollers: just wrap the code in a loop
> - async pollers: just call a delay function in the loop
> - workqueues: assert_command_context yields until in command context
>
> In addition, we will have much less work porting over threaded code from
> Linux. See the referenced series for an example of a USB mass storage
> gadget.
>
> To prepare for replacing them, the functionality is renamed to
> bthreads (as in barebox threads) and is made separate from pollers.
>
> How to add new architecture support:
>
> - Apply this series or check out https://github.com/a3f/barebox/tree/bthread
Now that I got a dev environment booting off master I have switched to your
bthread branch. I found there is already a commit to remove openrisc in next.
I will revert this in my branch.
Is there a timeframe you aim to have this all done?
Also, It seems networking it not working for me that is ok for the work here,
but it will be something I have to look into next for OpenRISC.
-Stafford
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2 00/11] common: introduce bthreads, co-operative
2021-03-03 12:15 ` [PATCH v2 00/11] common: introduce bthreads, co-operative Stafford Horne
@ 2021-03-03 13:35 ` Stafford Horne
2021-03-03 13:58 ` Ahmad Fatoum
2021-03-03 15:12 ` Sascha Hauer
2 siblings, 0 replies; 27+ messages in thread
From: Stafford Horne @ 2021-03-03 13:35 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox, sha, Jules Maselbas
On Wed, Mar 03, 2021 at 09:15:47PM +0900, Stafford Horne wrote:
> On Mon, Mar 01, 2021 at 12:00:55PM +0100, Ahmad Fatoum wrote:
> > Hello,
> >
> > This is v2 of barebox coroutine support:
> > https://lists.infradead.org/pipermail/barebox/2021-February/035032.html
> >
> > As discussed with Sascha, if this is to be added, this should be added for
> > all architectures and not be optional. If we have this as integral part,
> > it means we can substitute coroutines for:
> > - pollers: just wrap the code in a loop
> > - async pollers: just call a delay function in the loop
> > - workqueues: assert_command_context yields until in command context
> >
> > In addition, we will have much less work porting over threaded code from
> > Linux. See the referenced series for an example of a USB mass storage
> > gadget.
> >
> > To prepare for replacing them, the functionality is renamed to
> > bthreads (as in barebox threads) and is made separate from pollers.
> >
> > How to add new architecture support:
> >
> > - Apply this series or check out https://github.com/a3f/barebox/tree/bthread
>
> Now that I got a dev environment booting off master I have switched to your
> bthread branch. I found there is already a commit to remove openrisc in next.
>
> I will revert this in my branch.
>
> Is there a timeframe you aim to have this all done?
>
> Also, It seems networking it not working for me that is ok for the work here,
> but it will be something I have to look into next for OpenRISC.
The openrisc implementation is on this branch, I will send a patch in bit.
https://github.com/stffrdhrn/barebox/tree/openrisc-bthread
-Stafford
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2 00/11] common: introduce bthreads, co-operative
2021-03-03 12:15 ` [PATCH v2 00/11] common: introduce bthreads, co-operative Stafford Horne
2021-03-03 13:35 ` Stafford Horne
@ 2021-03-03 13:58 ` Ahmad Fatoum
2021-03-03 15:12 ` Sascha Hauer
2 siblings, 0 replies; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-03 13:58 UTC (permalink / raw)
To: Stafford Horne; +Cc: barebox, sha, Jules Maselbas
Hello Stafford,
On 03.03.21 13:15, Stafford Horne wrote:
> On Mon, Mar 01, 2021 at 12:00:55PM +0100, Ahmad Fatoum wrote:
>> Hello,
>>
>> This is v2 of barebox coroutine support:
>> https://lists.infradead.org/pipermail/barebox/2021-February/035032.html
>>
>> As discussed with Sascha, if this is to be added, this should be added for
>> all architectures and not be optional. If we have this as integral part,
>> it means we can substitute coroutines for:
>> - pollers: just wrap the code in a loop
>> - async pollers: just call a delay function in the loop
>> - workqueues: assert_command_context yields until in command context
>>
>> In addition, we will have much less work porting over threaded code from
>> Linux. See the referenced series for an example of a USB mass storage
>> gadget.
>>
>> To prepare for replacing them, the functionality is renamed to
>> bthreads (as in barebox threads) and is made separate from pollers.
>>
>> How to add new architecture support:
>>
>> - Apply this series or check out https://github.com/a3f/barebox/tree/bthread
>
> Now that I got a dev environment booting off master I have switched to your
> bthread branch. I found there is already a commit to remove openrisc in next.
>
> I will revert this in my branch.
Yes, please revert.
> Is there a timeframe you aim to have this all done?
I hoped it would be ready by middle of march, so it can go into next
before v2020.03.0, but no hurry. I can make it optional and withhold
adding code depending on bthreads until all architectures have support.
> Also, It seems networking it not working for me that is ok for the work here,
> but it will be something I have to look into next for OpenRISC.
Can't help here unfortunately. I haven't actually used this platform.
Cheers,
Ahmad
>
> -Stafford
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2 00/11] common: introduce bthreads, co-operative
2021-03-03 12:15 ` [PATCH v2 00/11] common: introduce bthreads, co-operative Stafford Horne
2021-03-03 13:35 ` Stafford Horne
2021-03-03 13:58 ` Ahmad Fatoum
@ 2021-03-03 15:12 ` Sascha Hauer
2 siblings, 0 replies; 27+ messages in thread
From: Sascha Hauer @ 2021-03-03 15:12 UTC (permalink / raw)
To: Stafford Horne; +Cc: Ahmad Fatoum, barebox, Jules Maselbas
On Wed, Mar 03, 2021 at 09:15:47PM +0900, Stafford Horne wrote:
> On Mon, Mar 01, 2021 at 12:00:55PM +0100, Ahmad Fatoum wrote:
> > Hello,
> >
> > This is v2 of barebox coroutine support:
> > https://lists.infradead.org/pipermail/barebox/2021-February/035032.html
> >
> > As discussed with Sascha, if this is to be added, this should be added for
> > all architectures and not be optional. If we have this as integral part,
> > it means we can substitute coroutines for:
> > - pollers: just wrap the code in a loop
> > - async pollers: just call a delay function in the loop
> > - workqueues: assert_command_context yields until in command context
> >
> > In addition, we will have much less work porting over threaded code from
> > Linux. See the referenced series for an example of a USB mass storage
> > gadget.
> >
> > To prepare for replacing them, the functionality is renamed to
> > bthreads (as in barebox threads) and is made separate from pollers.
> >
> > How to add new architecture support:
> >
> > - Apply this series or check out https://github.com/a3f/barebox/tree/bthread
>
> Now that I got a dev environment booting off master I have switched to your
> bthread branch. I found there is already a commit to remove openrisc in next.
>
> I will revert this in my branch.
In the meantime I reverted removing of openrisc. Thank you for looking
at it.
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 27+ messages in thread