[Sound-open-firmware] [PATCH] task: add priority driven task management

Liam Girdwood liam.r.girdwood at linux.intel.com
Tue Jun 6 21:35:41 CEST 2017


Provide a method for tasks to be performed on a priority basis using the
interrupts levels to preempt lower priority tasks.

The scheduler will use the to schedule work at different priorities.

Signed-off-by: Liam Girdwood <liam.r.girdwood at linux.intel.com>
---
 src/arch/xtensa/Makefile.am                       |   5 +-
 src/arch/xtensa/include/Makefile.am               |   3 +-
 src/arch/xtensa/include/arch/task.h               |  41 +++++++
 src/arch/xtensa/init.c                            |   2 +
 src/arch/xtensa/task.c                            | 140 ++++++++++++++++++++++
 src/platform/baytrail/include/platform/platform.h |   4 +
 6 files changed, 192 insertions(+), 3 deletions(-)
 create mode 100644 src/arch/xtensa/include/arch/task.h
 create mode 100644 src/arch/xtensa/task.c

diff --git a/src/arch/xtensa/Makefile.am b/src/arch/xtensa/Makefile.am
index b9b1cc6..6670ef2 100644
--- a/src/arch/xtensa/Makefile.am
+++ b/src/arch/xtensa/Makefile.am
@@ -32,7 +32,8 @@ reef_SOURCES = \
 	_vectors.S \
 	init.c \
 	wait.S \
-	timer.c
+	timer.c \
+	task.c
 
 reef_CFLAGS = \
 	$(ARCH_INCDIR) \
@@ -49,9 +50,9 @@ reef_LDADD = \
 	../../init/libinit.a \
 	../../platform/$(PLATFORM)/libplatform.a \
 	../../tasks/libtasks.a \
-	../../audio/libaudio.a \
 	../../lib/libcore.a \
 	../../ipc/libipc.a \
+	../../audio/libaudio.a \
 	../../drivers/libdrivers.a \
 	libreset.a \
 	xtos/libxtos.a \
diff --git a/src/arch/xtensa/include/Makefile.am b/src/arch/xtensa/include/Makefile.am
index 96481b6..f114582 100644
--- a/src/arch/xtensa/include/Makefile.am
+++ b/src/arch/xtensa/include/Makefile.am
@@ -8,4 +8,5 @@ noinst_HEADERS = \
 	arch/interrupt.h \
 	arch/reef.h \
 	arch/spinlock.h \
-	arch/timer.h
+	arch/timer.h \
+	arch/task.h
diff --git a/src/arch/xtensa/include/arch/task.h b/src/arch/xtensa/include/arch/task.h
new file mode 100644
index 0000000..1547751
--- /dev/null
+++ b/src/arch/xtensa/include/arch/task.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of the Intel Corporation nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Liam Girdwood <liam.r.girdwood at linux.intel.com>
+ *
+ */
+
+#ifndef __ARCH_TASK_H_
+#define __ARCH_TASK_H_
+
+struct task;
+
+void arch_run_task(struct task *task);
+
+int arch_init_tasks(void);
+
+#endif
diff --git a/src/arch/xtensa/init.c b/src/arch/xtensa/init.c
index f904738..1e52d99 100644
--- a/src/arch/xtensa/init.c
+++ b/src/arch/xtensa/init.c
@@ -34,6 +34,7 @@
 #include <reef/interrupt.h>
 #include <platform/interrupt.h>
 #include <reef/mailbox.h>
+#include <arch/task.h>
 #include <reef/debug.h>
 #include <reef/init.h>
 #include <stdint.h>
@@ -152,6 +153,7 @@ static void register_exceptions(void)
 int arch_init(struct reef *reef)
 {
 	register_exceptions();
+	arch_init_tasks();
 	return 0;
 }
 
