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