[Cbe-oss-dev] [PATCH 06/10 v3]MARS/core: Workload module split kernel cleanup

Yuji Mano yuji.mano at am.sony.com
Wed Nov 26 09:51:59 EST 2008


This cleans up the MARS core kernel implementation.
Most of the implementation will be moved into the task module/lib.
The kernel will only be responsible for workload scheduling and loading/running
the appropriate workload module.

Signed-off-by: Yuji Mano <yuji.mano at am.sony.com>

---
v2:
- updated the __stack symbol in Makefile so kernel uses 16K
v3:
- remove usage of obsolete TYPE workload bits
- remove kernel syscall to get workload_type

 core/src/common/kernel_internal_types.h |   17 +
 core/src/mpu/kernel/Makefile.am         |   15 -
 core/src/mpu/kernel/kernel.c            |  318 +++++++++++++++++++++++++
 core/src/mpu/kernel/kernel.h            |  126 ----------
 core/src/mpu/kernel/kernel_registers.c  |  152 ------------
 core/src/mpu/kernel/kernel_scheduler.c  |  253 --------------------
 core/src/mpu/kernel/kernel_syscalls.c   |  190 ---------------
 core/src/mpu/kernel/kernel_task.c       |  137 -----------
 core/src/mpu/kernel/kernel_workload.c   |  396 --------------------------------
 9 files changed, 334 insertions(+), 1270 deletions(-)

--- a/core/src/common/kernel_internal_types.h
+++ b/core/src/common/kernel_internal_types.h
@@ -40,10 +40,24 @@
 
 #include <stdint.h>
 
+#define MARS_KERNEL_STATUS_BUSY			0x0
+#define MARS_KERNEL_STATUS_IDLE			0x1
+#define MARS_KERNEL_STATUS_EXIT			0x2
 #define MARS_KERNEL_TICKS_FLAG_SYNC_BEGIN	0x1
 #define MARS_KERNEL_TICKS_FLAG_SYNC_END		0x2
 #define MARS_KERNEL_PARAMS_ALIGN		128
 
