summaryrefslogtreecommitdiff
path: root/c/src/lib/libbsp/sparc/shared/include/rmap.h
blob: c18dafed5ecf8551f9e1c907eb77f1f534d6bd0a (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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
/* RMAP stack and RMAP driver interface
 *
 *  COPYRIGHT (c) 2009
 *  Aeroflex Gaisler.
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.com/license/LICENSE.
 *
 */

#ifndef __RMAP_H__
#define __RMAP_H__

#ifdef __cplusplus
extern "C" {
#endif

/*** RMAP Driver interface ***/

#define PKT_OPTION_HDR_CRC	0x1 /* Enable Header CRC by Hardware */
#define PKT_OPTION_DATA_CRC	0x2 /* Enable Data CRC by Hardware */
/* skip len of header when calculating CRC by hardware */
#define PKT_OPTION_HDR_CRC_SKIPLEN(len)	(((len) & 0xf) << 8)
#define PKT_OPTION_HDR_CRC_SKIPLEN_MASK 0xf00

/* RMAP SpW packet */
struct rmap_spw_pkt {
	int		options;	/* Data CRC | Header CRC */
	int		hlen;
	unsigned char	*hdr;
	int		dlen;
	unsigned char	*data;
	int		reserved[2];	/* May be used internally by driver layer */
};

struct rmap_drv_ops {
	int	(*init)(void *cookie);						/* Initialize driver */
	int	(*ioctl)(void *cookie, int command, void *arg);			/* Configure driver */
	int	(*send)(void *cookie, struct rmap_spw_pkt *pkt);		/* Schedule one packet for transmission */
	int	(*recv)(void *cookie, struct rmap_spw_pkt *pkt);		/* Receive one packet */
};

/* RMAP driver description */
struct rmap_drv {
	struct rmap_drv_ops	ops;
	void			*cookie;
};

#define RMAP_TIMEOUT_SET_RTIME 0x01
#define RMAP_TIMEOUT_SET_WTIME 0x02
struct rmap_drv_timeout {
	unsigned int options;
	unsigned int rtimeout;
	unsigned int wtimeout;
};

/* RMAP driver ioctl commands */
#define RMAP_DRV_IOCTL_START		1	/* Start operation, packets will be sent/received after this command */
#define RMAP_DRV_IOCTL_STOP		2	/* Stop operation, no more packets will be sent before next START */
#define RMAP_DRV_IOCTL_BLOCK		3	/* Set RX/TX blocking */
#define RMAP_DRV_IOCTL_TIMEOUT		4	/* Set timeout in blocing mode */
#define RMAP_DRV_IOCTL_GET_CAP		5	/* Get capabilities of the driver/hardware */
#define RMAP_IOCTL_GET_CONFIG		6	/* Get Stack Configuration */

/* Capabilities */
#define DRV_CAP_HDR_CRC			0x1	/* Hardware supports HEADER CRC generation */
#define DRV_CAP_DATA_CRC		0x2	/* Hardware supports DATA CRC generation */


/*** RMAP Stack interface ***/

/* Function that will generate path addressing.
 *
 * \param cookie   Identifies RMAP stack, 
 * \param dir      Direction (0=to dst, 1=from dst)
 * \param srcadr   Source address (the SpW address of the interface used)
 * \param dstadr   Destination address to translate. Note that it is actually
 *                 a "unsigned short" given here, so this is rather a Node-ID.
 * \param buf      Where path address is put
 * \param len      On calling it indicates max length. On return it must be set
 *                 reflect the number of bytes was written to buf.
 */
typedef int (*rmap_route_t)(void *cookie, int dir, int srcadr, int dstadr, void *buf, int *len);

struct rmap_config {
	rmap_route_t	route_func;	/* Function that will generate path addressing */
	int		tid_msb;	/* 8 most significant bits in TID.
					 * Set to -1 for normal operation using
					 * all bits in TID for sequence counting.
					 */
	int		spw_adr;	/* The SpW Address of the SpW interface used */
	struct rmap_drv	*drv;		/* Driver used for transmission */
	int		max_rx_len;	/* Maximum data length of received packets */
	int		max_tx_len;	/* Maximum data length of transmitted packets */
	int		thread_safe;	/* Set this to non-zero to enable the RMAP stack to create a
					 * semaphore used to protect from multiple tasks entering the
					 * transfer function(s) of the stack at the same time */
};

struct rmap_command {
	char			type;		/* READ/WRITE/MODIFY ... */
	unsigned char		dstkey;		/* Destination key */
	unsigned char		status;		/* Error/Status response. 0 if no response is expected */
	unsigned short		dstadr;		/* Destination address */
	unsigned short		tid;		/* TID assigned to packet */
	unsigned long long	address;	/* READ/WRITE address, 32-bit + 8-bit extended */
	union {
		struct {
			unsigned int length;	/* 24-bit data length */
			unsigned char *data;	/* Data bytes, NOTE that 1 byte must be available
						 * for the stack to write the DATA CRC in the end
						 * of the data buffer. Stack write data[length] = CRC
						 */
		} write;
		struct {
			unsigned int length;	/* 24-bit length */
			unsigned int datalength;/* Response 24-bit length, may be different from requested length */
			unsigned int *data;	/* Response data is stored in this buffer */
		} read;
		struct {
			unsigned int length;	/* length 1,2 or 4 valid */
			unsigned int data;	/* 1,2 or 4 bytes data */
			unsigned int mask;	/* 1,2 or 4 bytes data mask */
			unsigned int oldlength;	/* Response, old data length */
			unsigned int olddata;	/* Response, old data before write */
		} read_m_write;
	} data;
};

struct rmap_command_write {
	char			type;		/* WRITE (Increment, Single, ACK, Verify) */
	unsigned char		dstkey;		/* Destination key */
	unsigned char		status;		/* Status response, set if ACK, non-zero indicates error */
	unsigned short		dstadr;		/* Destination address */
	unsigned short		tid;		/* TID assigned to packet */
	unsigned long long	address;	/* READ/WRITE address */
	unsigned int 		length;		/* 24-bit data length */
	unsigned char		*data;		/* Data bytes, NOTE that 1 byte must be available 
						 * for the stack to write the DATA CRC in the end 
						 * of the data buffer. Stack write data[length] = CRC
						 */
};

struct rmap_command_read {
	char			type;		/* READ (Single, Increment) */
	unsigned char		dstkey;		/* Destination key */
	unsigned char		status;		/* Status response, always set, non-zero indicates error */
	unsigned short		dstadr;		/* Destination address */
	unsigned short		tid;		/* TID assigned to packet */
	unsigned long long	address;	/* READ/WRITE address */
	unsigned int 		length;		/* 24-bit data length */
	unsigned int		datalength;	/* Response 24-bit length, may be different from requested length */
	unsigned int		*data;		/* Response data is stored in this buffer */
};

struct rmap_command_rmw {
	char			type;		/* RMAP_CMD_RMWI */
	unsigned char		dstkey;		/* Destination key */
	unsigned char		status;		/* Status response, always set, non-zero indicates error */
	unsigned short		dstadr;		/* Destination address */
	unsigned short		tid;		/* TID assigned to packet */
	unsigned long long	address;	/* READ/WRITE address */
	unsigned int		length;		/* length 1,2 or 4 valid */
	unsigned int		data;		/* 1,2 or 4 bytes data */
	unsigned int		mask;		/* 1,2 or 4 bytes data mask */
	unsigned int		oldlength;	/* Response, old data length */
	unsigned int		olddata;	/* Response, old data before write */
};

/* Command definition.
 *
 * R = READ
 * W = WRITE
 * M = MODIFY
 * S = SINGLE
 * I = INCREMENTING ADDRESSES
 * V = VERIFY
 * A = ACKNOWLEDGE
 */
enum {
	RMAP_CMD_UNUSED1 	= 0x0,	/* Not used */
	RMAP_CMD_UNUSED2 	= 0x1,	/* Not used */
	RMAP_CMD_RS		= 0x2,	/* Read single address */
	RMAP_CMD_RI		= 0x3,	/* Read incrementing addresses */
	RMAP_CMD_UNUSED3	= 0x4,	/* Not used */
	RMAP_CMD_UNUSED4	= 0x5,	/* Not used */
	RMAP_CMD_UNUSED5	= 0x6,	/* Not used */
	RMAP_CMD_RMWI		= 0x7,	/* Read-Modify-Write incrementing addresses */
	RMAP_CMD_WS		= 0x8,	/* Write, single address, don't verify before writing, no acknowledge */
	RMAP_CMD_WI		= 0x9,	/* Write, incrementing addresses, don't verify before writing, no acknowledge */
	RMAP_CMD_WSA		= 0xa,	/* Write, single address, don't verify before writing, send acknowledge */
	RMAP_CMD_WIA		= 0xb,	/* Write, incrementing addresses, don't verify before writing, send acknowledge */
	RMAP_CMD_WSV		= 0xc,	/* Write, single address, verify before writing, no acknowledge */
	RMAP_CMD_WIV		= 0xd,	/* Write, incrementing addresses, verify before writing, no acknowledge */
	RMAP_CMD_WSVA		= 0xe,	/* Write, single address, verify before writing, send acknowledge */
	RMAP_CMD_WIVA		= 0xf,	/* Write, incrementing addresses, verify before writing, send acknowledge */
};

#define RMAP_CMD_INCREMENT	0x1
#define RMAP_CMD_ACKNOWLEDGE	0x2
#define RMAP_CMD_VERIFY		0x4
#define RMAP_CMD_WRITE		0x8

/* Initialize the stack 
 *
 * \param route_func   Function that will generate path addressing
 * \param drv		Set driver used for transmission
 */
void *rmap_init(struct rmap_config *config);

/* Enables the RMAP stack to send/receive commands */

/* Disables the RMAP stack to send/receive commands */

/* Configure stack (blocking etc)*/
extern int rmap_ioctl(void *cookie, int command, void *arg);

/* Send a command and optionally block waiting for response.
 *
 * The transaction ID is incremented 
 *
 * \param cmd   RMAP command to transmit
 * \param resp  Response (stack blocking mode only)
 * \param tid   Pointer to where the Transaction ID is stored (stack non-blocking mode only)
 */
extern int rmap_send(void *cookie, struct rmap_command *cmd);

#if NOT_IMPLEMENTED
/** OPTIONAL PART 1 **/

/* Wait for response on a previously sent RMAP command, the command was sent
 * using rmap_send and was assigned a transaction ID (tid). The TID is used'
 * to separate different RMAP commands from each other.
 *
 * This is a blocking call.
 *
 * Only available when,
 *  - stack in non-blocking mode
 *  - driver in blocking mode.
 *
 * \param timeout  Timeout in ticks. Currently NOT used.
 * \param resp     Response on the Transaction ID
 * \param tid      Transaction ID
 */
extern int rmap_resp_wait(void *cookie, int timeout, struct rmap_command *resp, unsigned int tid);

/** OPTIONAL PART 2 **/

/* Check for response on a previously sent RMAP command, the command was sent
 * using rmap_send and was assigned a transaction ID (tid). The TID is used'
 * to separate different RMAP commands from each other.
 *
 * This function will never block.
 *
 * Only available when,
 *  - stack in non-blocking mode
 *  - driver in non-blocking mode.
 *
 * \param resp  Response on the Transaction ID
 * \param tid   Transaction ID
 */
extern int rmap_resp_poll(void *cookie, struct rmap_command *resp, unsigned int tid);
#endif

/* rmap_ioctl commands */
#define RMAP_IOCTL_START	0	/* Start RMAP stack, enables stack to send/receive packets */
#define RMAP_IOCTL_STOP		1	/* Stop RMAP stack, no packets will be sent/received */
#define RMAP_IOCTL_BLOCK	2	/* Set blocking mode */
#define RMAP_IOCTL_TIMEOUT	3	/* Set timeout for command responses in number of ticks */

#define RMAP_IOCTRL_BLOCK_ALL	0


/*** RMAP Stack help interface ***/

/* Parse a Write command */

/* Return the CRC of a RMAP data buffer of length len */
extern unsigned char rmap_crc_calc(unsigned char *data, unsigned int len);

/* A handy write function using the RMAP stack */
extern int rmap_write(void *cookie, void *dst, void *buf, int length, int dstadr, int dstkey);

/* A handy read function using the RMAP stack */
extern int rmap_read(void *cookie, void *src, void *buf, int length, int dstadr, int dstkey);

#ifdef __cplusplus
}
#endif

#endif