esiop.ss revision 1.5
1;	$NetBSD: esiop.ss,v 1.5 2002/04/23 12:55:28 bouyer Exp $
2
3;
4; Copyright (c) 2002 Manuel Bouyer.
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; 3. All advertising materials mentioning features or use of this software
15;    must display the following acknowledgement:
16;	This product includes software developed by the University of
17;	California, Berkeley and its contributors.
18; 4. Neither the name of the University nor the names of its contributors
19;    may be used to endorse or promote products derived from this software
20;    without specific prior written permission.
21;
22; THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25; ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32; SUCH DAMAGE.
33;
34
35ARCH 825
36
37; offsets in siop_common_xfer
38ABSOLUTE t_id = 40;
39ABSOLUTE t_msg_in = 48;
40ABSOLUTE t_ext_msg_in = 56;
41ABSOLUTE t_ext_msg_data = 64;
42ABSOLUTE t_msg_out = 72;
43ABSOLUTE t_cmd = 80;
44ABSOLUTE t_status = 88;
45ABSOLUTE t_data = 96;
46
47; offsets in the per-target lun table
48ABSOLUTE target_id = 0x0;
49ABSOLUTE target_luntbl = 0x8;
50
51;; interrupt codes
52; interrupts that needs a valid target/lun/tag
53ABSOLUTE int_done	= 0xff00;
54ABSOLUTE int_msgin	= 0xff01;
55ABSOLUTE int_extmsgin	= 0xff02;
56ABSOLUTE int_extmsgdata	= 0xff03;
57ABSOLUTE int_disc	= 0xff04;
58; interrupts that don't have a valid I/T/Q
59ABSOLUTE int_resfail	= 0xff80;     
60ABSOLUTE int_err	= 0xffff;     
61
62; We use the various scratch[a-j] registers to keep internal status:
63
64; scratchA1: offset in data DSA (for save data pointer)
65; scratchB: save/restore DSA in data loop
66; scratchC: current target/lun/tag
67; scratchC0: flags
68ABSOLUTE f_c_target	= 0x01 ; target valid
69ABSOLUTE f_c_lun	= 0x02 ; lun valud
70ABSOLUTE f_c_tag	= 0x04 ; tag valid
71ABSOLUTE f_c_data	= 0x08 ; data I/O in progress
72ABSOLUTE f_c_data_mask	= 0xf7 ; ~f_c_data
73ABSOLUTE f_c_sdp	= 0x10 ; got save data pointer message
74; scratchC[1-3]: target/lun/tag
75
76; scratchD: current DSA in start cmd ring
77; scratchE0: index in start cmd ring
78ABSOLUTE ncmd_slots	= 64 ; number of slots in CMD ring
79; flags in a cmd slot
80ABSOLUTE f_cmd_free	= 0x01 ; this slot is free
81ABSOLUTE f_cmd_ignore	= 0x02 ; this slot is not free but don't start it
82; offsets in a cmd slot
83ABSOLUTE o_cmd_dsa	= 0; also holds f_cmd_*
84ABSOLUTE o_cmd_id	= 4;
85
86; SCRATCHE1: last status
87
88ENTRY reselect;
89ENTRY cmdr0;
90ENTRY cmdr1;
91ENTRY cmdr2;
92ENTRY cmdr3;
93ENTRY led_on1;
94ENTRY led_on2;
95ENTRY led_off;
96ENTRY status;
97ENTRY msgin;
98ENTRY msgin_ack;
99ENTRY get_extmsgdata;
100ENTRY send_msgout;
101ENTRY script_sched;
102ENTRY load_targtable;
103
104EXTERN tlq_offset;
105EXTERN abs_msgin2;
106
107PROC  esiop_script:
108
109no_cmd:
110	MOVE ISTAT & 0x10 TO SFBR;  pending done command ?
111	INTFLY 0, IF NOT 0x00; 
112reselect:
113	MOVE 0x00 TO SCRATCHA1;
114	MOVE 0x00 TO SCRATCHC0;
115	MOVE 0xff TO SCRATCHE1;
116; a NOP by default; patched with MOVE GPREG | 0x01 to GPREG on compile-time
117; option "SIOP_SYMLED"
118led_off:
119	NOP;
120	WAIT RESELECT REL(reselect_fail);
121; a NOP by default; patched with MOVE GPREG & 0xfe to GPREG on compile-time
122; option "SIOP_SYMLED"
123led_on2:
124        NOP;
125	MOVE SSID & 0x0f to SFBR;
126	MOVE SFBR to SCRATCHC1;
127	MOVE SCRATCHC0 | f_c_target to SCRATCHC0; save target
128	CLEAR CARRY;
129	MOVE SCRATCHC1 SHL SFBR;
130	MOVE SFBR SHL DSA0; target * 4 in dsa
131	MOVE 0x0 to DSA1;
132	MOVE 0x0 to DSA2;
133	MOVE 0x0 to DSA3;
134; load DSA for the target table
135load_targtable:
136	MOVE DSA0 + 0x00 to DSA0; host will patch 0x0 with base of table
137	MOVE DSA1 + 0x00 to DSA1 with carry;
138	MOVE DSA2 + 0x00 to DSA2 with carry;
139	MOVE DSA3 + 0x00 to DSA3 with carry; now dsa -> basetable + target * 4
140	LOAD DSA0, 4, FROM 0; now load DSA for this target
141	SELECT FROM target_id, REL(nextisn);
142nextisn:
143	MOVE 1, abs_msgin2, WHEN MSG_IN;
144	MOVE SFBR & 0x07 to SCRATCHC2;
145	MOVE SCRATCHC0 | f_c_lun to SCRATCHC0; save LUN
146	CLEAR ACK and CARRY;
147	MOVE SCRATCHC2 SHL SFBR; 
148	MOVE SFBR SHL SFBR; lun * 4
149	MOVE DSA0 + SFBR TO DSA0;
150	MOVE DSA1 + 0x0 TO DSA1 with carry;
151	MOVE DSA2 + 0x0 TO DSA2 with carry;
152	MOVE DSA3 + 0x0 TO DSA3 with carry;
153	LOAD DSA0, 4, from target_luntbl; load DSA for this LUN
154	JUMP REL(waitphase), WHEN NOT MSG_IN;
155	MOVE 1, abs_msgin2, WHEN MSG_IN;
156	CLEAR ACK;
157	INT int_msgin, IF NOT 0x20; not a simple tag message, let host handle it
158	MOVE 1, abs_msgin2, WHEN MSG_IN; get tag
159	CLEAR ACK;
160	MOVE SFBR to SCRATCHA2;
161	MOVE SFBR to SCRATCHC3;
162	MOVE SCRATCHC0 | f_c_tag to SCRATCHC0; save TAG
163	MOVE 0x0 to SCRATCHA3;
164	CLEAR CARRY;
165	MOVE SCRATCHA2 SHL SCRATCHA2;
166	MOVE SCRATCHA3 SHL SCRATCHA3;
167	MOVE SCRATCHA2 SHL SCRATCHA2;
168	MOVE SCRATCHA3 SHL SCRATCHA3; TAG * 4 to SCRATCHA(2,3)
169	MOVE SCRATCHA2 TO SFBR;
170	MOVE DSA0 + SFBR TO DSA0;
171	MOVE DSA1 + 0x00 TO DSA1 with CARRY;
172	MOVE DSA2 + 0x00 TO DSA2 with CARRY;
173	MOVE DSA3 + 0x00 TO DSA3 with CARRY;
174	MOVE SCRATCHA3 TO SFBR;
175	MOVE DSA1 + SFBR TO DSA1;
176	MOVE DSA2 + 0x00 TO DSA2 with CARRY;
177	MOVE DSA3 + 0x00 TO DSA3 with CARRY; SCRACHA(2,3) + DSA to DSA
178	LOAD DSA0, 4, from 0; load DSA for this tag
179	JUMP REL(waitphase);
180
181reselect_fail:
182	; check that host asserted SIGP, this'll clear SIGP in ISTAT
183	MOVE CTEST2 & 0x40 TO SFBR;
184	INT int_resfail,  IF 0x00;
185script_sched:
186; Load ring DSA
187	MOVE SCRATCHD0 to SFBR;
188	MOVE SFBR to DSA0;
189	MOVE SCRATCHD1 to SFBR;
190	MOVE SFBR to DSA1;
191	MOVE SCRATCHD2 to SFBR;
192	MOVE SFBR to DSA2;
193	MOVE SCRATCHD3 to SFBR;
194	MOVE SFBR to DSA3;
195	LOAD SCRATCHA0,4, from o_cmd_dsa; /* get flags */
196	MOVE SCRATCHA0 & f_cmd_free to SFBR;
197	JUMP REL(no_cmd), IF NOT 0x0;
198	MOVE SCRATCHA0 & f_cmd_ignore to SFBR;
199	JUMP REL(ignore_cmd), IF NOT 0x0;
200; this slot is busy, attempt to exec command
201	SELECT ATN FROM o_cmd_id, REL(reselect);
202; select either succeeded or timed out.
203; if timed out the STO interrupt will be posted at the first SCSI bus access
204; waiting for a valid phase, so we have to do it now. If not a MSG_OUT phase,
205; this is an error anyway (we selected with ATN)
206	INT int_err, WHEN NOT MSG_OUT;
207ignore_cmd:
208	MOVE SCRATCHE0 + 1 to SCRATCHE0;
209	MOVE SCRATCHD0 + 8 to SCRATCHD0; sizeof (esiop_cmd_slot)
210	MOVE SCRATCHD1 + 0 to SCRATCHD1 WITH CARRY;
211	MOVE SCRATCHD2 + 0 to SCRATCHD2 WITH CARRY;
212	MOVE SCRATCHD3 + 0 to SCRATCHD3 WITH CARRY;
213	MOVE SCRATCHE0 TO SFBR;
214	JUMP REL(handle_cmd), IF  NOT ncmd_slots;
215; reset pointers to beggining of area
216cmdr0:
217	MOVE 0xff to SCRATCHD0; correct value will be patched by driver
218cmdr1:
219	MOVE 0xff to SCRATCHD1;
220cmdr2:
221	MOVE 0xff to SCRATCHD2;
222cmdr3:
223	MOVE 0xff to SCRATCHD3;
224	MOVE 0x00 to SCRATCHE0;
225handle_cmd:
226	MOVE SCRATCHA0 | f_cmd_free to SCRATCHA0;
227	STORE noflush SCRATCHA0, 4, FROM o_cmd_dsa;
228	MOVE SCRATCHA0 & f_cmd_ignore to SFBR;
229	JUMP REL(script_sched), IF NOT 0x00; /* next command if ignore */
230
231; a NOP by default; patched with MOVE GPREG & 0xfe to GPREG on compile-time
232; option "SIOP_SYMLED"
233led_on1:
234	NOP;
235	LOAD DSA0, 4, FROM o_cmd_dsa; /* load new DSA */
236	MOVE DSA0 & 0xfe to DSA0; /* clear f_cmd_free */
237	MOVE 0x00 TO SCRATCHA1;
238	MOVE 0xff TO SCRATCHE1;
239	LOAD SCRATCHC0, 4, FROM tlq_offset;
240;we can now send our identify message
241send_msgout: ; entry point for msgout after a msgin or status phase
242	SET ATN;
243	CLEAR ACK;
244msgout: 
245        MOVE FROM t_msg_out, WHEN MSG_OUT;
246	CLEAR ATN;  
247	JUMP REL(waitphase);
248
249msgin_ack:
250	CLEAR ACK;
251waitphase:
252	JUMP REL(msgout), WHEN MSG_OUT;
253	JUMP REL(msgin), WHEN MSG_IN;
254	JUMP REL(dataout), WHEN DATA_OUT;
255	JUMP REL(datain), WHEN DATA_IN;
256	JUMP REL(cmdout), WHEN CMD;
257	JUMP REL(status), WHEN STATUS;
258	INT int_err;
259
260
261handle_sdp:
262	CLEAR ACK;
263	MOVE SCRATCHC0 | f_c_sdp TO SCRATCHC0;
264	; should get a disconnect message now
265msgin:
266	CLEAR ATN
267	MOVE FROM t_msg_in, WHEN MSG_IN;
268handle_msgin:
269	JUMP REL(handle_cmpl), IF 0x00	; command complete message
270	JUMP REL(handle_sdp), IF 0x02	; save data pointer message
271	JUMP REL(handle_extin), IF 0x01	; extended message
272	INT int_msgin, IF NOT 0x04;
273	CALL REL(disconnect)		; disconnect message
274; if we didn't get sdp, or if offset is 0, no need to interrupt
275	MOVE SCRATCHC0 & f_c_sdp TO SFBR;
276	JUMP REL(script_sched), if 0x00;
277	MOVE SCRATCHA1 TO SFBR;
278	JUMP REL(script_sched), if 0x00;
279; Ok, we need to save data pointers
280	INT int_disc;
281
282cmdout:
283        MOVE FROM t_cmd, WHEN CMD; 
284	JUMP REL(waitphase);
285status: 
286        MOVE FROM t_status, WHEN STATUS;
287	MOVE SFBR TO SCRATCHE1;
288	JUMP REL(waitphase);
289datain:
290        CALL REL(savedsa);
291	MOVE SCRATCHC0 | f_c_data TO SCRATCHC0;
292	datain_loop:
293	MOVE FROM t_data, WHEN DATA_IN;
294	MOVE SCRATCHA1 + 1 TO SCRATCHA1 ; adjust offset
295	MOVE DSA0 + 8 to DSA0;
296	MOVE DSA1 + 0 to DSA1 WITH CARRY;
297	MOVE DSA2 + 0 to DSA2 WITH CARRY;
298	MOVE DSA3 + 0 to DSA3 WITH CARRY;
299	JUMP REL(datain_loop), WHEN DATA_IN;
300	CALL REL(restoredsa);
301	MOVE SCRATCHC0 & f_c_data_mask TO SCRATCHC0;
302	JUMP REL(waitphase);
303
304dataout:
305        CALL REL(savedsa);
306	MOVE SCRATCHC0 | f_c_data TO SCRATCHC0;
307dataout_loop:
308	MOVE FROM t_data, WHEN DATA_OUT;
309	MOVE SCRATCHA1 + 1 TO SCRATCHA1 ; adjust offset
310	MOVE DSA0 + 8 to DSA0;
311	MOVE DSA1 + 0 to DSA1 WITH CARRY;
312	MOVE DSA2 + 0 to DSA2 WITH CARRY;
313	MOVE DSA3 + 0 to DSA3 WITH CARRY;
314	JUMP REL(dataout_loop), WHEN DATA_OUT;
315	CALL REL(restoredsa);
316	MOVE SCRATCHC0 & f_c_data_mask TO SCRATCHC0;
317	JUMP REL(waitphase);
318
319savedsa:
320        MOVE DSA0 to SFBR;
321	MOVE SFBR to SCRATCHB0;       
322	MOVE DSA1 to SFBR;
323	MOVE SFBR to SCRATCHB1;       
324	MOVE DSA2 to SFBR;
325	MOVE SFBR to SCRATCHB2;
326	MOVE DSA3 to SFBR;
327	MOVE SFBR to SCRATCHB3;
328	RETURN;
329
330restoredsa:
331	MOVE SCRATCHB0 TO SFBR;
332	MOVE SFBR TO DSA0;
333	MOVE SCRATCHB1 TO SFBR;
334	MOVE SFBR TO DSA1;
335	MOVE SCRATCHB2 TO SFBR;
336	MOVE SFBR TO DSA2;
337	MOVE SCRATCHB3 TO SFBR;       
338	MOVE SFBR TO DSA3;
339	RETURN;
340
341disconnect:
342        MOVE SCNTL2 & 0x7f TO SCNTL2;
343	CLEAR ATN;
344	CLEAR ACK;
345	WAIT DISCONNECT;
346	RETURN;
347
348handle_cmpl:
349	CALL REL(disconnect);
350	MOVE SCRATCHE1 to SFBR;
351	INT int_done, IF NOT 0x00; if status is not "done", let host handle it
352	MOVE ISTAT | 0x10 TO ISTAT; else signal that cmd is done in ISTAT
353	JUMP REL(script_sched); and attempt next command
354
355handle_extin:
356	CLEAR ACK;
357	MOVE FROM t_ext_msg_in, WHEN MSG_IN;
358	INT int_extmsgin; /* let host fill in t_ext_msg_data */
359get_extmsgdata:
360	CLEAR ACK;
361	MOVE FROM t_ext_msg_data, WHEN MSG_IN;
362	INT int_extmsgdata; 
363
364PROC esiop_led_on:
365	MOVE GPREG & 0xfe TO GPREG;
366
367PROC esiop_led_off:
368	MOVE GPREG | 0x01 TO GPREG;
369