+/* mars kernel syscalls */
+struct mars_kernel_syscalls {
+	void				   (*module_exit)(uint8_t state);
+	uint64_t			   (*get_mars_context_ea)(void);
+	uint32_t			   (*get_kernel_id)(void);
+	uint16_t			   (*get_workload_id)(void);
+	struct mars_workload_context *     (*get_workload)(void);
+	struct mars_workload_queue_header *(*get_workload_queue_header)(void);
+	struct mars_workload_queue_block * (*get_workload_queue_block)(void);
+};
+
 /* mars kernel ticks */
 struct mars_kernel_ticks {
 	uint32_t flag;
@@ -58,4 +72,7 @@ struct mars_kernel_params {
 	struct mars_kernel_ticks kernel_ticks;
 } __attribute__((aligned(MARS_KERNEL_PARAMS_ALIGN)));
 
+/* mars module entry */
+void mars_module_entry(struct mars_kernel_syscalls *syscalls);
+
 #endif
--- a/core/src/mpu/kernel/Makefile.am
+++ b/core/src/mpu/kernel/Makefile.am
@@ -47,8 +47,7 @@ if DEBUG
 else
  extra_cppflags += "-DNDEBUG"
  # release kernel is 16K
- # ** todo **
- extra_ldflags += -Wl,--defsym=__stack=0x0fff0
+ extra_ldflags += -Wl,--defsym=__stack=0x03ff0
 endif
 
 if MARS_PLATFORM_CELL
@@ -89,16 +88,10 @@ AM_LDFLAGS = \
 
 noinst_PROGRAMS = mars_kernel
 
-mars_kernel_LDADD = $(builddir)/../lib/libmars.a
-
 mars_kernel_SOURCES = \
 	$(srcdir)/../../../src/common/*.h \
-	kernel.c \
-	kernel.h \
-	kernel_registers.c \
-	kernel_scheduler.c \
-	kernel_syscalls.c \
-	kernel_task.c \
-	kernel_workload.c
+	kernel.c
+
+mars_kernel_LDADD = $(builddir)/../lib/libmars_core.la
 
 CLEANFILES = *.map
--- a/core/src/mpu/kernel/kernel.c
+++ b/core/src/mpu/kernel/kernel.c
@@ -35,11 +35,318 @@
  * LIBRARY OR THE USE OR OTHER DEALINGS IN THE LIBRARY.
  */
 
-#include "kernel.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "mars/dma.h"
+#include "mars/error.h"
+#include "mars/module.h"
+#include "mars/mutex.h"
+
+#include "kernel_internal_types.h"
+#include "workload_internal_types.h"
+
+#define MARS_WORKLOAD_RESERVED_NONE	0
+#define MARS_WORKLOAD_RESERVED		1
+
+/* kernel */
+void *_kernel_stack;
+static struct mars_kernel_params kernel_params;
+
+/* workload queue */
+static struct mars_workload_queue_header queue_header;
+static struct mars_workload_queue_block queue_block;
+
+/* workload */
+static struct mars_workload_context workload;
+static uint8_t workload_state;
+static uint16_t workload_id;
+static uint64_t workload_ea;
+
+/* module entry */
+typedef void (*module_entry)(
+	const struct mars_kernel_syscalls *kernel_syscalls);
 
-struct mars_kernel_params kernel_params;
+static void module_exit(uint8_t state)
+{
+	workload_state = state;
+
+	/* restore kernel stack pointer and goto to exit label */
+	asm volatile (
+		"lqa	$sp, _kernel_stack;"
+		"br	_module_exit;"
+	);
+}
+
+static uint64_t get_mars_context_ea(void)
+{
+	return kernel_params.mars_context_ea;
+}
+
+static uint32_t get_kernel_id(void)
+{
+	return kernel_params.kernel_id;
+}
+
+static uint16_t get_workload_id(void)
+{
+	return workload_id;
+}
+
+static struct mars_workload_context *get_workload(void)
+{
+	return &workload;
+}
+
+static struct mars_workload_queue_header *get_workload_queue_header(void)
+{
+	return &queue_header;
+}
+
+static struct mars_workload_queue_block *get_workload_queue_block(void)
+{
+	return &queue_block;
+}
+
+static struct mars_kernel_syscalls kernel_syscalls =
+{
+	module_exit,
+	get_mars_context_ea,
+	get_kernel_id,
+	get_workload_id,
+	get_workload,
+	get_workload_queue_header,
+	get_workload_queue_block
+};
+
+static void get_block(int block, struct mars_workload_queue_block *dst)
+{
+	mars_dma_get_and_wait(dst,
+		queue_header.queue_ea +
+		offsetof(struct mars_workload_queue, block) +
+		sizeof(struct mars_workload_queue_block) * block,
+		sizeof(struct mars_workload_queue_block),
+		MARS_DMA_TAG);
+}
+
+static int search_block(int block)
+{
+	int i;
+	int index = -1;
+	uint16_t max_counter = 0;
+	uint16_t max_priority = 0;
+
+	/* search through workload queue for next workload to run
+	 * while incrementing wait counter for all waiting workloads
+	 * and pick the workload that has been waiting the longest
+	 */
+	for (i = 0; i < MARS_WORKLOAD_PER_BLOCK; i++) {
+		uint64_t *bits = &queue_block.bits[i];
+		uint8_t signal = MARS_BITS_GET(bits, SIGNAL);
+		uint8_t priority = MARS_BITS_GET(bits, PRIORITY);
+		uint16_t wait_id = MARS_BITS_GET(bits, WAIT_ID);
+		uint16_t counter = MARS_BITS_GET(bits, COUNTER);
+
+		switch (MARS_BITS_GET(bits, STATE)) {
+		case MARS_WORKLOAD_STATE_READY:
+			/* compare priority and counter with previous ones */
+			if (index < 0 || priority > max_priority ||
+			  (priority == max_priority && counter > max_counter)) {
+				index = i;
+				max_counter = counter;
+				max_priority = priority;
+			}
+			/* increment wait counter without overflowing */
+			if (counter < MARS_WORKLOAD_COUNTER_MAX)
+				MARS_BITS_SET(bits, COUNTER, counter + 1);
+			break;
+		case MARS_WORKLOAD_STATE_WAITING:
+			/* waiting for workload to finish so check status */
+			if (wait_id != MARS_WORKLOAD_ID_NONE) {
+				struct mars_workload_queue_block wait_block;
+				struct mars_workload_queue_block *p_wait_block;
+				uint8_t wait_state;
+
+				int bl = wait_id / MARS_WORKLOAD_PER_BLOCK;
+				int id = wait_id % MARS_WORKLOAD_PER_BLOCK;
+
+				/* check if workload id is in the same block */
+				if (block != bl) {
+					/* fetch the necessary block */
+					get_block(bl, &wait_block);
+					/* set pointer to check fetched block */
+					p_wait_block = &wait_block;
+				} else {
+					/* set pointer to check current block */
+					p_wait_block = &queue_block;
+				}
+
+				wait_state =
+					MARS_BITS_GET(&p_wait_block->bits[id],
+					STATE);
+
+				/* check if workload is finished and reset */
+				if (wait_state ==
+					MARS_WORKLOAD_STATE_FINISHED) {
+					MARS_BITS_SET(bits, WAIT_ID,
+						MARS_WORKLOAD_ID_NONE);
+					MARS_BITS_SET(bits, STATE,
+						MARS_WORKLOAD_STATE_READY);
+				}
+			/* waiting for signal so check signal bit and reset */
+			} else if (signal == MARS_WORKLOAD_SIGNAL_ON) {
+				MARS_BITS_SET(bits, SIGNAL,
+					MARS_WORKLOAD_SIGNAL_OFF);
+				MARS_BITS_SET(bits, STATE,
+					MARS_WORKLOAD_STATE_READY);
+				i--;
+			}
+			break;
+		default:
+			break;
+		}
+	}
+
+	/* returns -1 if no runnable workload found */
+	return index;
+}
+
+static int reserve_block(int block)
+{
+	int index;
+	uint64_t block_ea;
+
+	/* calculate block ea */
+	block_ea = queue_header.queue_ea +
+		offsetof(struct mars_workload_queue, block) +
+		sizeof(struct mars_workload_queue_block) * block;
+
+	mars_mutex_lock_get(block_ea, (struct mars_mutex *)&queue_block);
+
+	/* set the workload index */
+	index = search_block(block);
+	if (index >= 0) {
+		/* update the current state of the workload */
+		MARS_BITS_SET(&queue_block.bits[index], STATE,
+			MARS_WORKLOAD_STATE_RUNNING);
+
+		/* reset the counter for reserved workload */
+		MARS_BITS_SET(&queue_block.bits[index], COUNTER,
+			MARS_WORKLOAD_COUNTER_MIN);
+	}
+
+	mars_mutex_unlock_put(block_ea, (struct mars_mutex *)&queue_block);
+
+	return index;
+}
+
+static void release_block(int block, int index)
+{
+	uint64_t block_ea = queue_header.queue_ea +
+		offsetof(struct mars_workload_queue, block) +
+		sizeof(struct mars_workload_queue_block) * block;
+
+	mars_mutex_lock_get(block_ea, (struct mars_mutex *)&queue_block);
+
+	/* update current workload state in workload queue block */
+	MARS_BITS_SET(&queue_block.bits[index], STATE, workload_state);
+
+	mars_mutex_unlock_put(block_ea, (struct mars_mutex *)&queue_block);
+}
+
+static int __attribute__((noinline)) reserve_workload(void)
+{
+	int block;
+	int index = -1;
+
+	/* search workload queue blocks until runnable workload reserved */
+	for (block = 0; block < MARS_WORKLOAD_NUM_BLOCKS; block++) {
+		index = reserve_block(block);
+		if (index >= 0)
+			break;
+	}
+
+	/* no runnable workload found */
+	if (index < 0)
+		return MARS_WORKLOAD_RESERVED_NONE;
+
+	/* set global workload info based on workload block and index */
+	workload_id = MARS_WORKLOAD_PER_BLOCK * block + index;
+	workload_ea = queue_header.context_ea +
+		workload_id * sizeof(struct mars_workload_context);
+
+	/* get the workload context code from workload queue */
+	mars_dma_get_and_wait(&workload, workload_ea,
+		sizeof(struct mars_workload_context), MARS_DMA_TAG);
+
+	return MARS_WORKLOAD_RESERVED;
+}
+
+static void __attribute__((noinline)) release_workload(void)
+{
+	int block = workload_id / MARS_WORKLOAD_PER_BLOCK;
+	int index = workload_id % MARS_WORKLOAD_PER_BLOCK;
+
+	/* put the workload context into workload queue */
+	mars_dma_put_and_wait(&workload, workload_ea,
+		sizeof(struct mars_workload_context), MARS_DMA_TAG);
+
+	/* release block reservation */
+	release_block(block, index);
+}
+
+static int __attribute__((noinline)) scheduler(void)
+{
+	int status;
+
+	/* get the workload queue header */
+	mars_dma_get_and_wait(&queue_header,
+		kernel_params.workload_queue_ea +
+		offsetof(struct mars_workload_queue, header),
+		sizeof(struct mars_workload_queue_header),
+		MARS_DMA_TAG);
+
+	/* return exit status if exit flag is set from host */
+	if (queue_header.flag == MARS_WORKLOAD_QUEUE_FLAG_EXIT)
+		return MARS_KERNEL_STATUS_EXIT;
+
+	/* reserve next workload to run or return idle status if none found */
+	status = reserve_workload();
+
+	/* return idle status if no workload was reserved */
+	if (status == MARS_WORKLOAD_RESERVED_NONE)
+		return MARS_KERNEL_STATUS_IDLE;
+
+	/* load the exec code into mpu storage from host storage */
+	mars_dma_large_get_and_wait((void *)MARS_WORKLOAD_MODULE_ELF_VADDR,
+		workload.module.exec_ea, workload.module.exec_size,
+		MARS_DMA_TAG);
+
+	/* 0 the bss section */
+	memset((void *)MARS_WORKLOAD_MODULE_ELF_VADDR +
+		workload.module.exec_size, 0, workload.module.bss_size);
+
+	/* save kernel stack pointer */
+	asm volatile (
+		"stqa	$sp, _kernel_stack;"
+	);
+
+	/* call module entry function */
+	((module_entry)workload.module.entry)(&kernel_syscalls);
+
+	/* label so module can jump back here at exit */
+	asm volatile (
+		"_module_exit:"
+	);
+
+	/* release reservation of current workload */
+	release_workload();
+
+	return MARS_KERNEL_STATUS_BUSY;
+}
 
-static void kernel_get_params(uint64_t kernel_params_ea)
+static void get_params(uint64_t kernel_params_ea)
 {
 	int mask;
 
@@ -91,13 +398,14 @@ static void kernel_get_params(uint64_t k
 	spu_write_event_ack(MFC_LLR_LOST_EVENT);
 }
 
-int main(unsigned long long mpu_context_id, unsigned long long kernel_params_ea)
+int main(unsigned long long mpu_context_id,
+	unsigned long long kernel_params_ea)
 {
 	(void)mpu_context_id;
 
 	int exit_flag = 0;
 
-	kernel_get_params(kernel_params_ea);
+	get_params(kernel_params_ea);
 
 	while (!exit_flag) {
 		int status = scheduler();
--- a/core/src/mpu/kernel/kernel.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright 2008 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.
- */
-
-#ifndef MARS_KERNEL_H
-#define MARS_KERNEL_H
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <stddef.h>
-
-#include "mars/mutex.h"
-#include "mars/error.h"
-#include "mars/task_types.h"
-
-#include "kernel_internal_types.h"
-#include "mutex_internal_types.h"
-#include "workload_internal_types.h"
-#include "task_internal_types.h"
-#include "syscalls.h"
-#include "dma.h"
-
-#define MARS_KERNEL_STATUS_BUSY		0x0
-#define MARS_KERNEL_STATUS_IDLE		0x1
-#define MARS_KERNEL_STATUS_EXIT		0x2
-
-typedef void (*mars_entry)(void *workload_args, void *kernel_syscalls);
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-void mars_reentry(void);
-
-/* kernel scheduler function */
-int scheduler(void);
-
-/* kernel syscall functions */
-uint32_t syscall_get_ticks(void);
-uint64_t syscall_get_mars_context_ea(void);
-uint32_t syscall_get_kernel_id(void);
-uint16_t syscall_get_workload_id(void);
-uint64_t syscall_get_workload_ea(void);
-struct mars_workload_context *syscall_get_workload(void);
-struct mars_workload_context *syscall_get_workload_by_id(uint16_t workload_id);
-
-void syscall_init(void);
-void syscall_exit(void);
-void syscall_yield(void);
-void syscall_resume(void);
-int syscall_schedule(uint16_t workload_id, void *args, uint8_t priority);
-int syscall_wait(uint16_t workload_id);
-int syscall_try_wait(uint16_t workload_id);
-int syscall_signal_send(uint16_t workload_id);
-void syscall_signal_wait(void);
-int syscall_signal_try_wait(void);
-
-/* register saving / restoring functions */
-void registers_save(void);
-void registers_restore(void);
-
-/* workload specific functions */
-uint16_t workload_get_id(void);
-uint64_t workload_get_ea(void);
-struct mars_workload_context *workload_get(void);
-struct mars_workload_context *workload_get_by_id(uint16_t workload_id);
-
-void workload_exec(void);
-void workload_exit(void);
-void workload_yield(void);
-void workload_resume(void);
-int workload_schedule(uint16_t workload_id, void *args, uint8_t priority);
-int workload_wait(uint16_t workload_id);
-int workload_try_wait(uint16_t workload_id);
-int workload_signal_send(uint16_t workload_id);
-void workload_signal_wait(void);
-int workload_signal_try_wait(void);
-
-/* task specific functions */
-void task_exec(struct mars_task_context *task);
-void task_exit(struct mars_task_context *task);
-void task_yield(struct mars_task_context *task);
-void task_resume(struct mars_task_context *task);
-void task_schedule(struct mars_task_context *task, struct mars_task_args *args);
-
-extern struct mars_kernel_params kernel_params;
-extern struct mars_kernel_syscalls kernel_syscalls;
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
--- a/core/src/mpu/kernel/kernel_registers.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright 2008 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.
- */
-
-#include "kernel.h"
-
-void registers_save(void)
-{
-	/* push non-volatile registers on to the workload stack */
-	asm volatile (
-		"lqa	$75, workload_stack;"
-
-		"stqd	$80, -16($75);"
-		"stqd	$81, -32($75);"
-		"stqd	$82, -48($75);"
-		"stqd	$83, -64($75);"
-		"stqd	$84, -80($75);"
-		"stqd	$85, -96($75);"
-		"stqd	$86, -112($75);"
-		"stqd	$87, -128($75);"
-		"stqd	$88, -144($75);"
-		"stqd	$89, -160($75);"
-		"stqd	$90, -176($75);"
-		"stqd	$91, -192($75);"
-		"stqd	$92, -208($75);"
-		"stqd	$93, -224($75);"
-		"stqd	$94, -240($75);"
-		"stqd	$95, -256($75);"
-		"stqd	$96, -272($75);"
-		"stqd	$97, -288($75);"
-		"stqd	$98, -304($75);"
-		"stqd	$99, -320($75);"
-		"stqd	$100, -336($75);"
-		"stqd	$101, -352($75);"
-		"stqd	$102, -368($75);"
-		"stqd	$103, -384($75);"
-		"stqd	$104, -400($75);"
-		"stqd	$105, -416($75);"
-		"stqd	$106, -432($75);"
-		"stqd	$107, -448($75);"
-		"stqd	$108, -464($75);"
-		"stqd	$109, -480($75);"
-		"stqd	$110, -496($75);"
-		"stqd	$111, -512($75);"
-		"stqd	$112, -528($75);"
-		"stqd	$113, -544($75);"
-		"stqd	$114, -560($75);"
-		"stqd	$115, -576($75);"
-		"stqd	$116, -592($75);"
-		"stqd	$117, -608($75);"
-		"stqd	$118, -624($75);"
-		"stqd	$119, -640($75);"
-		"stqd	$120, -656($75);"
-		"stqd	$121, -672($75);"
-		"stqd	$122, -688($75);"
-		"stqd	$123, -704($75);"
-		"stqd	$124, -720($75);"
-		"stqd	$125, -736($75);"
-		"stqd	$126, -752($75);"
-		"stqd	$127, -768($75);"
-	);
-}
-
-void registers_restore(void)
-{
-	/* pop non-volatile registers from saved workload stack */
-	asm volatile (
-		"lqa	$75, workload_stack;"
-
-		"lqd	$80, -16($75);"
-		"lqd	$81, -32($75);"
-		"lqd	$82, -48($75);"
-		"lqd	$83, -64($75);"
-		"lqd	$84, -80($75);"
-		"lqd	$85, -96($75);"
-		"lqd	$86, -112($75);"
-		"lqd	$87, -128($75);"
-		"lqd	$88, -144($75);"
-		"lqd	$89, -160($75);"
-		"lqd	$90, -176($75);"
-		"lqd	$91, -192($75);"
-		"lqd	$92, -208($75);"
-		"lqd	$93, -224($75);"
-		"lqd	$94, -240($75);"
-		"lqd	$95, -256($75);"
-		"lqd	$96, -272($75);"
-		"lqd	$97, -288($75);"
-		"lqd	$98, -304($75);"
-		"lqd	$99, -320($75);"
-		"lqd	$100, -336($75);"
-		"lqd	$101, -352($75);"
-		"lqd	$102, -368($75);"
-		"lqd	$103, -384($75);"
-		"lqd	$104, -400($75);"
-		"lqd	$105, -416($75);"
-		"lqd	$106, -432($75);"
-		"lqd	$107, -448($75);"
-		"lqd	$108, -464($75);"
-		"lqd	$109, -480($75);"
-		"lqd	$110, -496($75);"
-		"lqd	$111, -512($75);"
-		"lqd	$112, -528($75);"
-		"lqd	$113, -544($75);"
-		"lqd	$114, -560($75);"
-		"lqd	$115, -576($75);"
-		"lqd	$116, -592($75);"
-		"lqd	$117, -608($75);"
-		"lqd	$118, -624($75);"
-		"lqd	$119, -640($75);"
-		"lqd	$120, -656($75);"
-		"lqd	$121, -672($75);"
-		"lqd	$122, -688($75);"
-		"lqd	$123, -704($75);"
-		"lqd	$124, -720($75);"
-		"lqd	$125, -736($75);"
-		"lqd	$126, -752($75);"
-		"lqd	$127, -768($75);"
-	);
-}
--- a/core/src/mpu/kernel/kernel_scheduler.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright 2008 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.
- */
-
-#include "kernel.h"
-
-#define MARS_WORKLOAD_RESERVED_NONE	0
-#define MARS_WORKLOAD_RESERVED		1
-
-struct mars_workload_queue_header queue_header;
-struct mars_workload_queue_block queue_block;
-struct mars_workload_context workload;
-uint8_t workload_type;
-uint8_t workload_state;
-uint16_t workload_index;
-uint64_t workload_ea;
-
-static inline void get_block(int block, struct mars_workload_queue_block *dst)
-{
-	mars_dma_get_and_wait(dst,
-		queue_header.queue_ea +
-		offsetof(struct mars_workload_queue, block) +
-		sizeof(struct mars_workload_queue_block) * block,
-		sizeof(struct mars_workload_queue_block),
-		MARS_DMA_TAG);
-}
-
-static int search_block(int block)
-{
-	int i;
-	int index = -1;
-	uint16_t max_counter = 0;
-	uint16_t max_priority = 0;
-
-	/* search through workload queue for next workload to run
-	 * while incrementing wait counter for all waiting workloads
-	 * and pick the workload that has been waiting the longest
-	 */
-	for (i = 0; i < MARS_WORKLOAD_PER_BLOCK; i++) {
-		uint64_t *bits = &queue_block.bits[i];
-		uint8_t signal = MARS_BITS_GET(bits, SIGNAL);
-		uint8_t priority = MARS_BITS_GET(bits, PRIORITY);
-		uint16_t wait_id = MARS_BITS_GET(bits, WAIT_ID);
-		uint16_t counter = MARS_BITS_GET(bits, COUNTER);
-
-		switch (MARS_BITS_GET(bits, STATE)) {
-		case MARS_WORKLOAD_STATE_READY:
-			/* compare priority and counter with previous ones */
-			if (index < 0 || priority > max_priority ||
-			  (priority == max_priority && counter > max_counter)) {
-				index = i;
-				max_counter = counter;
-				max_priority = priority;
-			}
-			/* increment wait counter without overflowing */
-			if (counter < MARS_WORKLOAD_COUNTER_MAX)
-				MARS_BITS_SET(bits, COUNTER, counter + 1);
-			break;
-		case MARS_WORKLOAD_STATE_WAITING:
-			/* waiting for workload to finish so check status */
-			if (wait_id != MARS_WORKLOAD_ID_NONE) {
-				struct mars_workload_queue_block wait_block;
-				struct mars_workload_queue_block *p_wait_block;
-				uint8_t wait_state;
-
-				int bl = wait_id / MARS_WORKLOAD_PER_BLOCK;
-				int id = wait_id % MARS_WORKLOAD_PER_BLOCK;
-
-				/* check if workload id is in the same block */
-				if (block != bl) {
-					/* fetch the necessary block */
-					get_block(bl, &wait_block);
-					/* set pointer to check fetched block */
-					p_wait_block = &wait_block;
-				} else {
-					/* set pointer to check current block */
-					p_wait_block = &queue_block;
-				}
-
-				wait_state =
-					MARS_BITS_GET(&p_wait_block->bits[id],
-					STATE);
-
-				/* check if workload is finished and reset */
-				if (wait_state ==
-					MARS_WORKLOAD_STATE_FINISHED) {
-					MARS_BITS_SET(bits, WAIT_ID,
-						MARS_WORKLOAD_ID_NONE);
-					MARS_BITS_SET(bits, STATE,
-						MARS_WORKLOAD_STATE_READY);
-				}
-			/* waiting for signal so check signal bit and reset */
-			} else if (signal == MARS_WORKLOAD_SIGNAL_ON) {
-				MARS_BITS_SET(bits, SIGNAL,
-					MARS_WORKLOAD_SIGNAL_OFF);
-				MARS_BITS_SET(bits, STATE,
-					MARS_WORKLOAD_STATE_READY);
-				i--;
-			}
-			break;
-		default:
-			break;
-		}
-	}
-
-	/* returns -1 if no runnable workload found */
-	return index;
-}
-
-static int reserve_block(int block)
-{
-	int index;
-	uint64_t block_ea = queue_header.queue_ea +
-		offsetof(struct mars_workload_queue, block) +
-		sizeof(struct mars_workload_queue_block) * block;
-
-	mars_mutex_lock_get(block_ea, (struct mars_mutex *)&queue_block);
-
-	/* set the workload index */
-	index = search_block(block);
-	if (index >= 0) {
-		/* update the current state of the workload */
-		MARS_BITS_SET(&queue_block.bits[index], STATE,
-			MARS_WORKLOAD_STATE_RUNNING);
-
-		/* reset the counter for reserved workload */
-		MARS_BITS_SET(&queue_block.bits[index], COUNTER,
-			MARS_WORKLOAD_COUNTER_MIN);
-	}
-
-	mars_mutex_unlock_put(block_ea, (struct mars_mutex *)&queue_block);
-
-	return index;
-}
-
-static void release_block(int block, int index)
-{
-	uint64_t block_ea = queue_header.queue_ea +
-		offsetof(struct mars_workload_queue, block) +
-		sizeof(struct mars_workload_queue_block) * block;
-
-	mars_mutex_lock_get(block_ea, (struct mars_mutex *)&queue_block);
-
-	/* update current workload state in workload queue block */
-	MARS_BITS_SET(&queue_block.bits[index], STATE, workload_state);
-
-	mars_mutex_unlock_put(block_ea, (struct mars_mutex *)&queue_block);
-}
-
-static int __attribute__((noinline)) reserve_workload(void)
-{
-	int block;
-	int index = -1;
-
-	/* search workload queue blocks until runnable workload reserved */
-	for (block = 0; block < MARS_WORKLOAD_NUM_BLOCKS; block++) {
-		index = reserve_block(block);
-		if (index >= 0)
-			break;
-	}
-
-	/* no runnable workload found */
-	if (index < 0)
-		return MARS_WORKLOAD_RESERVED_NONE;
-
-	/* set global workload info based on workload block and index */
-	workload_index = MARS_WORKLOAD_PER_BLOCK * block + index;
-	workload_type = MARS_BITS_GET(&queue_block.bits[index], TYPE);
-	workload_ea = queue_header.context_ea +
-		workload_index * sizeof(struct mars_workload_context);
-
-	/* dma the workload context code into LS from main memory */
-	mars_dma_get_and_wait(&workload, workload_ea,
-		sizeof(struct mars_workload_context), MARS_DMA_TAG);
-
-	return MARS_WORKLOAD_RESERVED;
-}
-
-static void __attribute__((noinline)) release_workload(void)
-{
-	int block = workload_index / MARS_WORKLOAD_PER_BLOCK;
-	int index = workload_index % MARS_WORKLOAD_PER_BLOCK;
-
-	mars_dma_put_and_wait(&workload, workload_ea,
-		sizeof(struct mars_workload_context), MARS_DMA_TAG);
-
-	/* release block reservation */
-	release_block(block, index);
-}
-
-int scheduler(void)
-{
-	int status;
-
-	/* dma in queue header */
-	mars_dma_get_and_wait(&queue_header,
-		kernel_params.workload_queue_ea +
-		offsetof(struct mars_workload_queue, header),
-		sizeof(struct mars_workload_queue_header),
-		MARS_DMA_TAG);
-
-	/* return exit status if exit flag is set from host */
-	if (queue_header.flag == MARS_WORKLOAD_QUEUE_FLAG_EXIT)
-		return MARS_KERNEL_STATUS_EXIT;
-
-	/* reserve next workload to run or return idle status if none found */
-	status = reserve_workload();
-
-	/* return idle status if no workload was reserved */
-	if (status == MARS_WORKLOAD_RESERVED_NONE)
-		return MARS_KERNEL_STATUS_IDLE;
-
-	/* execute the reserved workload */
-	workload_exec();
-
-	/* release reservation of current workload */
-	release_workload();
-
-	return MARS_KERNEL_STATUS_BUSY;
-}
--- a/core/src/mpu/kernel/kernel_syscalls.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright 2008 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.
- */
-
-#include "kernel.h"
-
-void *kernel_stack;
-void *workload_stack;
-
-struct mars_kernel_syscalls kernel_syscalls =
-{
-	syscall_get_ticks,
-	syscall_get_mars_context_ea,
-	syscall_get_kernel_id,
-	syscall_get_workload_id,
-	syscall_get_workload_ea,
-	syscall_get_workload,
-	syscall_get_workload_by_id,
-	syscall_init,
-	syscall_exit,
-	syscall_yield,
-	syscall_schedule,
-	syscall_wait,
-	syscall_try_wait,
-	syscall_signal_send,
-	syscall_signal_wait,
-	syscall_signal_try_wait
-};
-
-void mars_reentry(void)
-{
-	syscall_resume();
-}
-
-uint32_t syscall_get_ticks(void)
-{
-	return kernel_params.kernel_ticks.offset - spu_read_decrementer();
-}
-
-uint64_t syscall_get_mars_context_ea(void)
-{
-	return kernel_params.mars_context_ea;
-}
-
-uint32_t syscall_get_kernel_id(void)
-{
-	return kernel_params.kernel_id;
-}
-
-uint16_t syscall_get_workload_id(void)
-{
-	return workload_get_id();
-}
-
-uint64_t syscall_get_workload_ea(void)
-{
-	return workload_get_ea();
-}
-
-struct mars_workload_context *syscall_get_workload(void)
-{
-	return workload_get();
-}
-
-struct mars_workload_context *syscall_get_workload_by_id(uint16_t workload_id)
-{
-	return workload_get_by_id(workload_id);
-}
-
-void syscall_init(void)
-{
-	/* save the kernel stack
-	**
-	** We need to offset the stack pointer we want to save so that we
-	** return back to the caller of mars_entry and not the caller of
-	** the syscall mars_init and when mars_exit is called and pops the
-	** stack. But we don't want to modify the stack pointer directly
-	** just yet so we can return back to the current caller (mars_entry)
-	** so use a volatile register to do the offset.
-	** NO FUNCTION CALLS OR STACK PUSHES ALLOWED IN HERE.
-	*/
-	asm volatile (
-		"ai	$75, $sp, 32;"
-		"stqa	$75, kernel_stack;"
-	);
-}
-
-void syscall_exit(void)
-{
-	/* restore kernel stack */
-	asm volatile (
-		"lqa	$sp, kernel_stack;"
-	);
-
-	/* exit current workload */
-	workload_exit();
-}
-
-void syscall_yield(void)
-{
-	/* save workload stack and restore kernel stack */
-	asm volatile (
-		"stqa	$sp, workload_stack;"
-		"lqa	$sp, kernel_stack;"
-	);
-
-	/* yield current workload */
-	workload_yield();
-}
-
-void syscall_resume(void)
-{
-	/* resume current workload */
-	workload_resume();
-
-	/* save kernel stack and restore workload stack */
-	asm volatile (
-		"stqa	$sp, kernel_stack;"
-		"lqa	$sp, workload_stack;"
-	);
-}
-
-int syscall_schedule(uint16_t workload_id, void *args, uint8_t priority)
-{
-	return workload_schedule(workload_id, args, priority);
-}
-
-int syscall_wait(uint16_t workload_id)
-{
-	return workload_wait(workload_id);
-}
-
-int syscall_try_wait(uint16_t workload_id)
-{
-	return workload_try_wait(workload_id);
-}
-
-int syscall_signal_send(uint16_t workload_id)
-{
-	return workload_signal_send(workload_id);
-}
-
-void syscall_signal_wait(void)
-{
-	/* save workload stack and restore kernel stack */
-	asm volatile (
-		"stqa	$sp, workload_stack;"
-		"lqa	$sp, kernel_stack;"
-	);
-
-	workload_signal_wait();
-}
-
-int syscall_signal_try_wait(void)
-{
-	return workload_signal_try_wait();
-}
--- a/core/src/mpu/kernel/kernel_task.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2008 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.
- */
-
-#include <string.h>
-
-#include "kernel.h"
-
-extern void *workload_stack;
-
-void task_exec(struct mars_task_context *task)
-{
-	if (!task->stack) {
-		/* dma the exec code into mpu storage from host storage */
-		mars_dma_large_get_and_wait((void *)task->vaddr,
-			task->exec_ea, task->exec_size, MARS_DMA_TAG);
-
-		/* 0 the bss section */
-		memset((void *)task->vaddr + task->exec_size, 0,
-			task->bss_size);
-
-		/* call entry function */
-		((mars_entry)task->entry)(&task->args, &kernel_syscalls);
-	} else {
-		mars_reentry();
-	}
-}
-
-void task_exit(struct mars_task_context *task)
-{
-	(void)task;
-}
-
-void task_yield(struct mars_task_context *task)
-{
-	struct mars_task_context_save_unit
-		list[MARS_TASK_CONTEXT_SAVE_UNIT_MAX];
-	int i, offset = 0;
-
-	/* save workload stack pointer */
-	task->stack = (uint32_t)workload_stack;
-
-	/* dma get context save unit list */
-	mars_dma_get_and_wait(list, task->context_save_unit_ea,
-		MARS_TASK_CONTEXT_SAVE_UNIT_SIZE *
-		MARS_TASK_CONTEXT_SAVE_UNIT_MAX, MARS_DMA_TAG);
-
-	/* loop through save unit list */
-	for (i = 0; i < MARS_TASK_CONTEXT_SAVE_UNIT_MAX; i++) {
-		/* list terminator so exit loop */
-		if (!list[i].size)
-			break;
-
-		/* request dma put of the context save unit specified */
-		mars_dma_large_put((void *)(task->vaddr + list[i].addr),
-			task->context_save_area_ea + offset,
-			list[i].size, MARS_DMA_TAG);
-
-		offset += list[i].size;
-	}
-
-	/* wait for all dmas to complete */
-	mars_dma_wait(MARS_DMA_TAG);
-}
-
-void task_resume(struct mars_task_context *task)
-{
-	struct mars_task_context_save_unit
-		list[MARS_TASK_CONTEXT_SAVE_UNIT_MAX];
-	int i, offset = 0;
-
-	/* restore workload stack pointer */
-	workload_stack = (void *)task->stack;
-
-	/* dma save get context save unit list */
-	mars_dma_get_and_wait(list, task->context_save_unit_ea,
-		MARS_TASK_CONTEXT_SAVE_UNIT_SIZE *
-		MARS_TASK_CONTEXT_SAVE_UNIT_MAX, MARS_DMA_TAG);
-
-	/* loop through save unit list */
-	for (i = 0; i < MARS_TASK_CONTEXT_SAVE_UNIT_MAX; i++) {
-		/* list terminator so exit loop */
-		if (!list[i].size)
-			break;
-
-		/* request dma get of the context save unit specified */
-		mars_dma_large_get((void *)(task->vaddr + list[i].addr),
-			task->context_save_area_ea + offset,
-			list[i].size, MARS_DMA_TAG);
-
-		offset += list[i].size;
-	}
-
-	/* wait for all dmas to complete */
-	mars_dma_wait(MARS_DMA_TAG);
-}
-
-void task_schedule(struct mars_task_context *task, struct mars_task_args *args)
-{
-	/* initialize task specific context variables */
-	task->stack = 0;
-	if (args)
-		memcpy(&task->args, args, sizeof(struct mars_task_args));
-}
--- a/core/src/mpu/kernel/kernel_workload.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright 2008 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.
- */
-
-#include "kernel.h"
-
-extern struct mars_workload_queue_header queue_header;
-extern struct mars_workload_queue_block queue_block;
-extern struct mars_workload_context workload;
-extern uint8_t workload_type;
-extern uint8_t workload_state;
-extern uint16_t workload_index;
-extern uint64_t workload_ea;
-
-uint16_t workload_get_id(void)
-{
-	return workload_index;
-}
-
-uint64_t workload_get_ea(void)
-{
-	return workload_ea;
-}
-
-struct mars_workload_context *workload_get(void)
-{
-	return &workload;
-}
-
-struct mars_workload_context *workload_get_by_id(uint16_t workload_id)
-{
-	static struct mars_workload_context requested_workload;
-	uint64_t requested_workload_ea;
-
-	/* check function params */
-	if (workload_id >= MARS_WORKLOAD_MAX)
-		return NULL;
-
-	/* workload id is same as current workload so return local copy */
-	if (workload_id == workload_index)
-		return &workload;
-
-	/* get ea of workload to get */
-	requested_workload_ea = queue_header.context_ea +
-		workload_id * sizeof(struct mars_workload_context);
-
-	/* dma the workload context code into LS from main memory */
-	mars_dma_get_and_wait((void *)&requested_workload,
-		requested_workload_ea, sizeof(struct mars_workload_context),
-		MARS_DMA_TAG);
-
-	return &requested_workload;
-}
-
-void workload_exec(void)
-{
-	/* set current workload state to running */
-	workload_state = MARS_WORKLOAD_STATE_RUNNING;
-
-	/* workload type specific handling */
-	switch (workload_type) {
-	case MARS_WORKLOAD_TYPE_TASK:
-		task_exec((struct mars_task_context *)&workload);
-		break;
-	}
-}
-
-void workload_exit(void)
-{
-	/* set current workload state to finished */
-	workload_state = MARS_WORKLOAD_STATE_FINISHED;
-
-	/* workload type specific handling */
-	switch (workload_type) {
-	case MARS_WORKLOAD_TYPE_TASK:
-		task_exit((struct mars_task_context *)&workload);
-		break;
-	}
-}
-
-void workload_yield(void)
-{
-	/* set current workload state to ready */
-	workload_state = MARS_WORKLOAD_STATE_READY;
-
-	/* workload type specific handling */
-	switch (workload_type) {
-	case MARS_WORKLOAD_TYPE_TASK:
-		/* save non-volatile registers */
-		registers_save();
-
-		/* yield the task context */
-		task_yield((struct mars_task_context *)&workload);
-		break;
-	}
-}
-
-void workload_resume(void)
-{
-	/* set current workload state to running */
-	workload_state = MARS_WORKLOAD_STATE_RUNNING;
-
-	/* workload type specific handling */
-	switch (workload_type) {
-	case MARS_WORKLOAD_TYPE_TASK:
-		/* resume the task context */
-		task_resume((struct mars_task_context *)&workload);
-
-		/* restore non-volatile registers */
-		registers_restore();
-		break;
-	}
-}
-
-int workload_schedule(uint16_t workload_id, void *args, uint8_t priority)
-{
-	struct mars_workload_context schedule_workload;
-	uint8_t schedule_workload_type;
-	uint64_t schedule_workload_ea;
-	uint64_t block_ea;
-	int block;
-	int index;
-
-	/* check function params */
-	if (workload_id >= MARS_WORKLOAD_MAX)
-		return MARS_ERROR_PARAMS;
-	if (workload_id == workload_index)
-		return MARS_ERROR_PARAMS;
-
-	/* calculate block/index from id */
-	block = workload_id / MARS_WORKLOAD_PER_BLOCK;
-	index = workload_id % MARS_WORKLOAD_PER_BLOCK;
-
-	/* calculate block ea */
-	block_ea = queue_header.queue_ea +
-		offsetof(struct mars_workload_queue, block) +
-		sizeof(struct mars_workload_queue_block) * block;
-
-	mars_mutex_lock_get(block_ea, (struct mars_mutex *)&queue_block);
-
-	/* make sure workload is in the correct state */
-	if (MARS_BITS_GET(&queue_block.bits[index], STATE) !=
-		MARS_WORKLOAD_STATE_FINISHED) {
-		mars_mutex_unlock_put(block_ea,
-			(struct mars_mutex *)&queue_block);
-		return MARS_ERROR_STATE;
-	}
-
-	/* get information of workload to schedule */
-	schedule_workload_type = MARS_BITS_GET(&queue_block.bits[index], TYPE);
-	schedule_workload_ea = queue_header.context_ea +
-		workload_id * sizeof(struct mars_workload_context);
-
-	/* dma the workload context code into LS from main memory */
-	mars_dma_get_and_wait((void *)&schedule_workload,
-		schedule_workload_ea, sizeof(struct mars_workload_context),
-		MARS_DMA_TAG);
-
-	/* workload type specific handling */
-	switch (schedule_workload_type) {
-	case MARS_WORKLOAD_TYPE_TASK:
-		task_schedule((struct mars_task_context *)&schedule_workload,
-			(struct mars_task_args *)args);
-		break;
-	}
-
-	/* dma the workload context code into main memory from LS */
-	mars_dma_put_and_wait((void *)&schedule_workload,
-		schedule_workload_ea, sizeof(struct mars_workload_context),
-		MARS_DMA_TAG);
-
-	/* initialize queue block bits */
-	MARS_BITS_SET(&queue_block.bits[index], STATE,
-		MARS_WORKLOAD_STATE_READY);
-	MARS_BITS_SET(&queue_block.bits[index], PRIORITY,
-		priority);
-	MARS_BITS_SET(&queue_block.bits[index], COUNTER,
-		MARS_WORKLOAD_COUNTER_MIN);
-	MARS_BITS_SET(&queue_block.bits[index], SIGNAL,
-		MARS_WORKLOAD_SIGNAL_OFF);
-	MARS_BITS_SET(&queue_block.bits[index], WAIT_ID,
-		MARS_WORKLOAD_ID_NONE);
-
-	mars_mutex_unlock_put(block_ea, (struct mars_mutex *)&queue_block);
-
-	return MARS_SUCCESS;
-}
-
-int workload_wait(uint16_t workload_id)
-{
-	uint64_t block_ea;
-	int block;
-	int index;
-
-	/* check function params */
-	if (workload_id >= MARS_WORKLOAD_MAX)
-		return MARS_ERROR_PARAMS;
-	if (workload_id == workload_index)
-		return MARS_ERROR_PARAMS;
-
-	/* calculate block/index from id */
-	block = workload_index / MARS_WORKLOAD_PER_BLOCK;
-	index = workload_index % MARS_WORKLOAD_PER_BLOCK;
-
-	/* calculate block ea */
-	block_ea = queue_header.queue_ea +
-		offsetof(struct mars_workload_queue, block) +
-		sizeof(struct mars_workload_queue_block) * block;
-
-	mars_mutex_lock_get(block_ea, (struct mars_mutex *)&queue_block);
-
-	/* make sure workload is initialized */
-	if (MARS_BITS_GET(&queue_block.bits[index], STATE) ==
-		MARS_WORKLOAD_STATE_NONE) {
-		mars_mutex_unlock_put(block_ea,
-			(struct mars_mutex *)&queue_block);
-		return MARS_ERROR_STATE;
-	}
-
-	/* set the workload id to wait for */
-	MARS_BITS_SET(&queue_block.bits[index], WAIT_ID, workload_id);
-
-	mars_mutex_unlock_put(block_ea, (struct mars_mutex *)&queue_block);
-
-	return MARS_SUCCESS;
-}
-
-int workload_try_wait(uint16_t workload_id)
-{
-	uint64_t block_ea;
-	int block;
-	int index;
-
-	/* check function params */
-	if (workload_id >= MARS_WORKLOAD_MAX)
-		return MARS_ERROR_PARAMS;
-	if (workload_id == workload_index)
-		return MARS_ERROR_PARAMS;
-
-	/* calculate block/index from id */
-	block = workload_id / MARS_WORKLOAD_PER_BLOCK;
-	index = workload_id % MARS_WORKLOAD_PER_BLOCK;
-
-	/* calculate block ea */
-	block_ea = queue_header.queue_ea +
-		offsetof(struct mars_workload_queue, block) +
-		sizeof(struct mars_workload_queue_block) * block;
-
-	mars_mutex_lock_get(block_ea, (struct mars_mutex *)&queue_block);
-
-	/* check for valid state */
-	if (MARS_BITS_GET(&queue_block.bits[index], STATE) ==
-		MARS_WORKLOAD_STATE_NONE) {
-		mars_mutex_unlock_put(block_ea,
-			(struct mars_mutex *)&queue_block);
-		return MARS_ERROR_STATE;
-	}
-
-	mars_mutex_unlock_put(block_ea, (struct mars_mutex *)&queue_block);
-
-	/* check if workload is finished */
-	if (MARS_BITS_GET(&queue_block.bits[index], STATE) !=
-		MARS_WORKLOAD_STATE_FINISHED)
-		return MARS_ERROR_BUSY;
-
-	return MARS_SUCCESS;
-}
-
-int workload_signal_send(uint16_t workload_id)
-{
-	uint64_t block_ea;
-	int block;
-	int index;
-
-	/* check function params */
-	if (workload_id >= MARS_WORKLOAD_MAX)
-		return MARS_ERROR_PARAMS;
-	if (workload_id == workload_index)
-		return MARS_ERROR_PARAMS;
-
-	/* calculate block/index from id */
-	block = workload_id / MARS_WORKLOAD_PER_BLOCK;
-	index = workload_id % MARS_WORKLOAD_PER_BLOCK;
-
-	/* calculate block ea */
-	block_ea = queue_header.queue_ea +
-		offsetof(struct mars_workload_queue, block) +
-		sizeof(struct mars_workload_queue_block) * block;
-
-	mars_mutex_lock_get(block_ea, (struct mars_mutex *)&queue_block);
-
-	/* make sure workload is initialized */
-	if (MARS_BITS_GET(&queue_block.bits[index], STATE) ==
-		MARS_WORKLOAD_STATE_NONE) {
-		mars_mutex_unlock_put(block_ea,
-			(struct mars_mutex *)&queue_block);
-		return MARS_ERROR_STATE;
-	}
-
-	/* set the workload signal */
-	MARS_BITS_SET(&queue_block.bits[index], SIGNAL,
-		MARS_WORKLOAD_SIGNAL_ON);
-
-	mars_mutex_unlock_put(block_ea, (struct mars_mutex *)&queue_block);
-
-	return MARS_SUCCESS;
-}
-
-void workload_signal_wait(void)
-{
-	/* set current workload state to waiting */
-	workload_state = MARS_WORKLOAD_STATE_WAITING;
-
-	/* workload type specific handling */
-	switch (workload_type) {
-	case MARS_WORKLOAD_TYPE_TASK:
-		/* save non-volatile registers */
-		registers_save();
-
-		/* yield the task context */
-		task_yield((struct mars_task_context *)&workload);
-		break;
-	}
-}
-
-int workload_signal_try_wait(void)
-{
-	uint64_t block_ea;
-	int block;
-	int index;
-
-	/* check function params */
-	if (workload_index >= MARS_WORKLOAD_MAX)
-		return MARS_ERROR_PARAMS;
-
-	/* calculate block/index from id */
-	block = workload_index / MARS_WORKLOAD_PER_BLOCK;
-	index = workload_index % MARS_WORKLOAD_PER_BLOCK;
-
-	/* calculate block ea */
-	block_ea = queue_header.queue_ea +
-		offsetof(struct mars_workload_queue, block) +
-		sizeof(struct mars_workload_queue_block) * block;
-
-	mars_mutex_lock_get(block_ea, (struct mars_mutex *)&queue_block);
-
-	/* check for valid state */
-	if (MARS_BITS_GET(&queue_block.bits[index], STATE) ==
-		MARS_WORKLOAD_STATE_NONE) {
-		mars_mutex_unlock_put(block_ea,
-			(struct mars_mutex *)&queue_block);
-		return MARS_ERROR_STATE;
-	}
-
-	mars_mutex_unlock_put(block_ea, (struct mars_mutex *)&queue_block);
-
-	/* return busy if task has not received signal */
-	if (MARS_BITS_GET(&queue_block.bits[index], SIGNAL) !=
-		MARS_WORKLOAD_SIGNAL_ON)
-		return MARS_ERROR_BUSY;
-
-	return MARS_SUCCESS;
-}





More information about the cbe-oss-dev mailing list