mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v2 00/11] common: introduce bthreads, co-operative
@ 2021-03-01 11:00 Ahmad Fatoum
  2021-03-01 11:00 ` [PATCH v2 01/11] console: unconditionally run poller_call in ctrlc() Ahmad Fatoum
                   ` (11 more replies)
  0 siblings, 12 replies; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-01 11:00 UTC (permalink / raw)
  To: barebox; +Cc: Jules Maselbas, Stafford Horne, sha

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
  - Add implementations for setjmp, longjmp
    - Most easily extracted out of a libc, because they are C standard functions
    - Floating context backup can be omitted
  - Add implementation of initjmp
    - copy out the parts of setjmp that set return address and stack pointer
    - Check the architecture implemented in this series for examples
  - Add type definition and prototypes to <asm/setjmp.h>
  - select HAS_ARCH_SJLJ from arch config symbol
  - Test by running bthread -v


Current state of CONFIG_HAS_ARCH_SJLJ

    [x] arm 32-bit (Ahmad)
    [x] arm 64-bit (Sascha)
    [x] mips (Sascha)
    [x] powerpc (Sascha)
    [x] riscv (Sascha)
    [x] sandbox (Ahmad)
    [-] nios2 (Removed; Sascha)
    [?] x86 32-bit (Ahmad)
    [?] x86 64-bit (Ahmad)
    [?] openrisc (Stafford?)
    [?] kvx (Jules?)

Legend: [-] arch removed, [x] implemented, [?] TODO

@Sascha, could this already be merged? I won't add a new users till it
can be selected for all architectures.

Cheers,
Ahmad Fatoum (5):
  console: unconditionally run poller_call in ctrlc()
  common: introduce bthreads, co-operative barebox threads
  ARM: asm: setjmp: annotate setjmp/longjmp for GCC
  ARM: asm: setjmp: implement coroutine dependency initjmp()
  sandbox: asm: implement setjmp/longjmp/initjmp

Sascha Hauer (6):
  riscv: Add asm/asm.h
  riscv: Add asm/linkage.h
  riscv: Implement setjmp/longjmp/initjmp
  mips: Add linkage.h
  mips: Implement setjmp/longjmp/initjmp
  powerpc: Implement initjmp/setjmp/longjmp

 Documentation/devel/background-execution.rst |  43 +++-
 arch/arm/Kconfig                             |   1 +
 arch/arm/include/asm/setjmp.h                |   6 +-
 arch/arm/lib32/setjmp.S                      |   8 +
 arch/arm/lib64/setjmp.S                      |   9 +
 arch/mips/Kconfig                            |   1 +
 arch/mips/include/asm/linkage.h              |   9 +
 arch/mips/include/asm/setjmp.h               |  32 +++
 arch/mips/lib/Makefile                       |   1 +
 arch/mips/lib/setjmp.S                       |  50 +++++
 arch/powerpc/Kconfig                         |   1 +
 arch/powerpc/include/asm/setjmp.h            |  21 ++
 arch/powerpc/lib/Makefile                    |   2 +-
 arch/powerpc/lib/setjmp.S                    |  86 ++++++++
 arch/riscv/Kconfig                           |   1 +
 arch/riscv/include/asm/asm.h                 |  69 ++++++
 arch/riscv/include/asm/linkage.h             |  12 ++
 arch/riscv/include/asm/setjmp.h              |  27 +++
 arch/riscv/lib/Makefile                      |   2 +-
 arch/riscv/lib/longjmp.S                     |  28 +++
 arch/riscv/lib/setjmp.S                      |  35 +++
 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 ++++++++++++++++
 commands/Kconfig                             |   9 +
 commands/Makefile                            |   1 +
 common/Kconfig                               |  13 ++
 common/Makefile                              |   1 +
 common/bthread.c                             | 214 +++++++++++++++++++
 common/clock.c                               |   5 +-
 common/console.c                             |   6 +-
 include/bthread.h                            |  31 +++
 include/slice.h                              |  16 +-
 lib/readline.c                               |   5 +-
 36 files changed, 929 insertions(+), 24 deletions(-)
 create mode 100644 arch/mips/include/asm/linkage.h
 create mode 100644 arch/mips/include/asm/setjmp.h
 create mode 100644 arch/mips/lib/setjmp.S
 create mode 100644 arch/powerpc/include/asm/setjmp.h
 create mode 100644 arch/powerpc/lib/setjmp.S
 create mode 100644 arch/riscv/include/asm/asm.h
 create mode 100644 arch/riscv/include/asm/linkage.h
 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
 create mode 100644 arch/sandbox/include/asm/setjmp.h
 create mode 100644 arch/sandbox/os/setjmp.c
 create mode 100644 common/bthread.c
 create mode 100644 include/bthread.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 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 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

* [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

* [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 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

* [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

* 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

* 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

* [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 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

* 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] 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

* Re: [PATCH] fixup! common: introduce bthreads, co-operative barebox threads
  2021-03-04  8:49     ` Sascha Hauer
@ 2021-03-04  9:17       ` Ahmad Fatoum
  0 siblings, 0 replies; 27+ messages in thread
From: Ahmad Fatoum @ 2021-03-04  9:17 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox



On 04.03.21 09:49, Sascha Hauer wrote:
> Could you separate the option parsing from the functionality? The way it
> currently is is rather hard to extend.

Sure thing.

> 
> 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

end of thread, other threads:[~2021-03-14 12:43 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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-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
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
2021-03-01 11:00 ` [PATCH v2 03/11] ARM: asm: setjmp: annotate setjmp/longjmp for GCC Ahmad Fatoum
2021-03-01 11:00 ` [PATCH v2 04/11] ARM: asm: setjmp: implement coroutine dependency initjmp() Ahmad Fatoum
2021-03-01 11:01 ` [PATCH v2 05/11] sandbox: asm: implement setjmp/longjmp/initjmp Ahmad Fatoum
2021-03-01 11:01 ` [PATCH v2 06/11] riscv: Add asm/asm.h Ahmad Fatoum
2021-03-01 11:01 ` [PATCH v2 07/11] riscv: Add asm/linkage.h Ahmad Fatoum
2021-03-01 11:01 ` [PATCH v2 08/11] riscv: Implement setjmp/longjmp/initjmp Ahmad Fatoum
2021-03-01 11:01 ` [PATCH v2 09/11] mips: Add linkage.h Ahmad Fatoum
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
2021-03-07 12:00       ` Peter Mamonov
2021-03-10  8:17         ` Ahmad Fatoum
2021-03-14 12:40           ` Ahmad Fatoum
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
2021-03-03 13:35   ` Stafford Horne
2021-03-03 13:58   ` Ahmad Fatoum
2021-03-03 15:12   ` Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox