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

#ifndef __CELL_SPURS_JOB_DESCRIPTOR_H__
#define __CELL_SPURS_JOB_DESCRIPTOR_H__


#include <stdint.h>
#include <cell/spurs/error.h>

#ifdef __cplusplus
extern "C" {
#endif

	typedef struct CellSpursJobID
	{
		uint32_t notify : 2;
		uint32_t id : 30;
	} CellSpursJobID;

	typedef union CellSpursJobInputList
	{
		struct {
			uint16_t __reserved__;
			uint16_t size;
			uint32_t eal;
		} asInputList;
		uint64_t asUint;
	} CellSpursJobInputList;

	typedef union CellSpursJobCacheList
	{
		struct {
			uint32_t size;
			uint32_t eal;
		} asCacheList;
		uint64_t asUint;
	} CellSpursJobCacheList;

	typedef struct CellSpursJobHeader
	{
		/// Job binary Effective Address
		uint64_t eaBinary;

		/// Job binary size (actual size in bytes) >> 4
		uint16_t sizeBinary __attribute__((__packed__)); //16bits

		/// Input DMA List size (in bytes)
		uint16_t sizeDmaList __attribute__((__packed__));//8 bits

		/// High 32-bits of all input addresses
		uint32_t eaHighInput __attribute__((__packed__));

		/// Input or Input-Output flag
		uint32_t useInOutBuffer; // Input if zero, otherwise Input-Output
		
		/// Input size or Input-Output size
		uint32_t sizeInOrInOut;//18 bits

		/// Output size
		uint32_t sizeOut;//18 bits

		/// Scratch size
		uint32_t sizeScratch;//18 bits

		/// Cache-hinted read-only input Effective Address
		uint32_t eaHighCache;

		/// Cache-hinted read-only input DMA List size (in bytes)
		uint32_t sizeCacheDmaList;

		/// 30-bit Job ID for completion notification
		/// High 2 bits define notificication type
		///  0 = No notification
 		///  1 = Poll notification
		///  2 = Event notification
		///  3 = Unused
		CellSpursJobID idJob;

		uint32_t __reserved;

	} CellSpursJobHeader __attribute__((__aligned__(16)));

#define DEFINE_TYPE_CELL_SPURS_JOB(N,N_LIST) \
typedef struct _CellSpursJob##N\
{\
	CellSpursJobHeader header;\
	uint64_t dmaList[N_LIST];\
	uint64_t userData[(N-sizeof(CellSpursJobHeader)/sizeof(uint64_t) -N_LIST]; \
} CellSpursJob##N;

#define CELL_SPURS_GET_SIZE_BINARY(size_in_byte) \
  (uint16_t)(((uintptr_t)(size_in_byte) + 15) >> 4)

 typedef struct CellSpursJob64
 {
	 CellSpursJobHeader header;
	 union {
		 uint64_t dmaList[2];
		 uint64_t userData[2];
	 } workArea;
 } CellSpursJob64 __attribute__((aligned(16)));

 typedef struct CellSpursJob128
 {
	 CellSpursJobHeader header;
	 union {
		 uint64_t dmaList[10];
		 uint64_t userData[10];
	 } workArea;
 } CellSpursJob128 __attribute__((aligned(128)));


 typedef struct CellSpursJob256
 {
	 CellSpursJobHeader header;
	 union {
		 uint64_t dmaList[26];
		 uint64_t userData[26];
	 } workArea;
 } CellSpursJob256 __attribute__((aligned(128)));

 typedef struct CellSpursJobList
 {
	 uint32_t numJobs;
	 uint32_t sizeOfJob;
	 uint64_t eaJobList;
 } CellSpursJobList __attribute__((aligned(16)));



#ifdef __cplusplus
}
#endif

static inline
int cellSpursJobGetInputList(uint64_t *inputList,
							 uint16_t size,
							 uint32_t eal)
{
	int ret;
	ret = ((size & 0xf) |
		   (eal & 0xf)) ? CELL_SPURS_JOB_ERROR_ALIGN :
		((size > 0x4000) ? CELL_SPURS_JOB_ERROR_INVAL : CELL_OK);
	*inputList = ((uint64_t)size << 32) | (uint64_t)eal;

	return ret;
}

static inline
int cellSpursJobGetCacheList(uint64_t *cacheList,
							 uint16_t size,
							 uint32_t eal)
{
	int ret;
	ret = ((size & 0xf) |
		   (eal & 0xf)) ? CELL_SPURS_JOB_ERROR_ALIGN : CELL_OK;
	*cacheList = ((uint64_t)size << 32) | (uint64_t)eal;
	
	return ret;
}

#endif /* __CELL_SPURS_JOB_DESCRIPTOR_H__ */

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