[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