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