summaryrefslogtreecommitdiff
path: root/gcell/src/include/gc_job_desc.h
blob: b7915067804ecb1e939443cc32a0a6f21fd30b9b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/* -*- c -*- */
/*
 * Copyright 2007,2008 Free Software Foundation, Inc.
 * 
 * This file is part of GNU Radio
 * 
 * GNU Radio is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3, or (at your option)
 * any later version.
 * 
 * GNU Radio is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef INCLUDED_GC_JOB_DESC_H
#define INCLUDED_GC_JOB_DESC_H

/*!
 * This file contains the structures that are used to describe how to
 * call "jobs" that execute on the SPEs.  A "job" is a task, or piece of
 * work that you want to run on an SPE.
 *
 * There is code running in the SPE that knows how to interpret
 * these job descriptions. Thus, in most cases, the overhead
 * of invoking these is very low.
 *
 * The whole "job idea" is SPE centric.  At first pass,
 * the PPE will be constructing jobs and enqueing them.
 * However, there is nothing in the implementation that
 * prohibits SPEs from creating their own jobs in the
 * future.  Also, there is nothing prohibiting SPE-to-SPE
 * DMA's.
 *
 * SPE's dequeue and "pull" jobs to themselves, do the work, then
 * notify the entity that submitted the job.
 */

#include "gc_types.h"
#include "gc_job_desc_private.h"

/*
 * This is C, not C++ code...
 *
 * ...and is used by both PPE and SPE code
 */
__GC_BEGIN_DECLS


//! opaque ID that specifies which code to invoke on the SPE
typedef uint32_t gc_proc_id_t;
#define GCP_UNKNOWN_PROC ((gc_proc_id_t) -1)


//! final job status
typedef enum {
  JS_OK,
  JS_SHUTTING_DOWN,	    // job mananger is shutting down
  JS_TOO_MANY_CLIENTS,	    // too many client threads
  JS_UNKNOWN_PROC,	    // didn't recognize the procedure ID
  JS_BAD_DIRECTION,	    // EA arg has invalid direction
  JS_BAD_EAH,		    // not all EA args have the same high 32 address bits
  JS_BAD_N_DIRECT,	    // too many direct args
  JS_BAD_N_EA,		    // too many EA args
  JS_ARGS_TOO_LONG,  	    // total length of EA args exceeds limit
  JS_BAD_JUJU,	    	    // misc problem: you're having a bad day
  JS_BAD_JOB_DESC,	    // gc_job_desc was not allocated using mgr->alloc_job_desc()

} gc_job_status_t;

#define MAX_ARGS_DIRECT  8  // maximum number of args passed using "direct" method
#define MAX_ARGS_EA	 8  // maximum number of args passed via EA memory (dma)

/*
 * We support two classes of arguments,
 *   "direct", which are contained in the gc_job_desc_args and
 *   "EA", which are copied in/out according to info in gc_job_desc_args
 */

/*!
 * \brief Tag type of "direct" argument
 */
typedef enum {
  GCT_S32,
  GCT_U32,
  GCT_S64,
  GCT_U64,
  GCT_FLOAT,
  GCT_DOUBLE,
  GCT_FLT_CMPLX,
  GCT_DBL_CMPLX,
  GCT_EADDR,

} gc_tag_t;


/*!
 * \brief union for passing "direct" argument
 */
typedef union gc_arg_union
{
  int32_t	 s32;
  uint32_t	 u32;
  int64_t	 s64;
  uint64_t	 u64;
  float		 f;
  double	 d;
  //float complex  cf;	//  64-bits (C99)
  //double complex cd;  // 128-bits (C99)
  gc_eaddr_t	 ea;	//  64-bits
} _AL8 gc_arg_union_t;


/*!
 * \brief "direct" input or output arguments
 */
typedef struct gc_job_direct_args
{
  uint32_t	  nargs;		        // # of "direct" args
  gc_tag_t	  tag[MAX_ARGS_DIRECT] _AL16;   // type of direct arg[i]
  gc_arg_union_t  arg[MAX_ARGS_DIRECT] _AL16;   // direct argument values

} _AL16 gc_job_direct_args_t;


// specifies direction for args passed in EA memory

#define GCJD_DMA_GET		0x01		// in to SPE
#define	GCJD_DMA_PUT		0x02		// out from SPE

/*!
 * \brief Description of args passed in EA memory.
 * These are DMA'd between EA and LS as specified.
 */
typedef struct gc_job_ea_arg {
  //! EA address of buffer
  gc_eaddr_t     ea_addr;	

  //! GC_JD_DMA_* get arg or put arg
  uint32_t	 direction;

  //! number of bytes to get
  uint32_t	 get_size;	   

  //! number of bytes to put
  uint32_t	 put_size;

#if defined(__SPU__)
  //! local store address (filled in by SPU runtime)
  void		*ls_addr;
  uint32_t	 _pad[2];
#else
  uint32_t       _pad[3];
#endif

} _AL16 gc_job_ea_arg_t;


typedef struct gc_job_ea_args {
  uint32_t		nargs;
  gc_job_ea_arg_t	arg[MAX_ARGS_EA];

} _AL16 gc_job_ea_args_t;


/*!
 * \brief "job description" that is DMA'd to/from the SPE.
 */
typedef struct gc_job_desc
{
  gc_job_desc_private_t sys;	  // internals
  gc_job_status_t   	status;	  // what happened (output)
  gc_proc_id_t          proc_id;  // specifies which procedure to run
  gc_job_direct_args_t	input;	  // direct args to SPE
  gc_job_direct_args_t	output;	  // direct args from SPE
  gc_job_ea_args_t	eaa;	  // args passed via EA memory

} _AL128 gc_job_desc_t;


/*!
 * type of procedure invoked on spu
 */
typedef void (*gc_spu_proc_t)(const gc_job_direct_args_t *input,
			      gc_job_direct_args_t *output,
			      const gc_job_ea_args_t *eaa);

#if !defined(__SPU__)

static inline gc_job_desc_t *
ea_to_jdp(gc_eaddr_t ea)
{
  return (gc_job_desc_t *) ea_to_ptr(ea);
}

static inline gc_eaddr_t
jdp_to_ea(gc_job_desc_t *item)
{
  return ptr_to_ea(item);
}

#endif


__GC_END_DECLS

#endif /* INCLUDED_GC_JOB_DESC_H */