1.\" $NetBSD: microseq.9,v 1.6 2017/07/03 21:28:48 wiz 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 <ptr>, <len> */ 118#define MS_OP_PUT 1 /* put <ptr>, <len> */ 119#define MS_OP_RFETCH 2 /* rfetch <reg>, <mask>, <ptr> */ 120#define MS_OP_RSET 3 /* rset <reg>, <mask>, <mask> */ 121#define MS_OP_RASSERT 4 /* rassert <reg>, <mask> */ 122#define MS_OP_DELAY 5 /* delay <val> */ 123#define MS_OP_SET 6 /* set <val> */ 124#define MS_OP_DBRA 7 /* dbra <offset> */ 125#define MS_OP_BRSET 8 /* brset <mask>, <offset> */ 126#define MS_OP_BRCLEAR 9 /* brclear <mask>, <offset> */ 127#define MS_OP_RET 10 /* ret <retcode> */ 128#define MS_OP_C_CALL 11 /* c_call <function>, <parameter> */ 129#define MS_OP_PTR 12 /* ptr <pointer> */ 130#define MS_OP_ADELAY 13 /* adelay <val> */ 131#define MS_OP_BRSTAT 14 /* brstat <mask>, <mask>, <offset> */ 132#define MS_OP_SUBRET 15 /* subret <code> */ 133#define MS_OP_CALL 16 /* call <microsequence> */ 134#define MS_OP_RASSERT_P 17 /* rassert_p <iter>, <reg> */ 135#define MS_OP_RFETCH_P 18 /* rfetch_p <iter>, <reg>, <mask> */ 136#define MS_OP_TRIG 19 /* trigger <reg>, <len>, <array> */ 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 - \&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 cv_timedwait 9 320during microsequence execution. 321.Pp 322Parameter: 323.Bl -enum -offset indent 324.It 325delay in ms 326.El 327.Pp 328Predefined macro: MS_ADELAY(delay) 329.Ss MS_OP_BRSTAT - BRanch on STATe 330is used to branch on status register state condition. 331.Pp 332Parameter: 333.Bl -enum -offset indent 334.It 335mask of asserted bits. 336Bits that shall be asserted in the status register 337are set in the mask 338.It 339mask of cleared bits. 340Bits that shall be cleared in the status register 341are set in the mask 342.It 343integer offset in the current executed (sub)microsequence. 344Offset is added 345to the index of the next microinstruction to execute. 346.El 347.Pp 348Predefined macro: MS_BRSTAT(asserted_bits,clear_bits,offset) 349.Ss MS_OP_SUBRET - SUBmicrosequence RETurn 350is used to return from the submicrosequence call. 351This action is mandatory before a RET call. 352Some microinstructions (PUT, GET) may not be callable 353within a submicrosequence. 354.Pp 355No parameter. 356.Pp 357Predefined macro: MS_SUBRET() 358.Ss MS_OP_CALL - submicrosequence CALL 359is used to call a submicrosequence. 360A submicrosequence is a microsequence with a SUBRET call. 361Parameter: 362.Bl -enum -offset indent 363.It 364the submicrosequence to execute 365.El 366.Pp 367Predefined macro: MS_CALL(microseq) 368.Ss MS_OP_RASSERT_P - Register ASSERT from internal PTR 369is used to assert a register with data currently pointed by the 370internal PTR pointer. 371Parameter: 372.Bl -enum -offset indent 373.It 374amount of data to write to the register 375.It 376register 377.El 378.Pp 379Predefined macro: MS_RASSERT_P(iter,reg) 380.Ss MS_OP_RFETCH_P - Register FETCH to internal PTR 381is used to fetch data from a register. 382Data is stored in the buffer currently pointed by the internal PTR 383pointer. 384Parameter: 385.Bl -enum -offset indent 386.It 387amount of data to read from the register 388.It 389register 390.It 391mask applied to fetched data 392.El 393.Pp 394Predefined macro: MS_RFETCH_P(iter,reg,mask) 395.Ss MS_OP_TRIG - TRIG register 396is used to trigger the parallel port. 397This microinstruction is intended to provide a very efficient 398control of the parallel port. 399Triggering a register is writing data, wait a while, write data, 400wait a while... 401This allows to write magic sequences to the port. 402Parameter: 403.Bl -enum -offset indent 404.It 405amount of data to read from the register 406.It 407register 408.It 409size of the array 410.It 411array of unsigned chars. 412Each couple of u_chars define the data to write to the register 413and the delay in us to wait. 414The delay is limited to 255 us to simplify and reduce the size of 415the array. 416.El 417.Pp 418Predefined macro: MS_TRIG(reg,len,array) 419.Sh MICROSEQUENCES 420.Ss C structures 421.Bd -literal 422union ppb_insarg { 423 int i; 424 char c; 425 void *p; 426 int (* f)(void *, char *); 427}; 428 429struct ppb_microseq { 430 int opcode; /* microins. opcode */ 431 union ppb_insarg arg[PPB_MS_MAXARGS]; /* arguments */ 432}; 433.Ed 434.Ss Using microsequences 435To instantiate a microsequence, just declare an array of ppb_microseq 436structures and initialize it as needed. 437You may either use predefined macros 438or code directly your microinstructions according to the ppb_microseq 439definition. 440For example, 441.Bd -literal 442 struct ppb_microseq select_microseq[] = { 443 444 /* parameter list 445 */ 446 #define SELECT_TARGET MS_PARAM(0, 1, MS_TYP_INT) 447 #define SELECT_INITIATOR MS_PARAM(3, 1, MS_TYP_INT) 448 449 /* send the select command to the drive */ 450 MS_DASS(MS_UNKNOWN), 451 MS_CASS(H_nAUTO | H_nSELIN | H_INIT | H_STROBE), 452 MS_CASS( H_AUTO | H_nSELIN | H_INIT | H_STROBE), 453 MS_DASS(MS_UNKNOWN), 454 MS_CASS( H_AUTO | H_nSELIN | H_nINIT | H_STROBE), 455 456 /* now, wait until the drive is ready */ 457 MS_SET(VP0_SELTMO), 458/* loop: */ MS_BRSET(H_ACK, 2 /* ready */), 459 MS_DBRA(-2 /* loop */), 460/* error: */ MS_RET(1), 461/* ready: */ MS_RET(0) 462 }; 463.Ed 464.Pp 465Here, some parameters are undefined and must be filled before 466executing the microsequence. 467In order to initialize each microsequence, one 468should use the 469.Fn ppb_MS_init_msq 470function like this: 471.Bd -literal -offset indent 472ppb_MS_init_msq(select_microseq, 2, 473 SELECT_TARGET, 1 << target, 474 SELECT_INITIATOR, 1 << initiator); 475.Ed 476.Pp 477and then execute the microsequence. 478.Ss The microsequencer 479The microsequencer is executed either at ppbus or adapter level 480(see 481.Xr ppbus 4 482for info about ppbus system layers). 483Most of the microsequencer is executed at 484.Xr atppc 4 485level to avoid 486.Xr ppbus 4 487to adapter function call overhead. 488But some actions like deciding whereas the transfer is 489.Tn IEEE1284-1994 490compliant are executed at 491.Xr ppbus 4 492layer. 493.Sh SEE ALSO 494.Xr atppc 4 , 495.Xr ppbus 4 , 496.Xr vpo 4 497.Sh HISTORY 498The 499.Nm 500manual page first appeared in 501.Fx 3.0 . 502.Sh AUTHORS 503This 504manual page is based on the 505.Fx 506.Nm microseq 507manual page and was update for the 508.Nx 509port by 510.An Gary Thorpe . 511.Sh BUGS 512Only one level of submicrosequences is allowed. 513.Pp 514When triggering the port, maximum delay allowed is 255 us. 515