More syslink messaging work. Now basically done except for the I/O 'DMA'
[dragonfly.git] / sys / sys / syslink_msg.h
1 /*
2  * Copyright (c) 2004-2007 The DragonFly Project.  All rights reserved.
3  * 
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * $DragonFly: src/sys/sys/syslink_msg.h,v 1.9 2007/06/17 21:31:07 dillon Exp $
35  */
36 /*
37  * The syslink infrastructure implements an optimized RPC mechanism across a 
38  * communications link.  Endpoints, defined by a session sysid, are typically 
39  * associated with system structures but do not have to be.
40  *
41  * This header file is primarily responsible for the formatting of message
42  * traffic over a syslink.
43  */
44
45 #ifndef _SYS_SYSLINK_MSG_H_
46 #define _SYS_SYSLINK_MSG_H_
47
48 #ifndef _SYS_TYPES_H_
49 #include <sys/types.h>
50 #endif
51 #ifndef _MACHINE_ATOMIC_H_
52 #include <machine/atomic.h>
53 #endif
54
55 typedef int32_t         sl_auxdata_t;   /* auxillary data element */
56 typedef u_int32_t       sl_rlabel_t;    /* reply label routing id */
57 typedef u_int16_t       sl_proto_t;     /* protocol control field */
58 typedef u_int16_t       sl_cmd_t;       /* command/status id */
59 typedef u_int16_t       sl_reclen_t;    /* item length */
60
61 #define SL_ALIGN        8               /* 8-byte alignment */
62 #define SL_ALIGNMASK    (SL_ALIGN - 1)
63
64 /*
65  * SYSLINK_ELM - structured data element.
66  *
67  * syslink_msg's have zero or more syslink_elm's arranged as an array.
68  * Each syslink_elm may represent opaque data or recursively structured
69  * data.
70  *
71  * SE_CMD field - identify RPC command (at the top level) or RPC data element
72  *                in deeper recursions.
73  *
74  *      Please note that while bits have individual meanings, command switches
75  *      should universally compare all 16 bits against the command.  This
76  *      guarentees that commands will not be misinterpreted (e.g. reply vs
77  *      command, or data which has not been endian converted).
78  *
79  *      SE_CMDF_REPLY - is usually set in the top level syslink_elm embedded
80  *      in syslink message replies as a safety in order to prevent a reply
81  *      from being misinterpreted as a command.
82  *
83  *      SE_CMDF_STRUCTURED - indicates that the payload is an array of
84  *      structured syslink_elm's, otherwise the payload is considered to
85  *      be opaque.
86  *
87  *      SE_CMDF_GLOBAL - indicates that the command is globally defined by the
88  *      syslink standard and is not protocol-specific.  Note that PADs
89  *      are not global commands.
90  *
91  *      SE_CMDF_UNTRANSLATED - indicates that the syslink_elm structure had
92  *      to be translated into host endian format but any directly or
93  *      indirectly represented opaque data has not been.  This bit is used
94  *      by the protocol layer to properly endian-translate protocol-specific
95  *      opaque data.
96  *
97  *      SE_CMDF_ASIZE* - These 2 bits can encode the size for simple elments.
98  *      The size is verified prior to delivery so command switches on simple
99  *      elements need not check se_bytes.  This also makes it easier for
100  *      the protocol code to do endian conversions.
101  *
102  * SE_AUX field - auxillary data field (signed 32 bit integer)
103  *
104  *      This field contains protocol and command/element specific data.
105  *      This typically contains an error code in replies (at least in
106  *      sm_head).
107  */
108 struct syslink_elm {
109         sl_cmd_t        se_cmd;         /* syslink element command/status id */
110         sl_reclen_t     se_bytes;       /* unaligned record size */
111         sl_auxdata_t    se_aux;         /* auxillary data always present */
112         /* extended by data */
113 };
114
115 #define SE_CMDF_REPLY           0x8000  /* safety feature */
116 #define SE_CMDF_STRUCTURED      0x4000  /* payload is structured */
117 #define SE_CMDF_GLOBAL          0x2000  /* non-proto-specific global cmd */
118 #define SE_CMDF_UNTRANSLATED    0x1000  /* needs endian translation */
119
120 #define SE_CMDF_ASIZEMASK       0x0C00  /* auto-size mask */
121 #define SE_CMDF_ASIZEX          0x0000  /* N bytes of extended data */
122 #define SE_CMDF_ASIZE0          0x0400  /* 0 bytes of extended data */
123 #define SE_CMDF_ASIZE4          0x0800  /* 4 bytes of extended data */
124 #define SE_CMDF_ASIZE8          0x0C00  /* 8 bytes of extended data */
125
126 #define SE_CMD_MASK             0x03FF
127
128 #define SE_CMD_PAD              0x0000  /* always reserved to mean PAD */
129
130 /*
131  * SYSLINK_MSG - Syslink transactional command or response
132  *
133  * This structure represents a syslink transactional command or response
134  * between two end-points identified by the session id.  Either end may
135  * initiate a command independant of the other.  A transaction consists of
136  * the sending of a command and the reception of a response.
137  *
138  * Multiple transactions in each direction (and both directions at once)
139  * may occur in parallel.  The command/reply transaction space in one
140  * direction is independant of the command/reply transaction space in the
141  * other direction.
142  *
143  * SM_PROTO     rppppppx-ppppppx
144  *
145  *      r       0 = Command, 1 = Reply
146  *
147  *      x       Used to detect endian reversal.  The protocol id is OR'd
148  *              with 0x0100 on transmission.  If we find bit 0 set to 1 on
149  *              reception, endian translation must occur.
150  *
151  *      -       Reserved, must be 0
152  *
153  *      p12     Encoded protocol number.  Protocol 0 indicates PAD (r must
154  *              be 0 as well).  Protocols 0-63 are reserved and may only be
155  *              used when officially recognized by the DragonFly project.
156  *              64-4095 are user defined.
157  *
158  * SM_BYTES     bbbbbbbbbbbbbbbb
159  *
160  *      b16     This is the size of the whole message, including headers
161  *              but not including out-of-band DMA.  All messages must
162  *              be 8-byte aligned.  Unlike syslink_elm structures, sm_bytes
163  *              must be properly aligned.
164  *
165  * SM_RLABEL    llllllllllllllllllllllllllllllll
166  *
167  *      l32     This is a 32 bit reply label routing id.  The format of
168  *              this field is defined by the transport layer.  The field
169  *              is typically assigned in the command message as it passes
170  *              through the transport layer and is retained verbatim in
171  *              the reply message.
172  *
173  *              The most typical use of this field is as an aid to direct
174  *              messages in a multi-threaded environment.  For example,
175  *              a kernel talking to a filesystem over a syslink might
176  *              identify the thread originating the command in this field
177  *              in order to allow the reply to be routed directly back to
178  *              that thread.
179  *
180  *              The field can also be used in crossbar switching meshes
181  *              to identify both the originator and the target, but it
182  *              should be noted that the verbatim requirement means the
183  *              mesh must pick out the proper field based on the 'r'eply
184  *              bit in sm_proto.
185  *
186  * SM_MSGID     m64
187  *
188  *      m64     This 64 bit message id combined with the mesh id and the
189  *              'r'eply bit (and also the direction of the message when
190  *              operating over a full-duplex syslink) uniquely identifies
191  *              a syslink message.
192  *
193  *              The message id is typically set to the address of the
194  *              syslink message or control structure used by the originator,
195  *              or obtained from a 64 bit counter.  This way the originator
196  *              can guarentee uniqueness without actually having to track
197  *              message id allocations.
198  *
199  * SM_SESSID    s64
200  *
201  *      s64     This is a 64 bit session id key whos primary purpose is to
202  *              validate a link and prevent improperly routed or stale
203  *              messages from having an adverse effect on the cluster.  The
204  *              field is typically left 0 for intra-host links.
205  *
206  * SM_HEAD      (structure)
207  *
208  *      All syslink messages other then PAD messages must contain at least
209  *      one whole syslink_elm.  Elements are arranged in an array until
210  *      the syslink message space is exhausted.  Each element may represent
211  *      opaque data or recursively structured data.  Structured data consists
212  *      of an array of 0 or more elements embedded in the parent element.
213  *
214  *
215  * ENDIAN TRANSLATION - endian translation occurs when a message is received
216  * with bit 0 set in sm_proto, indicating that the native endian mode of
217  * the sender is different from the native endian mode of the receiver.
218  * Endian translation is NOT specific to little or big endian formatting
219  * but instead occurs only when the two sides have different native endian
220  * modes.  All fields are interpreted structurally.  Only little and big
221  * endian formats are supported (i.e. simple byte reversal).
222  *
223  * Translation consists of reversing the byte ordering for each structural
224  * field.  Any syslink_elm structures are recursively translated as well,
225  * but opaque data contained within is not.  The SE_CMDF_UNTRANSLATED bit
226  * in each translated syslink_elm structure is flipped.
227  *
228  * Syslink routers and switches may or may not translate a syslink_msg (but
229  * they must still properly interpret the syslink_msg header as the
230  * message passes through).  It is possible for a message to be translated
231  * multiple times while it transits the network so it is important when
232  * translation occurs that the SE_CMDF_UNTRANSLATED bit in the syslink_elm
233  * structures gets flipped rather then simply set.
234  */
235 struct syslink_msg {
236         sl_proto_t      sm_proto;       /* protocol id, endian, reply bit */
237         sl_reclen_t     sm_bytes;       /* unaligned size of message */
238         sl_rlabel_t     sm_rlabel;      /* reply label routing id */
239         /* minimum syslink_msg size is 8 bytes (special PAD) */
240         sysid_t         sm_msgid;       /* message id */
241         sysid_t         sm_sessid;      /* session id */
242         struct syslink_elm sm_head;     /* structured data */
243 };
244
245 /*
246  * Minimum sizes for syslink pads and syslink messages.  Pads can be as
247  * small as 8 bytes and are 8-byte aligned.  Syslink messages can be as
248  * small as 16 bytes and are 8-byte aligned.
249  */
250 #define SL_MIN_PAD_SIZE         offsetof(struct syslink_msg, sm_msgid)
251 #define SL_MIN_MSG_SIZE         sizeof(struct syslink_msg)
252 #define SL_MIN_ELM_SIZE         sizeof(struct syslink_elm)
253 #define SL_MSG_ALIGN(bytes)     (((bytes) + 7) & ~7)
254
255 /*
256  * sm_proto field       rppppppx-PPPPPPx        encoded
257  *                      ----ppppppPPPPPP        decoded
258  *
259  * Note: SMPROTO_ defines are in encoded form
260  */
261 #define SM_PROTO_REPLY          0x8000
262 #define SM_PROTO_ENDIAN_NORM    0x0100
263 #define SM_PROTO_ENDIAN_REV     0x0001
264 #define SM_PROTO_ENCODE(n)      ((((n) << 1) & ~127) | (((n) << 3) & 0x7E00) \
265                                  | SM_PROTO_ENDIAN_NORM)
266 #define SM_PROTO_DECODE(n)      ((((n) >> 1) & 63) | (((n) >> 3) & )) 0x0FC0) \
267                                  | SM_PROTO_ENDIAN_NORM)
268
269 /*
270  * Reserved protocol encodings 0-63
271  */
272 #define SMPROTO_PAD             SM_PROTO_ENCODE(0x0000)
273
274 /*
275  * high level protocol encodings
276  */
277 #define SMPROTO_BSDVFS          SM_PROTO_ENCODE(0x0040)
278
279 /*
280  * Syslink messages may contain recursive components.  The recursion depth
281  * allowed is limited to SL_MAXDEPTH.
282  *
283  * Syslink messages, NON-inclusive of any DMA buffers, are limited to
284  * SL_MAXSIZE bytes.  DMA buffer limitations are not defined here but
285  * the expectation is that they can be fairly large.
286  */
287 #define SL_MAXDEPTH     10
288 #define SL_MAXSIZE      4096
289
290 /*
291  * slmsgalloc() sizes
292  */
293 #define SLMSG_SMALL     256
294 #define SLMSG_BIG       SL_MAXSIZE
295
296
297 union syslink_small_msg {
298         struct syslink_msg msg;
299         char buf[SLMSG_SMALL];
300 };
301
302 union syslink_big_msg {
303         struct syslink_msg msg;
304         char buf[SLMSG_BIG];
305 };
306
307 typedef struct syslink_msg      *syslink_msg_t;
308 typedef struct syslink_elm      *syslink_elm_t;
309
310 #endif
311