[Cbe-oss-dev] [PATCH 21/23]MARS/task: asm sched func
Yuji Mano
yuji.mano at am.sony.com
Sat Mar 14 12:19:09 EST 2009
Rewrite part of task module in assembly language
This patch reimplement part of task module in assembly language to
guarantee particular stack layout.
Signed-off-by: Kazunori Asayama <asayama at sm.sony.co.jp>
Signed-off-by: Yuji Mano <yuji.mano at am.sony.com>
---
task/src/mpu/module/Makefile.am | 3
task/src/mpu/module/task_module.c | 89 ++++++--------------------
task/src/mpu/module/task_switch.S | 126 ++++++++++++++++++++++++++++++++++++++
3 files changed, 148 insertions(+), 70 deletions(-)
--- a/task/src/mpu/module/Makefile.am
+++ b/task/src/mpu/module/Makefile.am
@@ -101,7 +101,8 @@ noinst_PROGRAMS = mars_task_module
mars_task_module_SOURCES = \
$(srcdir)/../../../src/common/*.h \
task_module.c \
- task_module.h
+ task_module.h \
+ task_switch.S
mars_task_module_LDADD = -lmars_base
--- a/task/src/mpu/module/task_module.c
+++ b/task/src/mpu/module/task_module.c
@@ -49,13 +49,20 @@
#define MARS_TASK_REGISTER_SAVE_AREA_SIZE (16 * (127 - 80 + 1))
-/* stack pointer storage */
-void *__module_stack;
-void *__task_stack;
-
/* global task variables */
static struct mars_task_context *task;
+/* called by task_switch.S */
+void __module_main(void);
+void __task_save(void *task_heap);
+void __task_restore(int task_cached);
+
+/* defined in task_switch.S */
+extern void *__task_stack;
+extern void task_exit(void);
+extern void task_save(void *task_heap, int wait);
+extern void task_restore(int task_cached);
+
/* task entry */
typedef void (*mars_task_entry)(struct mars_task_args *args,
struct mars_task_module_syscalls *task_module_syscalls);
@@ -218,7 +225,7 @@ static void registers_restore(void *ptr)
: : [ptr] "r" (ptr));
}
-static void __attribute__((noinline)) context_save(void *task_heap)
+void __task_save(void *task_heap)
{
/* save registers state */
registers_save(__task_stack);
@@ -242,7 +249,7 @@ static void __attribute__((noinline)) co
task->context_save_area_high_size, 1);
}
-static void __attribute__((noinline)) context_restore(int task_cached)
+void __task_restore(int task_cached)
{
/* if task not cashed restore context MPU storage state */
if (!task_cached)
@@ -256,61 +263,9 @@ static void __attribute__((noinline)) co
registers_restore(__task_stack);
}
-static void __attribute__((noinline)) context_wait(void *task_heap)
-{
- register void *sp asm("$sp");
-
- /* save task stack pointer */
- __task_stack = sp;
-
- /* restore module stack pointer */
- sp = __module_stack;
-
- /* save task context */
- context_save(task_heap);
-
- /* put workload into waiting state */
- mars_module_workload_wait();
-}
-
-static void __attribute__((noinline)) context_resume(int task_cached)
-{
- register void *sp asm("$sp");
-
- /* restore task context */
- context_restore(task_cached);
-
- /* restore task stack pointer */
- sp = __task_stack;
-
- /* sync before executing loaded code */
- spu_sync();
-}
-
static void task_yield(void *task_heap)
{
- register void *sp asm("$sp");
-
- /* save task stack pointer and restore module stack pointer */
- __task_stack = sp;
- sp = __module_stack;
-
- /* save task context */
- context_save(task_heap);
-
- /* yield workload and put into ready state */
- mars_module_workload_yield();
-}
-
-static void task_exit(void)
-{
- /* restore module stack pointer */
- register void *sp asm("$sp");
-
- sp = __module_stack;
-
- /* put workload into finished state */
- mars_module_workload_finish();
+ task_save(task_heap, 0);
}
static int task_schedule(uint16_t workload_id, struct mars_task_args *args,
@@ -346,7 +301,7 @@ static int task_wait(uint16_t workload_i
if (ret != MARS_SUCCESS)
return ret;
- context_wait(task_heap);
+ task_save(task_heap, 1);
return mars_module_workload_wait_reset();
}
@@ -376,7 +331,7 @@ static int task_signal_send(uint16_t wor
static int task_signal_wait(void *task_heap)
{
- context_wait(task_heap);
+ task_save(task_heap, 1);
return mars_module_workload_signal_reset();
}
@@ -416,7 +371,7 @@ static struct mars_task_module_syscalls
mars_module_dma_wait
};
-static void context_start(void)
+static void task_run(void)
{
__vector unsigned char *bss_ptr, *bss_end;
@@ -441,14 +396,10 @@ static void context_start(void)
((mars_task_entry)task->entry)(&task->args, &task_module_syscalls);
}
-void mars_module_main(void)
+void __module_main(void)
{
- register void *sp asm("$sp");
int task_cached;
- /* save module stack pointer */
- __module_stack = sp;
-
/* get task context */
task = get_task();
@@ -463,9 +414,9 @@ void mars_module_main(void)
/* if stack pointer is uninitialized run fresh, otherwise resume */
if (!task->stack)
- context_start();
+ task_run();
else
- context_resume(task_cached);
+ task_restore(task_cached);
/* we should never reach here */
}
--- /dev/null
+++ b/task/src/mpu/module/task_switch.S
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2009 Sony Corporation of America
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this Library and associated documentation files (the
+ * "Library"), to deal in the Library without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Library, and to
+ * permit persons to whom the Library is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Library.
+ *
+ * If you modify the Library, you may copy and distribute your modified
+ * version of the Library in object code or as an executable provided
+ * that you also do one of the following:
+ *
+ * Accompany the modified version of the Library with the complete
+ * corresponding machine-readable source code for the modified version
+ * of the Library; or,
+ *
+ * Accompany the modified version of the Library with a written offer
+ * for a complete machine-readable copy of the corresponding source
+ * code of the modified version of the Library.
+ *
+ *
+ * THE LIBRARY IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * LIBRARY OR THE USE OR OTHER DEALINGS IN THE LIBRARY.
+ */
+
+.data
+
+/* void *__module_stack */
+.align 4
+.globl __module_stack
+__module_stack:
+.space 4
+
+/* void *__task_stack */
+.align 4
+.globl __task_stack
+__task_stack:
+.space 4
+
+
+.text
+
+/* void mars_module_main(void) */
+.global mars_module_main
+.type mars_module_main, @function
+mars_module_main:
+ stqd $LR, 16($SP) /* save link register */
+ stqd $SP, -32($SP) /* save back chain */
+ ai $SP, $SP, -32 /* push stack frame */
+
+ stqa $SP, __module_stack /* save module stack */
+ brsl $LR, __module_main /* call module main body */
+
+ ai $SP, $SP, 32 /* pop stack frame */
+ lqd $LR, 16($SP) /* restore link register */
+ bi $LR /* return */
+
+.size mars_module_main, .-mars_module_main
+
+
+/* void task_exit(void) */
+.global task_exit
+.type task_exit, @function
+task_exit:
+ stqd $LR, 16($SP) /* save link register */
+ stqd $SP, -32($SP) /* save back chain */
+ ai $SP, $SP, -32 /* push stack frame */
+
+ lqa $SP, __module_stack /* restore module stack */
+ br mars_module_workload_finish /* module finish (no return) */
+
+.size task_exit, .-task_exit
+
+
+/* void task_save(void *task_heap, int wait) */
+.global task_save
+.type task_save, @function
+task_save:
+ stqd $LR, 16($SP) /* save link register */
+ stqd $SP, -48($SP) /* save back chain */
+ ai $SP, $SP, -48 /* push stack frame */
+
+ stqd $4, 32($SP) /* save function param */
+
+ stqa $SP, __task_stack /* save task stack */
+ lqa $SP, __module_stack /* restore module stack */
+ brsl $LR, __task_save /* call task save body */
+
+ lqa $2, __task_stack /* load saved task stack ptr */
+ lqd $3, 32($2) /* load saved function param */
+
+ brz $3, mars_module_workload_yield /* module yield (no return) */
+ br mars_module_workload_wait /* module wait (no return) */
+
+.size task_save, .-task_save
+
+
+/* void task_restore(int task_cached) */
+.global task_restore
+.type task_restore, @function
+task_restore:
+ stqd $LR, 16($SP) /* save link register */
+ stqd $SP, -32($SP) /* save back chain */
+ ai $SP, $SP, -32 /* push stack frame */
+
+ brsl $LR, __task_restore /* call task restore body */
+ lqr $SP, __task_stack /* restore task stack */
+ sync /* sync before execution */
+
+ ai $SP, $SP, 48 /* pop task_save stack frame */
+ lqd $LR, 16($SP) /* restore link register */
+ bi $LR /* return from task_save call */
+
+.size task_restore, .-task_restore
More information about the cbe-oss-dev
mailing list