/* SCE CONFIDENTIAL
PLAYSTATION(R)3 Programmer Tool Runtime Library 154.001
 * Copyright (C) 2006 Sony Computer Entertainment Inc.
 * All Rights Reserved.
 */

#ifndef __CELL_SPURS_TASK_H__
#define __CELL_SPURS_TASK_H__ 1

/* The C Standard Library */
#include <stdint.h>

/* SPU C/C++ Language Extention */
#include <spu_intrinsics.h>

/* SPURS */
#include <cell/spurs/task_types.h>
#include <cell/spurs/types.h>			/* CellSpursWorkloadId */
#include <cell/spurs/error.h>
#include <cell/spurs/workload.h>		/* cellSpursGetWorkloadData */
#include <cell/spurs/common.h>			/* functions moved to common.h */

#define CELL_SPURS_TASK_LS_ALL		((vec_uint4){CELL_SPURS_TASK_TOP_MASK,0xffffffffu,0xffffffffu,0xffffffffu})

#ifdef __cplusplus
extern "C" {
#endif

/*
 * taskset control
 */
int cellSpursShutdownTaskset(uint64_t eaTaskset);

/*
 * taskset information for SPU common
 */
static inline
int cellSpursLookUpTasksetAddress(uint64_t *taskset, CellSpursWorkloadId id)
{
	if (taskset == 0) {
		return CELL_SPURS_TASK_ERROR_NULL_POINTER;
	}
	if (id >= CELL_SPURS_MAX_WORKLOAD) {
		return CELL_SPURS_TASK_ERROR_INVAL;
	}
	*taskset = _cellSpursGetWorkloadData(id);
	return CELL_OK;
}

/*
 * task control for SPURS task
 */
void cellSpursMain(qword argTask, uint64_t argTaskset);
void cellSpursExit(void) __attribute__((noreturn));
int cellSpursYield(void);
int cellSpursWaitSignal(void);

/*
 * task control for SPU common
 */
int cellSpursCreateTask(uint64_t	eaTaskset,
						CellSpursTaskId*,
						uint64_t	eaElf,
						uint64_t	eaContext,
						uint32_t	sizeContext,
						vec_uint4	lsPattern,
						qword		argument);

int cellSpursSendSignal(uint64_t eaTaskset, CellSpursTaskId);

/*
 * task information
 */
CellSpursTaskId cellSpursGetTaskId(void);
uint64_t cellSpursGetTasksetAddress(void);
uint64_t cellSpursGetElfAddress(void);

/*
 * LS context pattern
 */
vec_uint4 cellSpursContextGetLsPattern(void);

int cellSpursContextSetLsPattern(vec_uint4 ls_pattern);

static inline
vec_uint4 cellSpursContextGenerateLsPattern(intptr_t start, int size)
{
	int mbegin = CELL_SPURS_CONTEXT_SIZE2BITS(start);
	int mend   = CELL_SPURS_CONTEXT_SIZE2BITS(start + size + 2047);
	vec_uint4 mask_base  = (vec_uint4)(-1);
	vec_uint4 mask_begin = spu_rlmaskqw(spu_rlmaskqwbytebc(mask_base,7-mbegin),-mbegin);
	vec_uint4 mask_end   = spu_slqw(spu_slqwbytebc(mask_base,128-mend),128-mend);
	return spu_and(mask_begin, mask_end);
}

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* __CELL_SPURS_TASK_H__ */

/*
 * Local Variables:
 * mode: C
 * c-file-style: "stroustrup"
 * tab-width: 4
 * End:
 * vim:sw=4:sts=4:ts=4
 */