diff --git a/src/arch/xtensa/task.c b/src/arch/xtensa/task.c
new file mode 100644
index 0000000..7e74c07
--- /dev/null
+++ b/src/arch/xtensa/task.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2017, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of the Intel Corporation nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Liam Girdwood <liam.r.girdwood at linux.intel.com>
+ *
+ */
+
+#include <reef/schedule.h>
+#include <reef/interrupt.h>
+#include <platform/platform.h>
+#include <reef/debug.h>
+#include <stdint.h>
+#include <errno.h>
+
+static struct task *_irq_low_task = NULL;
+static struct task *_irq_med_task = NULL;
+static struct task *_irq_high_task = NULL;
+
+static inline uint32_t task_get_irq(struct task *task)
+{
+	uint32_t irq;
+
+	switch (task->priority) {
+	case TASK_PRI_MED + 1 ... TASK_PRI_LOW:
+		irq = PLATFORM_IRQ_TASK_LOW;
+		break;
+	case TASK_PRI_HIGH ... TASK_PRI_MED - 1:
+		irq = PLATFORM_IRQ_TASK_HIGH;
+		break;
+	case TASK_PRI_MED:
+	default:
+		irq = PLATFORM_IRQ_TASK_MED;
+		break;
+	}
+
+	return irq;
+}
+
+static inline void task_set_data(struct task *task)
+{
+	switch (task->priority) {
+	case TASK_PRI_MED + 1 ... TASK_PRI_LOW:
+		_irq_low_task = task;
+		break;
+	case TASK_PRI_HIGH ... TASK_PRI_MED - 1:
+		_irq_high_task = task;
+		break;
+	case TASK_PRI_MED:
+	default:
+		_irq_med_task = task;
+		break;
+	}
+}
+
+static void _irq_low(void *arg)
+{
+	struct task *task = *(struct task **)arg;
+	uint32_t irq;
+
+	if (task->func)
+		task->func(task->data);
+
+	schedule_task_complete(task);
+	irq = task_get_irq(task);
+	interrupt_clear(irq);
+}
+
+static void _irq_med(void *arg)
+{
+	struct task *task = *(struct task **)arg;
+	uint32_t irq;
+
+	if (task->func)
+		task->func(task->data);
+
+	schedule_task_complete(task);
+	irq = task_get_irq(task);
+	interrupt_clear(irq);
+}
+
+static void _irq_high(void *arg)
+{
+	struct task *task = *(struct task **)arg;
+	uint32_t irq;
+
+	if (task->func)
+		task->func(task->data);
+
+	schedule_task_complete(task);
+	irq = task_get_irq(task);
+	interrupt_clear(irq);
+}
+
+/* architecture specific method of running task */
+void arch_run_task(struct task *task)
+{
+	uint32_t irq;
+
+	task_set_data(task);
+	irq = task_get_irq(task);
+	interrupt_set(irq);
+}
+
+int arch_init_tasks(void)
+{
+	interrupt_register(PLATFORM_IRQ_TASK_LOW, _irq_low, &_irq_low_task);
+	interrupt_enable(PLATFORM_IRQ_TASK_LOW);
+
+	interrupt_register(PLATFORM_IRQ_TASK_MED, _irq_med, &_irq_med_task);
+	interrupt_enable(PLATFORM_IRQ_TASK_MED);
+
+	interrupt_register(PLATFORM_IRQ_TASK_HIGH, _irq_high, &_irq_high_task);
+	interrupt_enable(PLATFORM_IRQ_TASK_HIGH);
+
+	return 0;
+}
diff --git a/src/platform/baytrail/include/platform/platform.h b/src/platform/baytrail/include/platform/platform.h
index cd1e1d9..3cc19cc 100644
--- a/src/platform/baytrail/include/platform/platform.h
+++ b/src/platform/baytrail/include/platform/platform.h
@@ -52,6 +52,10 @@ struct reef;
 /* pipeline IRQ */
 #define PLATFORM_PIPELINE_IRQ	IRQ_NUM_SOFTWARE4
 
+#define PLATFORM_IRQ_TASK_HIGH	IRQ_NUM_SOFTWARE4
+#define PLATFORM_IRQ_TASK_MED	IRQ_NUM_SOFTWARE3
+#define PLATFORM_IRQ_TASK_LOW	IRQ_NUM_SOFTWARE2
+
 /* DMA treats PHY addresses as host address unless within DSP region */
 #define PLATFORM_HOST_DMA_MASK	0xFF000000
 
-- 
2.11.0



More information about the Sound-open-firmware mailing list