1 | /* |
---|
2 | * GR1553B BC driver, Descriptor LIST handling |
---|
3 | * |
---|
4 | * COPYRIGHT (c) 2010. |
---|
5 | * Cobham Gaisler AB. |
---|
6 | * |
---|
7 | * The license and distribution terms for this file may be |
---|
8 | * found in the file LICENSE in this distribution or at |
---|
9 | * http://www.rtems.com/license/LICENSE. |
---|
10 | */ |
---|
11 | |
---|
12 | #ifndef __GR1553BC_LIST_H__ |
---|
13 | #define __GR1553BC_LIST_H__ |
---|
14 | |
---|
15 | /*!\file doc/gr1553bc_list.h |
---|
16 | * \brief GR1553B BC driver |
---|
17 | * |
---|
18 | * \section OVERVIEW |
---|
19 | * |
---|
20 | * The BC device driver can schedule synchronous and asynchronous lists |
---|
21 | * of descriptors. The list contains a descriptor table and a software |
---|
22 | * description to make some operations possible, for example translate |
---|
23 | * descriptor-address into descriptor-number. |
---|
24 | * |
---|
25 | * This is the LIST API. It provides functionality to create and manage |
---|
26 | * a BC descriptor list. |
---|
27 | * |
---|
28 | * A list is built up by the following build blocks: |
---|
29 | * - Major Frame (Consists of N Minor Frames) |
---|
30 | * - Minor Frame (Consists of up to 32 1553 Message Slots) |
---|
31 | * - Message Slot (Transfer/Condition BC descriptor) |
---|
32 | * |
---|
33 | * The user can configure lists with different configuration of number of |
---|
34 | * Major Frames, Minor Frame and messages slots within a Minor Frame. The |
---|
35 | * List manages a strait descriptor table (may be changed) and a Frame/Slot |
---|
36 | * tree in order to easily find it's way through all descriptor created. |
---|
37 | * |
---|
38 | * Each Minor frame consist of up to 32 message slot and 2 message slots |
---|
39 | * for time management and descriptor find operations. The list can manage |
---|
40 | * time slots per minor frame, for example a minor frame may be programmed |
---|
41 | * to take 8ms and when the user allocate a message slot within that Minor |
---|
42 | * frame the time spcified will be subtracted from the 8ms, and when the |
---|
43 | * message slot is freed the time will be returned to the Minor frame again. |
---|
44 | * |
---|
45 | * A Major, Minor and Message Slots are identified using a MID (Message-ID). |
---|
46 | * The MID is a way for the user to avoid using pointers are talk with the |
---|
47 | * list API in an easier way. For example a condition Slot that should jump |
---|
48 | * to a transfer slot can be created by knowing "MID and Jump-To-MID". When |
---|
49 | * allocating a Slot (with or without time) the user may specify a certain |
---|
50 | * Slot or a Minor frame, when a Minor frame is given then the API will find |
---|
51 | * a free Slot as early in the Minor Frame as possible and return it to the |
---|
52 | * user. |
---|
53 | * |
---|
54 | * A MID can be created using the macros: |
---|
55 | * GR1553BC_ID(major,minor,slot) - ID of a SLOT |
---|
56 | * GR1553BC_MINOR_ID(major,minor) - ID of a MINOR (Slot=0xff) |
---|
57 | * GR1553BC_MAJOR_ID(major) - ID of a Major (Minor=0xff,Slot=0xff) |
---|
58 | * |
---|
59 | * The typical approach create lists is in the following order: |
---|
60 | * -# gr1553bc_list_alloc(&list, MAJOR_CNT) |
---|
61 | * -# gr1553bc_list_config(list, &listcfg) |
---|
62 | * -# Create all Major Frames and Minor frame, for each major frame: |
---|
63 | * a) gr1553bc_major_alloc_skel(&major, &major_minor_cfg) |
---|
64 | * b) gr1553bc_list_set_major(list, &major, MAJOR_NUM) |
---|
65 | * -# link end Major Frames together: |
---|
66 | * a) gr1553bc_list_set_major(&major7, &major0) // Connect Major frames |
---|
67 | * -# gr1553bc_list_table_alloc() (Allocate Descriptor Table) |
---|
68 | * -# gr1553bc_list_table_build() (Build Descriptor Table from Majors/Minors) |
---|
69 | * -# Allocate and initialize Descriptors pre defined before starting: |
---|
70 | * -## gr1553bc_slot_alloc(list, &MID, TIME_REQUIRED, ..) |
---|
71 | * -## gr1553bc_slot_transfer(MID, ...) |
---|
72 | * -# START BC HARDWARE BY SHCDULING ABOVE LIST |
---|
73 | * -# Operate on List |
---|
74 | * |
---|
75 | * |
---|
76 | * \section bc_list_update Changing a scheduled BC list (during BC-runtime) |
---|
77 | * |
---|
78 | * One can use the INDICATION service to avoid modifying |
---|
79 | * a descriptor currently in use by the BC core. One can also in most cases |
---|
80 | * do descriptor initialization in three steps: Init Descriptor as Dummy |
---|
81 | * with and allocated time (often done before starting/scheduling list), |
---|
82 | * then modify transfer options and data-pointers, then clear the Dummy |
---|
83 | * bit in one atomic data store. This approach will avoid potential races |
---|
84 | * between software has hardware. |
---|
85 | * |
---|
86 | * |
---|
87 | * \section bc_memory_setup Custom Memory Setup |
---|
88 | * |
---|
89 | * For designs where dynamically memory is not an option, or the driver |
---|
90 | * is used on a AMBA-over-PCI bus (where malloc() does not work), the |
---|
91 | * API allows the user to provide custom addresses for descriptor table |
---|
92 | * and object descriptions (lists, major frames, minor frames). Custom |
---|
93 | * descriptor table is probably the most interesting thing for most, it |
---|
94 | * is setup with gr1553bc_list_table_alloc(list, CUSTOM_ADDRESS). |
---|
95 | * |
---|
96 | * Object descriptions are normally allocated during initialization |
---|
97 | * procedure by providing the API with a object configuration, for |
---|
98 | * example a Major Frame configuration enables the API to allocate |
---|
99 | * the software description of a Major Frame with all it's Minor frames. |
---|
100 | * |
---|
101 | * |
---|
102 | * \section major Major Frame |
---|
103 | * |
---|
104 | * Consists of multiple Minor frames. A Major frame may be connected/linked |
---|
105 | * with another Major frame, this will result in a Jump Slot from last |
---|
106 | * Minor frame in the first Major to the first Minor in the second Major. |
---|
107 | * |
---|
108 | * |
---|
109 | * \section minor Minor Frame |
---|
110 | * |
---|
111 | * Consists of up to 32 Message Slots. The services are Time-Management and |
---|
112 | * Slot allocation. |
---|
113 | * |
---|
114 | * Time-Management is optional. |
---|
115 | * |
---|
116 | * Time-Slot-Management can be enabled per Minor frame. A Minor frame can be |
---|
117 | * assigned a time in microseconds. The BC will not continue to the next |
---|
118 | * Minor frame until the time has passed. It is managed by adding an extra |
---|
119 | * Dummy Message Slot with the total minor frame time. Each time a message |
---|
120 | * Slot is allocated (with a certain time: Slot-Time) the Slot-Time will |
---|
121 | * be decremented from the total time of the Minor frame. This way the |
---|
122 | * sum of the Message Slot will always sum up to the total time of the |
---|
123 | * Minor configuration. When a message slot is freed, the Dymmy Message |
---|
124 | * Slot's Slot-Time is incremented with the freed Slot-Time. |
---|
125 | * |
---|
126 | * A Message Slot can be allocated by identifying a specific free Slot |
---|
127 | * by the MID (Message-ID) or by letting the API allocate the first free |
---|
128 | * Slot in the Minor Frame (Set MID Slot-ID to 0xff to identify Minor |
---|
129 | * Frame). |
---|
130 | * |
---|
131 | * |
---|
132 | * \section slot Message Slot |
---|
133 | * |
---|
134 | * The GR1553B BC core supports two Slot (Descriptor) Types: |
---|
135 | * - Transfer descriptor |
---|
136 | * - Condition descriptor (Jump, unconditional-IRQ) |
---|
137 | * |
---|
138 | * See the hardware manual for a detail description of a descriptor (Slot). |
---|
139 | * |
---|
140 | * The BC Core is unaware of lists, it steps through executing each |
---|
141 | * descriptor as the encountered, Conditionals resulting in jumps may |
---|
142 | * let us to create more complex arrangements of buffer descriptos (BDs) |
---|
143 | * which we call list. |
---|
144 | * |
---|
145 | * Transfer BDs (TBDs) may have a time slot assigned, the BC core will wait |
---|
146 | * until the time has expired before executing the next descriptor. Time |
---|
147 | * slots are handled by a Minor frame in the list. |
---|
148 | * |
---|
149 | * A Message Slot is allocated using the gr1553bc_slot_alloc() function, |
---|
150 | * and configured by calling one of the below functions: |
---|
151 | * - gr1553bc_slot_irq_prepare [unconditional IRQ slot] |
---|
152 | * - gr1553bc_slot_jump [unconditional jump] |
---|
153 | * - gr1553bc_slot_exttrig [Dummy transfer, wait for EXTERNAL-TRIGGER] |
---|
154 | * - gr1553bc_slot_transfer [Transfer descriptor] |
---|
155 | * - gr1553bc_slot_empty [Create Dummy Transfer descriptor] |
---|
156 | * - gr1553bc_slot_raw [Custom Descriptor handling] |
---|
157 | * |
---|
158 | * - gr1553bc_slot_dummy [Set existing Transfer descriptor to Dummy] |
---|
159 | * - gr1553bc_slot_update [Update DataPointer|Status of a TBD] |
---|
160 | * |
---|
161 | * |
---|
162 | * \section bc_IRQ Interrupt Handling |
---|
163 | * |
---|
164 | * There are different types of interrupts, Error IRQs or transfer IRQs. The |
---|
165 | * Error IRQs are handled by the driver can a callback function is called. |
---|
166 | * |
---|
167 | * Transfer Descriptors can be programmed to generate interrupt, and |
---|
168 | * condition descriptors can be programmed to generate interrupt |
---|
169 | * unconditionaly (there exists more conditional types). When a Transfer |
---|
170 | * descriptor causes IRQ the general ISR callback of the BC driver is |
---|
171 | * called to let the user handle the interrupt. When a condition descriptor |
---|
172 | * causes an IRQ a custom IRQ handler is called (if assigned). |
---|
173 | * |
---|
174 | * Transfers descriptor IRQ is enabled by configuring the descriptor. |
---|
175 | * |
---|
176 | * The API provides functions for placing unconditional IRQ points anywhere |
---|
177 | * in the list. The order: |
---|
178 | * -# gr1553bc_slot_alloc(&MID, TIME=0, ..) |
---|
179 | * -# gr1553bc_slot_irq_prepare(MID, funcISR, data) |
---|
180 | * -# gr1553bc_slot_irq_enable(MID) |
---|
181 | * |
---|
182 | * \verbatim |
---|
183 | * void funcISR(*bd, *data) |
---|
184 | * { |
---|
185 | * // HANDLE ONE OR MULTIPLE DESCRIPTORS (MULTIPLE IN THIS EXAMPLE): |
---|
186 | * int MID; |
---|
187 | * gr1553bc_mid_from_bd(bd,&MID,NULL); |
---|
188 | * printf("IRQ ON %06x\n", MID); |
---|
189 | * } |
---|
190 | * \endverbatim |
---|
191 | * |
---|
192 | * \ingroup GR1553BC |
---|
193 | */ |
---|
194 | |
---|
195 | #include <stdint.h> |
---|
196 | #include <bsp/gr1553bc.h> |
---|
197 | |
---|
198 | /**** CONFIGURATION OPTIONS ****/ |
---|
199 | |
---|
200 | /* Define GR1553BC_TIMESLOT to make driver take care of time |
---|
201 | * management of minor frames. |
---|
202 | */ |
---|
203 | #define GR1553BC_TIMESLOT |
---|
204 | |
---|
205 | #define GR1553BC_MINOR_MAX 256 |
---|
206 | #define GR1553BC_SLOT_MAX 32 |
---|
207 | |
---|
208 | #ifdef __cplusplus |
---|
209 | extern "C" { |
---|
210 | #endif |
---|
211 | |
---|
212 | struct gr1553bc_list; |
---|
213 | struct gr1553bc_major; |
---|
214 | struct gr1553bc_minor; |
---|
215 | struct gr1553bc_minor_cfg; |
---|
216 | struct gr1553bc_major_cfg; |
---|
217 | |
---|
218 | struct gr1553bc_minor_cfg { |
---|
219 | int slot_cnt; |
---|
220 | int timeslot; /* Total time of minor frame in us */ |
---|
221 | }; |
---|
222 | |
---|
223 | struct gr1553bc_major_cfg { |
---|
224 | int minor_cnt; /* Number of Minor Frames */ |
---|
225 | struct gr1553bc_minor_cfg minor_cfgs[1]; |
---|
226 | }; |
---|
227 | |
---|
228 | struct gr1553bc_list_cfg { |
---|
229 | unsigned char rt_timeout[31]; /* Number of us timeout tolerance per RT */ |
---|
230 | unsigned char bc_timeout; /* Number of us timeout tolerance of |
---|
231 | * broadcast transfers */ |
---|
232 | int tropt_irq_on_err; /* Generate IRQ on transfer error */ |
---|
233 | int tropt_pause_on_err; /* Pause list on transfer error */ |
---|
234 | int async_list; /* Set to non-zero if asyncronous list*/ |
---|
235 | }; |
---|
236 | |
---|
237 | /* Default Configuration */ |
---|
238 | extern struct gr1553bc_list_cfg gr1553bc_def_cfg; |
---|
239 | |
---|
240 | /* Complete list of all major frames */ |
---|
241 | struct gr1553bc_list { |
---|
242 | void *_table_custom; /* Config option given by user */ |
---|
243 | void *_table; /* address of allocated bd-table */ |
---|
244 | unsigned int table_hw; /* Descriptor table base HW-ADR */ |
---|
245 | unsigned int table_cpu; /* Descriptor table base CPU-ADR */ |
---|
246 | int table_size; /* Descriptor Table Size */ |
---|
247 | void *bc; /* BC HW, needed for adr translation */ |
---|
248 | unsigned char rt_timeout[32]; /* Tolerance per RT, default 20us |
---|
249 | * Note: 31 is for Broadcast */ |
---|
250 | uint32_t tropts; /* Transfer descriptor options: |
---|
251 | * On transfer error the following bits |
---|
252 | * do affect: |
---|
253 | * - bit28 1=Generate IRQ |
---|
254 | * - bit26 1=Pause transfer list |
---|
255 | * |
---|
256 | */ |
---|
257 | int async_list; /* async list or not */ |
---|
258 | int major_cnt; /* Number of Major frames */ |
---|
259 | struct gr1553bc_major *majors[1]; /* Var-Array of Major Pointers*/ |
---|
260 | }; |
---|
261 | |
---|
262 | /* Alloc a List with a maximum number of Major frames supported */ |
---|
263 | extern int gr1553bc_list_alloc(struct gr1553bc_list **list, int max_major); |
---|
264 | |
---|
265 | /* Free List if allocated with gr1553bc_list_alloc() */ |
---|
266 | extern void gr1553bc_list_free(struct gr1553bc_list *list); |
---|
267 | |
---|
268 | /* Configure Global List parameters |
---|
269 | * |
---|
270 | * \param list List to be configured and initialized. |
---|
271 | * \param cfg List Configuration |
---|
272 | * \param bc The BC hardware device description |
---|
273 | * (only needed for address translation) |
---|
274 | */ |
---|
275 | extern int gr1553bc_list_config |
---|
276 | ( |
---|
277 | struct gr1553bc_list *list, |
---|
278 | struct gr1553bc_list_cfg *cfg, |
---|
279 | void *bc |
---|
280 | ); |
---|
281 | |
---|
282 | /* Link a 'major' Major frame with next major frame |
---|
283 | * The links affected: |
---|
284 | * - major->next |
---|
285 | * - major->minor[LAST]->next |
---|
286 | */ |
---|
287 | extern void gr1553bc_list_link_major( |
---|
288 | struct gr1553bc_major *major, |
---|
289 | struct gr1553bc_major *next |
---|
290 | ); |
---|
291 | |
---|
292 | /* Link in a Major frame into a BC list. |
---|
293 | * Calls gr1553bc_list_link_major() to link major frame with major-1 and |
---|
294 | * major+1. If ending or starting major frame the frame is wrapped around. |
---|
295 | */ |
---|
296 | extern int gr1553bc_list_set_major( |
---|
297 | struct gr1553bc_list *list, |
---|
298 | struct gr1553bc_major *major, |
---|
299 | int no); |
---|
300 | |
---|
301 | /* Calculate the size required in the descriptor table by one minor frame. */ |
---|
302 | extern int gr1553bc_minor_table_size(struct gr1553bc_minor *minor); |
---|
303 | |
---|
304 | /* Calculate the size required for the descriptor table. |
---|
305 | */ |
---|
306 | extern int gr1553bc_list_table_size(struct gr1553bc_list *list); |
---|
307 | |
---|
308 | /* Allocate an empty descriptor table from list description suitable for |
---|
309 | * the BC given by 'bc'. |
---|
310 | * |
---|
311 | * \param bdtab_custom Custom Descriptor Allocation options: |
---|
312 | * ZERO: Dynamically allocated by Driver (CPU near RAM) |
---|
313 | * Non-Zero: Use provided address as BASE of BD-TABLE |
---|
314 | * Non-Zero with LSB set: Same as Non-Zero but address |
---|
315 | * is given as HW address (used with AMBA-over-PCI to |
---|
316 | * to specify RAM location on PCI board). |
---|
317 | */ |
---|
318 | extern int gr1553bc_list_table_alloc |
---|
319 | ( |
---|
320 | struct gr1553bc_list *list, |
---|
321 | void *bdtab_custom |
---|
322 | ); |
---|
323 | |
---|
324 | /* Free descriptor table allocated with gr1553bc_list_table_alloc() */ |
---|
325 | extern void gr1553bc_list_table_free(struct gr1553bc_list *list); |
---|
326 | |
---|
327 | /* Build an empty descriptor table from list description, |
---|
328 | * the minor frames will be linked together. |
---|
329 | */ |
---|
330 | extern int gr1553bc_list_table_build(struct gr1553bc_list *list); |
---|
331 | |
---|
332 | /* Major Frame */ |
---|
333 | struct gr1553bc_major { |
---|
334 | struct gr1553bc_major *next; /* Next Major Frame */ |
---|
335 | struct gr1553bc_major_cfg *cfg; /* User Config of Major frame */ |
---|
336 | struct gr1553bc_minor *minors[1]; /* Minor frames */ |
---|
337 | }; |
---|
338 | |
---|
339 | /* Minor Frame */ |
---|
340 | struct gr1553bc_minor { |
---|
341 | struct gr1553bc_minor *next; /* Next Minor Frame */ |
---|
342 | struct gr1553bc_minor_cfg *cfg; /* User Config of Minor frame */ |
---|
343 | uint32_t alloc; /* Descripts allocated */ |
---|
344 | |
---|
345 | /* Note: THIS POINTER MUST BE ALIGNED ON A 128-bit BOUNDARY */ |
---|
346 | union gr1553bc_bd *bds; /* Descriptors for this minor frame (CPU ADRS)*/ |
---|
347 | }; |
---|
348 | |
---|
349 | /* Alloc a Major/Minor frame skeleton according to the configuration structure. |
---|
350 | * The descriptor table is not allocated. |
---|
351 | */ |
---|
352 | extern int gr1553bc_major_alloc_skel |
---|
353 | ( |
---|
354 | struct gr1553bc_major **major, |
---|
355 | struct gr1553bc_major_cfg *cfg |
---|
356 | ); |
---|
357 | |
---|
358 | /* Unique Message/Descriptor ID. Can be used to identify a Major or Minor |
---|
359 | * Frame, or a Slot. |
---|
360 | * |
---|
361 | * - If minor_num is 0xff, the ID identifies a Major Frame |
---|
362 | * - If slot_num is 0xff, the ID identifies a Minor Frame |
---|
363 | * - If non of the above is true, the ID identifies a specific Slot |
---|
364 | */ |
---|
365 | #define GR1553BC_ID(major_num, minor_num, slot_num) \ |
---|
366 | ((((major_num)<<16)&0xff0000) | (((minor_num)<<8)&0xff00) | \ |
---|
367 | ((slot_num) & 0xff)) |
---|
368 | #define GR1553BC_MINOR_ID(major_num, minor_num) \ |
---|
369 | GR1553BC_ID(major_num, minor_num, 0xff) |
---|
370 | #define GR1553BC_MAJOR_ID(major_num) \ |
---|
371 | GR1553BC_ID(major_num, 0xff, 0xff) |
---|
372 | |
---|
373 | #define GR1553BC_MAJID_FROM_ID(mid) (((mid) >> 16) & 0xff) |
---|
374 | #define GR1553BC_MINID_FROM_ID(mid) (((mid) >> 8) & 0xff) |
---|
375 | #define GR1553BC_SLOTID_FROM_ID(mid) ((mid) & 0xff) |
---|
376 | #define GR1553BC_ID_SET_SLOT(mid, slot_num) (((mid) & ~0xff) | ((slot_num) & 0xff)) |
---|
377 | |
---|
378 | extern struct gr1553bc_major *gr1553bc_major_from_id |
---|
379 | ( |
---|
380 | struct gr1553bc_list *list, |
---|
381 | int mid |
---|
382 | ); |
---|
383 | |
---|
384 | extern struct gr1553bc_minor *gr1553bc_minor_from_id |
---|
385 | ( |
---|
386 | struct gr1553bc_list *list, |
---|
387 | int mid |
---|
388 | ); |
---|
389 | |
---|
390 | /* Get free time left of minor frame identified by MID 'mid' */ |
---|
391 | extern int gr1553bc_list_freetime(struct gr1553bc_list *list, int mid); |
---|
392 | |
---|
393 | /* Get free time left of minor frame */ |
---|
394 | extern int gr1553bc_minor_freetime(struct gr1553bc_minor *minor); |
---|
395 | |
---|
396 | /* Allocate a time slot on a minor frame, major/minor frame is identified |
---|
397 | * by MID. The 'mid' is a input/ouput parameter, the resulting slot taken |
---|
398 | * will be placed in 'mid', a pointer to the allocated descriptor is stored |
---|
399 | * into bd. |
---|
400 | * |
---|
401 | * Major/Minor must be specified by MID, if slot is specified that slot will |
---|
402 | * be allocated, if slot is 0xff, then the first free slot is allocated. |
---|
403 | * |
---|
404 | * The function fails (return negative) if timeslot is longer than remaining |
---|
405 | * time in minor frame, if no more slots are available in minor frame, if |
---|
406 | * MID points to a bad major/minor or major/minor/slot. |
---|
407 | */ |
---|
408 | extern int gr1553bc_slot_alloc( |
---|
409 | struct gr1553bc_list *list, |
---|
410 | int *mid, |
---|
411 | int timeslot, |
---|
412 | union gr1553bc_bd **bd |
---|
413 | ); |
---|
414 | /* Same as gr1553bc_slot_alloc but identifies a minor instead of list. |
---|
415 | * The major/minor part of MID is ignored. |
---|
416 | */ |
---|
417 | extern int gr1553bc_slot_alloc2( |
---|
418 | struct gr1553bc_minor *minor, |
---|
419 | int *mid, |
---|
420 | int timeslot, |
---|
421 | union gr1553bc_bd **bd |
---|
422 | ); |
---|
423 | |
---|
424 | /* Free message slot and the time associated with it. The time taken by the |
---|
425 | * message slot is added to the END TIME descriptor, if managed by the driver |
---|
426 | * for this minor frame. The descriptor will be |
---|
427 | */ |
---|
428 | extern int gr1553bc_slot_free(struct gr1553bc_list *list, int mid); |
---|
429 | extern int gr1553bc_slot_free2(struct gr1553bc_minor *minor, int mid); |
---|
430 | |
---|
431 | /* Find MID from Descriptor pointer |
---|
432 | * |
---|
433 | * In the end of each minor frame is a unconditional jump |
---|
434 | * to next minor frame descriptor. The hardware does not |
---|
435 | * use the last 8 bytes of conditional descriptors, in the |
---|
436 | * padding area a MID is stored so that we can lookup the |
---|
437 | * MID of a descriptor. This function finds the jump |
---|
438 | * descriptor and subtracs the offset from it. |
---|
439 | * |
---|
440 | * A faster way of looking up can be implemented if the |
---|
441 | * list is symertical, however in the current setup we |
---|
442 | * allow different numbers of slots in minor frames, and |
---|
443 | * different number of minor frames in a major frame. |
---|
444 | * |
---|
445 | * \param bd IN: Descriptor to lookup MID of (CPU address of BD) |
---|
446 | * \param mid OUT: Pointer to where Message-ID (Slot-ID) will be stored |
---|
447 | * \param async OUT: Function will store non-zero value if BD belogs to |
---|
448 | * async list. |
---|
449 | */ |
---|
450 | extern int gr1553bc_mid_from_bd( |
---|
451 | union gr1553bc_bd *bd, |
---|
452 | int *mid, |
---|
453 | int *async |
---|
454 | ); |
---|
455 | |
---|
456 | /********** TRANSFER DESCRIPTOR MANIPULATION **********/ |
---|
457 | |
---|
458 | /* Get pointer to descriptor entry from MID. */ |
---|
459 | extern union gr1553bc_bd *gr1553bc_slot_bd |
---|
460 | ( |
---|
461 | struct gr1553bc_list *list, |
---|
462 | int mid |
---|
463 | ); |
---|
464 | |
---|
465 | /* IRQ function */ |
---|
466 | typedef void (*bcirq_func_t)(union gr1553bc_bd *bd, void *data); |
---|
467 | |
---|
468 | /* Create unconditional IRQ customly defined location. |
---|
469 | * The IRQ is disabled, enable it with gr1553bc_slot_irq_enable(). |
---|
470 | */ |
---|
471 | extern int gr1553bc_slot_irq_prepare |
---|
472 | ( |
---|
473 | struct gr1553bc_list *list, |
---|
474 | int mid, |
---|
475 | bcirq_func_t func, |
---|
476 | void *data |
---|
477 | ); |
---|
478 | |
---|
479 | /* Enable previously prepared unconditional IRQ */ |
---|
480 | extern int gr1553bc_slot_irq_enable(struct gr1553bc_list *list, int mid); |
---|
481 | |
---|
482 | /* Disable unconditional IRQ point, changed to unconditional JUMP |
---|
483 | * to descriptor following. |
---|
484 | * After disabling it it can be enabled again, or freed. |
---|
485 | */ |
---|
486 | extern int gr1553bc_slot_irq_disable(struct gr1553bc_list *list, int mid); |
---|
487 | |
---|
488 | /* Create custom jump to descriptor, conditional or unconditional, see |
---|
489 | * hardware manual for conditions. |
---|
490 | * |
---|
491 | * set conditional to GR1553BC_UNCOND_JMP for unconditional jump. |
---|
492 | */ |
---|
493 | extern int gr1553bc_slot_jump |
---|
494 | ( |
---|
495 | struct gr1553bc_list *list, |
---|
496 | int mid, |
---|
497 | uint32_t condition, |
---|
498 | int to_mid |
---|
499 | ); |
---|
500 | |
---|
501 | /* Create a dummy transfer, paused until external trigger is set. The |
---|
502 | * Slot is will have the dummy bit set, no transfer will take place. |
---|
503 | */ |
---|
504 | extern int gr1553bc_slot_exttrig(struct gr1553bc_list *list, int mid); |
---|
505 | |
---|
506 | /* Create a transfer on a previous allocated descriptor. It is assumed |
---|
507 | * that the descriptor has been initialized empty before calling this |
---|
508 | * function, this is to avoid races. |
---|
509 | * |
---|
510 | * The settings that are controlled on a global level (and not |
---|
511 | * by this function): |
---|
512 | * - IRQ after transfer error |
---|
513 | * - IRQ after transfer (not supported, insert separate IRQ slot after this) |
---|
514 | * - Pause schedule after transfer error |
---|
515 | * - Pause schedule after transfer (not supported) |
---|
516 | * - slot time optional (set when MID allocated), otherwise 0 |
---|
517 | * - (OPTIONAL) Dummy Bit, set using slot_empty() or ..._TT_DUMMY |
---|
518 | * - RT timeout tolerance (managed per RT) |
---|
519 | * |
---|
520 | * Input Parameters: |
---|
521 | * - Retry Mode (options) |
---|
522 | * - Number of retires (options) |
---|
523 | * - Bus selection (A or B) (options) |
---|
524 | * - dummy bit (options) |
---|
525 | * - transfer type (tt) |
---|
526 | * - rt src/dst address (tt) |
---|
527 | * - RT subaddress (tt) |
---|
528 | * - word count (tt) |
---|
529 | * - mode code (tt) |
---|
530 | * - data pointer (dptr) |
---|
531 | * |
---|
532 | * |
---|
533 | * See macros defined in this header file for creating transfer types (tt) |
---|
534 | * and word count etc. |
---|
535 | * |
---|
536 | * See macros defined in this header file for creating the mask of options. |
---|
537 | * |
---|
538 | * Note that if bit0 (LSB) of dptr is set, then the address is translated into |
---|
539 | * hardware address, otherwise the dptr is assumed to be accessible from the |
---|
540 | * 1553 core. This is an option only for AMBA-over-PCI. |
---|
541 | */ |
---|
542 | extern int gr1553bc_slot_transfer( |
---|
543 | struct gr1553bc_list *list, |
---|
544 | int mid, |
---|
545 | int options, |
---|
546 | int tt, |
---|
547 | uint16_t *dptr); |
---|
548 | |
---|
549 | /* Remove or set dummy bit of a transfer descriptor |
---|
550 | * Bit31 of *dummy is written to the dummy bit, the |
---|
551 | * old descriptor value is stored into *dummy. |
---|
552 | */ |
---|
553 | extern int gr1553bc_slot_dummy( |
---|
554 | struct gr1553bc_list *list, |
---|
555 | int mid, |
---|
556 | unsigned int *dummy); |
---|
557 | |
---|
558 | /* Make a slot empty (BC will not generate bus transfers), time slot |
---|
559 | * allocated is untouched (if assigned). |
---|
560 | */ |
---|
561 | extern int gr1553bc_slot_empty(struct gr1553bc_list *list, int mid); |
---|
562 | |
---|
563 | /* Transfer descriptor status and/or update Transfer descriptor data pointer. |
---|
564 | * |
---|
565 | * Read and/or write Status of a slot. Writing the status word may be |
---|
566 | * used by software to indicate that result has been handled, or bit 31 |
---|
567 | * may be written 1 telling software that when it reaches 0, then BC |
---|
568 | * has executed the request. |
---|
569 | * |
---|
570 | * Operation: |
---|
571 | * bd->status = *stat & (bd->status 0xffffff) | (*stat & 0x80000000); |
---|
572 | * *stat = Value of bd->status before rewrite. |
---|
573 | * |
---|
574 | * Note that the status word is not written when *stat is zero. |
---|
575 | * |
---|
576 | * Note that if bit0 (LSB) of dptr is set, then the address is translated into |
---|
577 | * hardware address, otherwise the dptr is assumed to be accessible from the |
---|
578 | * 1553 core. This is an option only for AMBA-over-PCI. |
---|
579 | */ |
---|
580 | extern int gr1553bc_slot_update( |
---|
581 | struct gr1553bc_list *list, |
---|
582 | int mid, |
---|
583 | uint16_t *dptr, |
---|
584 | unsigned int *stat); |
---|
585 | |
---|
586 | /* Modify a transfer descriptor in any way, |
---|
587 | * |
---|
588 | * flags: |
---|
589 | * bit[N=0..3]: 1 = set BD wordN according to argument wordN, |
---|
590 | * 0 = do not modify BD wordN |
---|
591 | */ |
---|
592 | extern int gr1553bc_slot_raw |
---|
593 | ( |
---|
594 | struct gr1553bc_list *list, |
---|
595 | int mid, |
---|
596 | unsigned int flags, |
---|
597 | uint32_t word0, |
---|
598 | uint32_t word1, |
---|
599 | uint32_t word2, |
---|
600 | uint32_t word3 |
---|
601 | ); |
---|
602 | |
---|
603 | |
---|
604 | /***** Macros to create BC Transfer Types (tt) for gr1553bc_slot_transfer() *****/ |
---|
605 | |
---|
606 | /* WRITE TO RT (BC-to-RT) */ |
---|
607 | #define GR1553BC_BC2RT(rtadr, subadr, word_count) \ |
---|
608 | ((rtadr<<11) | (subadr<<5) | (0x1f<<21) | (0<<10) | \ |
---|
609 | ((word_count>=32) ? 0 : word_count)) |
---|
610 | |
---|
611 | /* READ FROM RT (RT-to-BC) */ |
---|
612 | #define GR1553BC_RT2BC(rtadr, subadr, word_count) \ |
---|
613 | ((rtadr<<11) | (subadr<<5) | (0x1f<<21) | (1<<10) | \ |
---|
614 | ((word_count>=32) ? 0 : word_count)) |
---|
615 | |
---|
616 | /* RT(TX) WRITE TO RT(RX) (RT-to-RT) */ |
---|
617 | #define GR1553BC_RT2RT(tx_rtadr, tx_subadr, rx_rtadr, rx_subadr, word_count) \ |
---|
618 | ((rx_rtadr<<11) | (rx_subadr<<5) | \ |
---|
619 | (tx_rtadr<<21) | (tx_subadr<<16) | \ |
---|
620 | (0<<10) | \ |
---|
621 | ((word_count>=32) ? 0 : word_count)) |
---|
622 | |
---|
623 | /* Mode command without data. (BC-to-RT) |
---|
624 | * Mode code: 0,1,2,3,4,5,6,7 or 8. |
---|
625 | */ |
---|
626 | #define GR1553BC_MC_NODATA(rtadr, modecode) \ |
---|
627 | ((rtadr<<11) | (0x1f<<5) | (0x1f<<21) | \ |
---|
628 | (modecode<<0) | (1<<10)) |
---|
629 | |
---|
630 | /* Mode command with 4 byte data (RT-to-BC) |
---|
631 | * Mode code: 16, 18 or 19. |
---|
632 | */ |
---|
633 | #define GR1553BC_MC_RT2BC(rtadr, modecode) \ |
---|
634 | ((rtadr<<11) | (0x1f<<5) | (0x1f<<21) | \ |
---|
635 | (modecode<<0) | (1<<10)) |
---|
636 | |
---|
637 | /* Mode command with 4 byte data (BC-to-RT) |
---|
638 | * Mode code: 17, 20 or 21. |
---|
639 | */ |
---|
640 | #define GR1553BC_MC_BC2RT(rtadr, modecode) \ |
---|
641 | ((rtadr<<11) | (0x1f<<5) | (0x1f<<21) | \ |
---|
642 | (modecode<<0) | (0<<10)) |
---|
643 | |
---|
644 | /* Broadcast to all RTs, to a specific subaddress (BC-to-RTs) */ |
---|
645 | #define GR1553BC_BC_BC2RT(subadr, word_count) \ |
---|
646 | ((0x1f<<11) | (subadr<<5) | (0x1f<<21) | \ |
---|
647 | (0<<10) | \ |
---|
648 | ((word_count>=32) ? 0 : word_count)) |
---|
649 | |
---|
650 | /* Request RT to broadcast to all RTs, to a specific subaddress (RT-to-RTs) */ |
---|
651 | #define GR1553BC_BC_RT2RT(tx_rtadr, tx_subadr, rx_subadr, word_count) \ |
---|
652 | ((0x1f<<11) | (rx_subadr<<5) | \ |
---|
653 | (tx_rtadr<<21) | (tx_subadr<<16) | \ |
---|
654 | (0<<10) | \ |
---|
655 | ((word_count>=32) ? 0 : word_count)) |
---|
656 | |
---|
657 | /* Broadcast mode command without data (BC-to-RTs) |
---|
658 | * Mode code: 1,3,4,5,6,7 or 8 |
---|
659 | */ |
---|
660 | #define GR1553BC_BC_MC_NODATA(modecode) \ |
---|
661 | ((0x1f<<11) | (0x1f<<5) | (0x1f<<21) | \ |
---|
662 | ((modecode)<<0) | (1<<10)) |
---|
663 | |
---|
664 | /* Broadcast mode command with 4 byte data (BC-to-RTs) |
---|
665 | * Mode code: 17, 20 or 21 |
---|
666 | */ |
---|
667 | #define GR1553BC_BC_MC_BC2RT(modecode) \ |
---|
668 | ((0x1f<<11) | (0x1f<<5) | (0x1f<<21) | \ |
---|
669 | ((modecode)<<0) | (0<<10)) |
---|
670 | |
---|
671 | |
---|
672 | /***** Macros to create BC options (options) for gr1553bc_slot_transfer() *****/ |
---|
673 | |
---|
674 | /* Dummy (BC does no bus trasactions) */ |
---|
675 | #define GR1553BC_OPT_DUMMY (1<<1) |
---|
676 | |
---|
677 | /* Retry modes */ |
---|
678 | #define GR1553BC_RETRY_SAME 0x0 /* Retry on the same bus only */ |
---|
679 | #define GR1553BC_RETRY_ALTER 0x1 /* Retry alternating on both busses */ |
---|
680 | #define GR1553BC_RETRY_ATTEMPT 0x2 /* Many attepts first on original |
---|
681 | * bus then on other bus */ |
---|
682 | /* Number of retires supported */ |
---|
683 | #define GR1553BC_RETRY_CNT_MAX 6 |
---|
684 | |
---|
685 | /* Dummy bit: No transfer |
---|
686 | * Bus bit: 0=A, 1=B |
---|
687 | * Exttrig bit: Wait for external trigger (used for timesync) |
---|
688 | * Exclusive bit: 1=Don't allow other messages in this time slot. |
---|
689 | */ |
---|
690 | #define GR1553BC_OPTIONS(dummy, exttrig, exclusive, retrymode, nretry, bus) \ |
---|
691 | ((((exttrig) & 0x1) << 30) | (((exclusive) & 0x1) << 29) | \ |
---|
692 | ((retrymode) << 23) | ((nretry) << 20) | \ |
---|
693 | ((bus) & 1) | (((dummy) & 0x1) << 1)) |
---|
694 | |
---|
695 | #define GR1553BC_OPTIONS_BUSA GR1553BC_OPTIONS(0,0,0,GR1553BC_RETRY_SAME,0,0) |
---|
696 | #define GR1553BC_OPTIONS_BUSB GR1553BC_OPTIONS(0,0,0,GR1553BC_RETRY_SAME,0,1) |
---|
697 | #define GR1553BC_OPTIONS_BUSA_DUM GR1553BC_OPTIONS(1,0,0,GR1553BC_RETRY_SAME,0,0) |
---|
698 | #define GR1553BC_OPTIONS_BUSB_DUM GR1553BC_OPTIONS(1,0,0,GR1553BC_RETRY_SAME,0,1) |
---|
699 | |
---|
700 | /* Show parts of a list - this is for debugging only */ |
---|
701 | extern void gr1553bc_show_list(struct gr1553bc_list *list, int options); |
---|
702 | |
---|
703 | #ifdef __cplusplus |
---|
704 | } |
---|
705 | #endif |
---|
706 | |
---|
707 | #endif /* __GR1553BC_LIST_H__ */ |
---|