summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2013-05-06 12:20:52 -0500
committerRonald G. Minnich <rminnich@gmail.com>2013-05-14 05:18:47 +0200
commit4409a5eef6d1d669caad1bfe3fbefee87ea7734e (patch)
treea586c21f4def3f0ac3e318e2925facd85f23fff1 /src/include
parent8c8af592ca20e6c2dc48bea2c3ae66aa92c9dca7 (diff)
downloadcoreboot-4409a5eef6d1d669caad1bfe3fbefee87ea7734e.tar.xz
coreboot: add thread cooperative multitasking
The cooperative multitasking support allows the boot state machine to be ran cooperatively with other threads of work. The main thread still continues to run the boot state machine (src/lib/hardwaremain.c). All callbacks from the state machine are still ran synchronously from within the main thread's context. Without any other code added the only change to the boot sequence when cooperative multitasking is enabled is the queueing of an idlle thread. The idle thread is responsible for ensuring progress is made by calling timer callbacks. The main thread can yield to any other threads in the system. That means that anyone that spins up a thread must ensure no shared resources are used from 2 or more execution contexts. The support is originally intentioned to allow for long work itesm with busy loops to occur in parallel during a boot. Note that the intention on when to yield a thread will be on calls to udelay(). Change-Id: Ia4d67a38665b12ce2643474843a93babd8a40c77 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/3206 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'src/include')
-rw-r--r--src/include/thread.h83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/include/thread.h b/src/include/thread.h
new file mode 100644
index 0000000000..148c448bb2
--- /dev/null
+++ b/src/include/thread.h
@@ -0,0 +1,83 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef THREAD_H_
+#define THREAD_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <bootstate.h>
+#include <timer.h>
+#include <arch/cpu.h>
+
+#if CONFIG_COOP_MULTITASKING && !defined(__SMM__) && !defined(__PRE_RAM__)
+
+struct thread {
+ int id;
+ uintptr_t stack_current;
+ uintptr_t stack_orig;
+ struct thread *next;
+ void (*entry)(void *);
+ void *entry_arg;
+ int can_yield;
+};
+
+void threads_initialize(void);
+/* Run func(arrg) on a new thread. Return 0 on successful start of thread, < 0
+ * when thread could not be started. Note that the thread will block the
+ * current state in the boot state machine until it is complete. */
+int thread_run(void (*func)(void *), void *arg);
+/* thread_run_until is the same as thread_run() except that it blocks state
+ * transitions from occuring in the (state, seq) pair of the boot state
+ * machine. */
+int thread_run_until(void (*func)(void *), void *arg,
+ boot_state_t state, boot_state_sequence_t seq);
+/* Return 0 on successful yield for the given amount of time, < 0 when thread
+ * did not yield. */
+int thread_yield_microseconds(unsigned microsecs);
+
+/* Allow and prevent thread cooperation on current running thread. By default
+ * all threads are marked to be cooperative. That means a thread can yeild
+ * to another thread at a pre-determined switch point. Current there is
+ * only a single place where switching may occur: a call to udelay(). */
+void thread_cooperate(void);
+void thread_prevent_coop(void);
+
+static inline void thread_init_cpu_info_non_bsp(struct cpu_info *ci)
+{
+ ci->thread = NULL;
+}
+
+/* Architecture specific thread functions. */
+void asmlinkage switch_to_thread(uintptr_t new_stack, uintptr_t *saved_stack);
+/* Set up the stack frame for a new thread so that a switch_to_thread() call
+ * will enter the thread_entry() function with arg as a parameter. The
+ * saved_stack field in the struct thread needs to be updated accordingly. */
+void arch_prepare_thread(struct thread *t,
+ void asmlinkage (*thread_entry)(void *), void *arg);
+#else
+static inline void threads_initialize(void) {}
+static inline int thread_run(void (*func)(void *), void *arg) { return -1; }
+static inline int thread_yield_microseconds(unsigned microsecs) { return -1; }
+static inline void thread_cooperate(void) {}
+static inline void thread_prevent_coop(void) {}
+struct cpu_info;
+static inline void thread_init_cpu_info_non_bsp(struct cpu_info *ci) { }
+#endif
+
+#endif /* THREAD_H_ */