![](https://secure.gravatar.com/avatar/24e6a8158be3c9b52253d878d1487123.jpg?s=120&d=mm&r=g)
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@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@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@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