xref: /freebsd/share/man/man9/microseq.9 (revision 5d70612b3f814f934494f69876a4b34e13c436f9)
1.\" Copyright (c) 1998, 1999, Nicolas Souchu
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
25.\"
26.Dd June 6, 1998
27.Dt MICROSEQ 9
28.Os FreeBSD
29.Sh NAME
30.Nm microseq
31.Nd
32ppbus microseqencer developer's guide
33.Sh SYNOPSIS
34.Fd "#include <sys/types.h>"
35.Fd "#include <dev/ppbus/ppbconf.h>"
36.Fd "#include <dev/ppbus/ppb_msq.h>"
37.Sh DESCRIPTION
38See
39.Xr ppbus 4
40for ppbus description and general info about the microsequencer.
41.Pp
42The purpose of this document is to encourage developers to use the
43microsequencer mechanism in order to have:
44.Bl -enum -offset indent
45.It
46a uniform programming model
47.It
48efficient code
49.El
50.Pp
51Before using microsequences, you are encouraged to look at
52.Xr ppc 4
53microsequencer implementation and an example of how using it in
54.Xr vpo 4 .
55.Sh PPBUS register model
56.Ss Background
57The parallel port model chosen for ppbus is the PC parallel port model.
58Thus, any register described later has the same semantic than its counterpart
59in a PC parallel port. For more info about ISA/ECP programming, get the
60Microsoft standard referenced as "Extended Capabilities Port Protocol and
61ISA interface Standard". Registers described later are standard parallel port
62registers.
63.Pp
64Mask macros are defined in the standard ppbus include files for each valid
65bit of parallel port registers.
66.Ss Data register
67In compatible or nibble mode, writing to this register will drive data to the
68parallel port data lines. In any other mode, drivers may be tri-stated by
69setting the direction bit (PCD) in the control register. Reads to this register
70return the value on the data lines.
71.Ss Device status register
72This read-only register reflects the inputs on the parallel port interface.
73.Pp
74.Bl -column "Bit" "Name" "Description" -compact
75.It Em Bit Ta Em Name Ta Em Description
76.It 7 Ta nBUSY Ta "inverted version of parallel port Busy signal"
77.It 6 Ta nACK Ta "version of parallel port nAck signal"
78.It 5 Ta PERROR Ta "version of parallel port PERROR signal"
79.It 4 Ta SELECT Ta "version of parallel port Select signal"
80.It 3 Ta nFAULT Ta "version of parallel port nFault signal"
81.El
82.Pp
83Others are reserved and return undefined result when read.
84.Ss Device control register
85This register directly controls several output signals as well as enabling
86some functions.
87.Pp
88.Bl -column "Bit" "Name    " "Description" -compact
89.It Em Bit Ta Em Name Ta Em Description
90.It 5 Ta PCD Ta "direction bit in extended modes"
91.It 4 Ta IRQENABLE Ta "1 enables an interrupt on the rising edge of nAck"
92.It 3 Ta SELECTIN Ta "inverted and driven as parallel port nSelectin signal"
93.It 2 Ta nINIT Ta "driven as parallel port nInit signal"
94.It 1 Ta AUTOFEED Ta "inverted and driven as parallel port nAutoFd signal"
95.It 0 Ta STROBE Ta "inverted and driven as parallel port nStrobe signal"
96.El
97.Sh MICROINSTRUCTIONS
98.Ss Description
99.Em Microinstructions
100are either parallel port accesses, program iterations, submicrosequence or
101C calls. The parallel port must be considered as the logical model described in
102.Xr ppbus 4 .
103.Pp
104Available microinstructions are:
105.Bd -literal
106#define MS_OP_GET       0	/* get <ptr>, <len>			*/
107#define MS_OP_PUT       1	/* put <ptr>, <len>			*/
108#define MS_OP_RFETCH	2	/* rfetch <reg>, <mask>, <ptr>		*/
109#define MS_OP_RSET	3	/* rset <reg>, <mask>, <mask>		*/
110#define MS_OP_RASSERT	4	/* rassert <reg>, <mask>		*/
111#define MS_OP_DELAY     5	/* delay <val>				*/
112#define MS_OP_SET       6	/* set <val>				*/
113#define MS_OP_DBRA      7	/* dbra <offset>			*/
114#define MS_OP_BRSET     8	/* brset <mask>, <offset>		*/
115#define MS_OP_BRCLEAR   9	/* brclear <mask>, <offset>		*/
116#define MS_OP_RET       10	/* ret <retcode>			*/
117#define MS_OP_C_CALL	11	/* c_call <function>, <parameter>	*/
118#define MS_OP_PTR	12	/* ptr <pointer>			*/
119#define MS_OP_ADELAY	13	/* adelay <val>				*/
120#define MS_OP_BRSTAT	14	/* brstat <mask>, <mask>, <offset>	*/
121#define MS_OP_SUBRET	15	/* subret <code>			*/
122#define MS_OP_CALL	16	/* call <microsequence>			*/
123#define MS_OP_RASSERT_P	17	/* rassert_p <iter>, <reg>		*/
124#define MS_OP_RFETCH_P	18	/* rfetch_p <iter>, <reg>, <mask>	*/
125#define MS_OP_TRIG	19	/* trigger <reg>, <len>, <array>	*/
126.Ed
127.Ss Execution context
128The
129.Em execution context
130of microinstructions is:
131.Bl -bullet -item -offset indent
132.It
133the
134.Em program counter
135which points to the next microinstruction to execute either in the main
136microsequence or in a subcall
137.It
138the current value of
139.Em ptr
140which points to the next char to send/receive
141.It
142the current value of the internal
143.Em branch register
144.El
145.Pp
146This data is modified by some of the microinstructions, not all.
147.Ss MS_OP_GET and MS_OP_PUT
148are microinstructions used to do either predefined standard IEEE1284-1994
149transfers or programmed non-standard io.
150.Ss MS_OP_RFETCH - Register FETCH
151is used to retrieve the current value of a parallel port register, apply a
152mask and save it in a buffer.
153.Pp
154Parameters:
155.Bl -enum -offset indent
156.It
157register
158.It
159character mask
160.It
161pointer to the buffer
162.El
163.Pp
164Predefined macro: MS_RFETCH(reg,mask,ptr)
165.Ss MS_OP_RSET - Register SET
166is used to assert/clear some bits of a particular parallel port register,
167two masks are applied.
168.Pp
169Parameters:
170.Bl -enum -offset ident
171.It
172register
173.It
174mask of bits to assert
175.It
176mask of bits to clear
177.El
178.Pp
179Predefined macro: MS_RSET(reg,assert,clear)
180.Ss MS_OP_RASSERT - Register ASSERT
181is used to assert all bits of a particular parallel port register.
182.Pp
183Parameters:
184.Bl -enum -offset ident
185.It
186register
187.It
188byte to assert
189.El
190.Pp
191Predefined macro: MS_RASSERT(reg,byte)
192.Ss MS_OP_DELAY - microsecond DELAY
193is used to delay the execution of the microsequence.
194.Pp
195Parameter:
196.Bl -enum -offset ident
197.It
198delay in microseconds
199.El
200.Pp
201Predefined macro: MS_DELAY(delay)
202.Ss MS_OP_SET - SET internal branch register
203is used to set the value of the internal branch register.
204.Pp
205Parameter:
206.Bl -enum -offset ident
207.It
208integer value
209.El
210.Pp
211Predefined macro: MS_SET(accum)
212.Ss MS_OP_DBRA - Do BRAnch
213is used to branch if internal branch register decremented by one result value
214is positive.
215.Pp
216Parameter:
217.Bl -enum -offset ident
218.It
219integer offset in the current executed (sub)microsequence. Offset is added to
220the index of the next microinstruction to execute.
221.El
222.Pp
223Predefined macro: MS_DBRA(offset)
224.Ss MS_OP_BRSET - BRanch on SET
225is used to branch if some of the status register bits of the parallel port
226are set.
227.Pp
228Parameter:
229.Bl -enum -offset ident
230.It
231bits of the status register
232.It
233integer offset in the current executed (sub)microsequence. Offset is added to
234the index of the next microinstruction to execute.
235.El
236.Pp
237Predefined macro: MS_BRSET(mask,offset)
238.Ss MS_OP_BRCLEAR - BRanch on CLEAR
239is used to branch if some of the status register bits of the parallel port
240are cleared.
241.Pp
242Parameter:
243.Bl -enum -offset ident
244.It
245bits of the status register
246.It
247integer offset in the current executed (sub)microsequence. Offset is added to
248the index of the next microinstruction to execute.
249.El
250.Pp
251Predefined macro: MS_BRCLEAR(mask,offset)
252.Ss MS_OP_RET - RETurn
253is used to return from a microsequence. This instruction is mandatory. This
254is the only way for the microsequencer to detect the end of the microsequence.
255The return code is returned in the integer pointed by the (int *) parameter
256of the ppb_MS_microseq().
257.Pp
258Parameter:
259.Bl -enum -offset ident
260.It
261integer return code
262.El
263.Pp
264Predefined macro: MS_RET(code)
265.Ss MS_OP_C_CALL - C function CALL
266is used to call C functions from microsequence execution. This may be useful
267when a non-standard i/o is performed to retrieve a data character from the
268parallel port.
269.Pp
270Parameter:
271.Bl -enum -offset ident
272.It
273the C function to call
274.It
275the parameter to pass to the function call
276.El
277.Pp
278The C function shall be declared as a
279.Fd int(*)(void *p, char *ptr)
280The ptr parameter is the current position in the buffer currently scanned.
281.Pp
282Predefined macro: MS_C_CALL(func,param)
283.Ss MS_OP_PTR - initialize internal PTR
284is used to initialize the internal pointer to the currently scanned buffer.
285This pointer is passed to any C call (see above).
286.Pp
287Parameter:
288.Bl -enum -offset ident
289.It
290pointer to the buffer that shall be accessed by xxx_P() microsequence calls.
291Note that this pointer is automatically incremented during xxx_P() calls
292.El
293.Pp
294Predefined macro: MS_PTR(ptr)
295.Ss MS_OP_ADELAY - do an Asynchronous DELAY
296is used to make a tsleep() during microsequence execution. The tsleep is
297executed at PPBPRI level.
298.Pp
299Parameter:
300.Bl -enum -offset ident
301.It
302delay in ms
303.El
304.Pp
305Predefined macro: MS_ADELAY(delay)
306.Ss MS_OP_BRSTAT - BRanch on STATe
307is used to branch on status register state condition.
308.Pp
309Parameter:
310.Bl -enum -offset ident
311.It
312mask of asserted bits. Bits that shall be asserted in the status register
313are set in the mask
314.It
315mask of cleared bits. Bits that shall be cleared in the status register
316are set in the mask
317.It
318integer offset in the current executed (sub)microsequence. Offset is added
319to the index of the next microinstruction to execute.
320.El
321.Pp
322Predefined macro: MS_BRSTAT(asserted_bits,clear_bits,offset)
323.Ss MS_OP_SUBRET - SUBmicrosequence RETurn
324is used to return from the submicrosequence call. This action is mandatory
325before a RET call. Some microinstructions (PUT, GET) may not be callable
326within a submicrosequence.
327.Pp
328No parameter.
329.Pp
330Predefined macro: MS_SUBRET()
331.Ss MS_OP_CALL - submicrosequence CALL
332is used to call a submicrosequence. A submicrosequence is a microsequence with
333a SUBRET call.
334Parameter:
335.Bl -enum -offset ident
336.It
337the submicrosequence to execute
338.El
339.Pp
340Predefined macro: MS_CALL(microseq)
341.Ss MS_OP_RASSERT_P - Register ASSERT from internal PTR
342is used to assert a register with data currently pointed by the internal PTR
343pointer.
344Parameter:
345.Bl -enum -offset ident
346.It
347amount of data to write to the register
348.It
349register
350.El
351.Pp
352Predefined macro: MS_RASSERT_P(iter,reg)
353.Ss MS_OP_RFETCH_P - Register FETCH to internal PTR
354is used to fetch data from a register. Data is stored in the buffer currently
355pointed by the internal PTR pointer.
356Parameter:
357.Bl -enum -offset ident
358.It
359amount of data to read from the register
360.It
361register
362.It
363mask applied to fetched data
364.El
365.Pp
366Predefined macro: MS_RFETCH_P(iter,reg,mask)
367.Ss MS_OP_TRIG - TRIG register
368is used to trigger the parallel port. This microinstruction is intended to
369provide a very efficient control of the parallel port. Triggering a register
370is writing data, wait a while, write data, wait a while... This allows to
371write magic sequences to the port.
372Parameter:
373.Bl -enum -offset ident
374.It
375amount of data to read from the register
376.It
377register
378.It
379size of the array
380.It
381array of unsigned chars. Each couple of u_chars define the data to write to
382the register and the delay in us to wait. The delay is limited to 255 us to
383simplify and reduce the size of the array.
384.El
385.Pp
386Predefined macro: MS_TRIG(reg,len,array)
387.Sh MICROSEQUENCES
388.Ss C structures
389.Bd -literal
390union ppb_insarg {
391     int     i;
392     char    c;
393     void    *p;
394     int     (* f)(void *, char *);
395};
396
397struct ppb_microseq {
398     int                     opcode;         /* microins. opcode */
399     union ppb_insarg        arg[PPB_MS_MAXARGS];    /* arguments */
400};
401.Ed
402.Ss Using microsequences
403To instantiate a microsequence, just declare an array of ppb_microseq
404structures and initialize it as needed. You may either use predefined macros
405or code directly your microinstructions according to the ppb_microseq
406definition. For example,
407.Bd -literal
408     struct ppb_microseq select_microseq[] = {
409
410	     /* parameter list
411	      */
412	     #define SELECT_TARGET    MS_PARAM(0, 1, MS_TYP_INT)
413	     #define SELECT_INITIATOR MS_PARAM(3, 1, MS_TYP_INT)
414
415	     /* send the select command to the drive */
416	     MS_DASS(MS_UNKNOWN),
417	     MS_CASS(H_nAUTO | H_nSELIN |  H_INIT | H_STROBE),
418	     MS_CASS( H_AUTO | H_nSELIN |  H_INIT | H_STROBE),
419	     MS_DASS(MS_UNKNOWN),
420	     MS_CASS( H_AUTO | H_nSELIN | H_nINIT | H_STROBE),
421
422	     /* now, wait until the drive is ready */
423	     MS_SET(VP0_SELTMO),
424/* loop: */     MS_BRSET(H_ACK, 2 /* ready */),
425	     MS_DBRA(-2 /* loop */),
426/* error: */    MS_RET(1),
427/* ready: */    MS_RET(0)
428     };
429.Ed
430.Pp
431Here, some parameters are undefined and must be filled before executing
432the microsequence. In order to initialize each microsequence, one
433should use the ppb_MS_init_msq() function like this:
434.Bd -literal
435     ppb_MS_init_msq(select_microseq, 2,
436		     SELECT_TARGET, 1 << target,
437		     SELECT_INITIATOR, 1 << initiator);
438.Ed
439.Pp
440and then execute the microsequence.
441.Ss The microsequencer
442The microsequencer is executed either at ppbus or adapter level (see
443.Xr ppbus 4
444for info about ppbus system layers). Most of the microsequencer is executed
445at ppc level to avoid ppbus to adapter function call overhead. But some
446actions like deciding whereas the transfer is IEEE1284-1994 compliant are
447executed at ppbus layer.
448.Sh BUGS
449Only one level of submicrosequences is allowed.
450.Pp
451When triggering the port, maximum delay allowed is 255 us.
452.Sh SEE ALSO
453.Xr ppbus 4 ,
454.Xr ppc 4 ,
455.Xr vpo 4
456.Sh HISTORY
457The
458.Nm
459manual page first appeared in
460.Fx 3.0 .
461.Sh AUTHOR
462This
463manual page was written by
464.An Nicolas Souchu .
465