]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/sd53c8xx.n
ether82563: fix multicast for i210
[plan9front.git] / sys / src / 9 / pc / sd53c8xx.n
1 // NCR 53c8xx driver for Plan 9
2 // Nigel Roles (nigel@9fs.org)
3 //
4 // Microcode
5 //
6 // 27/5/02      Fixed problems with transfers >= 256 * 512
7 //
8 // 13/3/01      Fixed microcode to support targets > 7
9 //
10
11 extern  scsi_id_buf
12 extern  msg_out_buf
13 extern  cmd_buf
14 extern  data_buf
15 extern  status_buf
16 extern  msgin_buf
17 extern  dsa_0
18 extern  dsa_1
19 extern  dsa_head
20 extern  ssid_mask
21
22 SIR_MSG_IO_COMPLETE = 0
23 error_not_cmd_complete = 1
24 error_disconnected = 2
25 error_reselected = 3
26 error_unexpected_phase = 4
27 error_weird_message = 5
28 SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT = 6
29 error_not_identify_after_reselect = 7
30 error_too_much_data = 8
31 error_too_little_data = 9
32 SIR_MSG_REJECT = 10
33 SIR_MSG_SDTR = 11
34 SIR_EV_RESPONSE_OK = 12
35 error_sigp_set = 13
36 SIR_EV_PHASE_SWITCH_AFTER_ID = 14
37 SIR_MSG_WDTR = 15
38 SIR_MSG_IGNORE_WIDE_RESIDUE = 16
39 SIR_NOTIFY_DISC = 100
40 SIR_NOTIFY_RESELECT = 101
41 SIR_NOTIFY_MSG_IN = 102
42 SIR_NOTIFY_STATUS = 103
43 SIR_NOTIFY_DUMP = 104
44 SIR_NOTIFY_DUMP2 = 105
45 SIR_NOTIFY_SIGP = 106
46 SIR_NOTIFY_ISSUE = 107
47 SIR_NOTIFY_WAIT_RESELECT = 108
48 SIR_NOTIFY_ISSUE_CHECK = 109
49 SIR_NOTIFY_DUMP_NEXT_CODE = 110
50 SIR_NOTIFY_COMMAND = 111
51 SIR_NOTIFY_DATA_IN = 112
52 SIR_NOTIFY_DATA_OUT = 113
53 SIR_NOTIFY_BLOCK_DATA_IN = 114
54 SIR_NOTIFY_WSR = 115
55 SIR_NOTIFY_LOAD_SYNC = 116
56 SIR_NOTIFY_RESELECTED_ON_SELECT = 117
57 SIR_NOTIFY_LOAD_STATE = 118
58
59 STATE_FREE = 0
60 STATE_ALLOCATED = 1
61 STATE_ISSUE = 2
62 STATE_DISCONNECTED = 3
63 STATE_DONE = 4
64 STATE_END = 5
65
66 RESULT_OK = 0
67         
68 MSG_IDENTIFY = 0x80
69 MSG_DISCONNECT = 0x04
70 MSG_SAVE_DATA_POINTER = 0x02
71 MSG_RESTORE_POINTERS = 0x03
72 MSG_IGNORE_WIDE_RESIDUE = 0x23
73 X_MSG = 0x01
74 X_MSG_SDTR = 0x01
75 X_MSG_WDTR = 0x03
76 MSG_REJECT = 0x07
77
78 BSIZE = 512
79 //BSIZE=4096
80
81  // idle:
82         jump    wait_for_reselection    
83 start:
84         call    load_sync
85 //      move    13 to ctest0
86 //      int     SIR_NOTIFY_ISSUE
87         clear   target
88         select  atn from scsi_id_buf, reselected_on_select // do I need to clear ATN here?
89         jump    start1, when msg_in     // why is this here?
90 start1:
91 //      move    14 to ctest0
92         move    from msg_out_buf, when msg_out
93 id_out_mismatch:
94         jump    start1, when msg_out            // repeat on parity grounds
95         jump    to_decisions, when not cmd
96 cmd_phase:
97 //      int     SIR_NOTIFY_COMMAND
98         clear   atn
99         move    from cmd_buf, when cmd
100 cmd_out_mismatch:
101         jump    to_decisions, when not data_in
102 data_in_phase:
103         move    memory 4, state, scratcha
104         move    memory 4, dmaaddr, scratchb
105 //      int     SIR_NOTIFY_DATA_IN
106 data_in_block_loop:
107         move    scratcha2 to sfbr
108         jump    data_in_normal, if 0
109 //      int     SIR_NOTIFY_BLOCK_DATA_IN
110         move    BSIZE, ptr dmaaddr, when data_in                // transfer BSIZE bytes
111 data_in_block_mismatch:
112         move    scratchb1 + BSIZE / 256 to scratchb1            // add BSIZE to scratchb
113         move    scratchb2 + 0 to scratchb2 with carry
114         move    scratchb3 + 0 to scratchb3 with carry
115         move    scratcha2 + 255 to scratcha2                    // sub one from block count
116         move    memory 4, scratchb, dmaaddr                     // save latest dmaddr
117         jump    data_in_block_loop, when data_in
118         move    memory 4, scratcha, state                       // save latest state
119         call    save_state
120         jump    to_decisions
121 data_block_mismatch_recover:
122         move    memory 4, scratchb, dmaaddr                     // save latest dmaddr
123 data_mismatch_recover:
124         move    memory 4, scratcha, state                       // save latest state
125         jump    to_decisions                                    // no need to save
126                                                                 // as interrupt routine
127                                                                 // did this
128 data_in_normal:
129         move    scratcha3 to sfbr
130         int     error_too_much_data, if not 0
131         move    from data_buf, when data_in
132 data_in_mismatch:
133         move    2 to scratcha3
134         move    memory 4, scratcha, state
135         call    save_state
136         jump    post_data_to_decisions
137 data_out_phase:
138 //      int     SIR_NOTIFY_DATA_OUT
139         move    memory 4, state, scratcha
140         move    memory 4, dmaaddr, scratchb
141 data_out_block_loop:
142         move    scratcha2 to sfbr
143         jump    data_out_normal, if 0
144         move    memory 4, dmaaddr, scratchb
145         move    BSIZE, ptr dmaaddr, when data_out               // transfer BSIZE bytes
146 data_out_block_mismatch:
147         move    scratchb1 + BSIZE / 256 to scratchb1            // add BSIZE to scratchb
148         move    scratchb2 + 0 to scratchb2 with carry
149         move    scratchb3 + 0 to scratchb3 with carry
150         move    scratcha2 + 255 to scratcha2                    // sub one from block count
151         move    memory 4, scratchb, dmaaddr                     // save latest dmaddr
152         jump    data_out_block_loop, when data_out
153         move    memory 4, scratcha, state                       // save latest state
154         jump    to_decisions
155 data_out_normal:
156         move    scratcha3 to sfbr
157         int     error_too_little_data, if not 0
158         move    from data_buf, when data_out
159 data_out_mismatch:
160         move    2 to scratcha3
161         move    memory 4, scratcha, state
162         call    save_state
163         jump    post_data_to_decisions
164 status_phase:
165         move    from status_buf, when status
166 //      int     SIR_NOTIFY_STATUS
167         int     error_unexpected_phase, when not msg_in
168 msg_in_phase:
169         move    1, scratcha, when msg_in
170 //      int     SIR_NOTIFY_MSG_IN
171         jump    rejected, if MSG_REJECT
172 msg_in_not_reject:
173         jump    disconnected, if MSG_DISCONNECT
174         jump    msg_in_skip, if MSG_SAVE_DATA_POINTER
175         jump    msg_in_skip, if MSG_RESTORE_POINTERS
176         jump    ignore_wide, if MSG_IGNORE_WIDE_RESIDUE
177         jump    extended, if X_MSG
178         int     error_not_cmd_complete, if not 0
179         move    scntl2&0x7e to scntl2                   // take care not to clear WSR
180         clear   ack
181         wait    disconnect
182         // update state
183         move    memory 4, state, scratcha
184         move    STATE_DONE to scratcha0
185         move    RESULT_OK to scratcha1
186         move    memory 4, scratcha, state
187         call    save_state
188 //      int     SIR_MSG_IO_COMPLETE
189         intfly  0
190         jump    issue_check
191
192 rejected:
193         int     SIR_MSG_REJECT
194         clear   ack
195         jump    to_decisions
196 msg_in_skip:
197         clear   ack
198         jump    to_decisions
199         
200 extended:
201         clear   ack
202         int     error_unexpected_phase, when not msg_in
203         move    1, scratcha1, when msg_in
204         jump    ext_3, if 3
205         jump    ext_2, if 2
206         int     error_weird_message, if not 1
207 ext_1:
208         clear   ack
209         int     error_unexpected_phase, when not msg_in
210         move    1, scratcha1, when msg_in
211         jump    ext_done
212
213 ext_3:  clear   ack
214         int     error_unexpected_phase, when not msg_in
215         move    1, scratcha1, when msg_in
216         clear   ack
217         int     error_unexpected_phase, when not msg_in
218         move    1, scratcha2, when msg_in
219         clear   ack
220         int     error_unexpected_phase, when not msg_in
221         move    1, scratcha3, when msg_in
222         move    scratcha1 to sfbr
223         jump    ext_done, if not X_MSG_SDTR
224
225 // the target sent SDTR - leave ACK asserted and signal kernel
226 // kernel will either restart at reject, or continue
227 sdtr:   int     SIR_MSG_SDTR
228         clear   ack
229         jump    to_decisions
230
231 ext_2:  clear   ack
232         int     error_unexpected_phase, when not msg_in
233         move    1, scratcha1, when msg_in
234         clear   ack
235         int     error_unexpected_phase, when not msg_in
236         move    1, scratcha2, when msg_in
237         move    scratcha1 to sfbr
238         jump    ext_done, if not X_MSG_WDTR
239
240 wdtr:   int     SIR_MSG_WDTR
241         clear   ack
242         jump    to_decisions
243
244 ext_done:
245 //      ought to check message here, but instead reject all
246 //      NB ATN set
247 reject:
248         set     atn                                     // get target's ATN
249         clear   ack                                     // finish ACK
250         move    MSG_REJECT to scratcha                  // prepare message
251         int     error_unexpected_phase, when not msg_out// didn't get ATN
252         clear   atn                                     // last byte coming
253         move    1, scratcha, when msg_out               // send byte
254         clear   ack                                     // finish ACK
255         jump    reject, when msg_out                    // parity error
256         jump    to_decisions
257         
258 ignore_wide:
259         clear   ack
260         int     error_unexpected_phase, when not msg_in
261         move    1, scratcha1, when msg_in
262         int     SIR_MSG_IGNORE_WIDE_RESIDUE
263         clear   ack
264         jump    to_decisions
265
266 //      sends a response to a message
267 response:
268         set     atn
269         clear   ack
270         int     error_unexpected_phase, when not msg_out
271 response_repeat:
272         move    from msg_out_buf, when msg_out
273         jump    response_repeat, when msg_out           // repeat on parity grounds
274 // now look for response
275 // msg_in could be a REJECT
276 // anything other message is something else so signal kernel first
277         jump    response_msg_in, when msg_in
278         int     SIR_EV_RESPONSE_OK                      // not a MSG_IN so OK
279         jump    to_decisions
280
281 response_msg_in:
282         move    1, scratcha, when msg_in
283         jump    rejected, if MSG_REJECT         // go and generate rej interrupt
284         int     SIR_EV_RESPONSE_OK              // not a REJECT so OK
285         jump    msg_in_not_reject               // try others
286
287 disconnected:
288 //      move    5 to ctest0
289         move    scntl2&0x7e to scntl2                   // don't clear WSR
290         clear   ack
291         wait    disconnect
292         // UPDATE state to disconnected
293         move    memory 4, state, scratcha
294         move    STATE_DISCONNECTED to scratcha0
295         move    memory 4, scratcha, state
296         call    save_state
297 wsr_check:
298         move    scntl2&0x01 to sfbr
299         int     SIR_NOTIFY_WSR, if not 0
300 //      int     SIR_NOTIFY_DISC
301         jump    issue_check
302
303 reselected_on_select:
304         int     SIR_NOTIFY_RESELECTED_ON_SELECT
305         jump    reselected
306
307 wait_for_reselection:
308 //      move    11 to ctest0
309 //      int     SIR_NOTIFY_WAIT_RESELECT
310         wait reselect sigp_set
311 reselected:
312 //      move    12 to ctest0
313         clear   target
314         int     SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT, when not msg_in
315         move    1, scratchb, when msg_in
316         int     error_not_identify_after_reselect, if not MSG_IDENTIFY and mask 0x1f
317 //      int     SIR_NOTIFY_RESELECT
318         // now locate the right DSA - note do not clear ACK, so target doesn't start
319         // synchronous transfer until we are ready
320 find_dsa:
321 //      move    6 to ctest0
322         move    memory 4, dsa_head, dsa
323 find_dsa_loop:
324 //      move    7 to ctest0
325 //      move    8 to ctest0
326         // load state from DSA into dsa_copy
327         call    load_state
328         move    memory 4, state, scratcha               // get dsastate in scratcha
329         move    scratcha0 to sfbr                       // and state variable in sfbr
330         jump    find_dsa_next, if not STATE_DISCONNECTED // wrong state
331         int     error_reselected, if STATE_END
332         move    ssid & ssid_mask to sfbr                        // get target ID
333         move    memory 1, targ, find_dsa_smc1           // forge target comparison instruction
334 find_dsa_smc1:
335         jump    find_dsa_next, if not 255               // jump if not matched
336         move    memory 1, lun, find_dsa_smc2            // forge lun comparison instruction
337         move    scratchb0 to sfbr                       // recover IDENTIFY message
338 find_dsa_smc2:
339         jump    reload_sync, if 255 and mask ~7         // off we jolly well go
340 find_dsa_next:
341         move    memory 4, next, dsa                     // find next
342         jump    find_dsa_loop
343
344 // id_out terminated early
345 // most likely the message wasn't recognised
346 // clear ATN and accept the message in
347 // called from sd53c8xx.c directly
348 id_out_mismatch_recover:
349         clear   atn
350         jump    msg_in_phase, when msg_in
351         int     SIR_MSG_REJECT
352         jump    to_decisions
353
354 // Reload synchronous registers after a reconnect. If the transfer is a synchronous read, then
355 // as soon as we clear ACK, the target will switch to data_in and start blasting data into the
356 // fifo. We need to be executing the 'jump when data_in' instruction before the target stops REQing
357 // since it is the REQ which latches the 'when'. The target will do 16 REQs before stopping, so
358 // we have 16 bytes (160uS) plus delays to do this after clearing ACK. Once the jump is executing,
359 // the target will wait, so as much debugging as you like can happen in data_in_phase, just don't
360 // stick any delays between 'clear ack' and 'jump data_in_phase, when data_in'.
361
362 reload_sync:
363         call    load_sync
364         clear   ack
365 to_decisions:
366         jump    data_in_phase, when data_in
367         jump    cmd_phase, if cmd
368         jump    data_out_phase, if data_out
369         jump    status_phase, if status
370         jump    msg_in_phase, if msg_in
371         int     error_unexpected_phase
372
373 post_data_to_decisions:
374         jump    status_phase, when status
375         jump    msg_in_phase, if msg_in
376         int     error_unexpected_phase
377         
378 //
379 // MULTI_TARGET
380 //
381 // following must mirror top of dsa structure
382 // the first section is loaded and saved, the
383 // second section loaded only
384 dsa_copy:
385 state:  defw    0                       // a0 is state, a1 result, a2 dma block count
386 dmaaddr: defw   0                       // dma address for block moves
387 dsa_save_end:
388 targ:   defw    0                       // lsb is target
389 lun:    defw    0                       // lsb is lun
390 sync:   defw    0                       // lsb is scntl3, sxfer
391 next:   defw    0
392 dsa_load_end:
393 dsa_load_len = dsa_load_end - dsa_copy
394 dsa_save_len = dsa_save_end - dsa_copy
395
396 load_state:
397 //      int     SIR_NOTIFY_LOAD_STATE
398         jump load_state_okay
399
400         move    dsa0 to sfbr
401         jump load_state_okay, if not 0
402         move    dsa1 to sfbr
403         jump load_state_okay, if not 0
404         move    dsa2 to sfbr
405         jump load_state_okay, if not 0
406         move    dsa3 to sfbr
407         jump load_state_okay, if not 0
408         // dsa is 0
409         move    memory 4, dsa, dmaaddr
410         move    memory 4, dsa, targ
411         move    memory 4, dsa, lun
412         move    memory 4, dsa, sync
413         move    memory 4, dsa, next
414         move    memory 4, dsa, scratcha
415         move    STATE_END to sfbr
416         move    sfbr to scratcha0
417         move    memory 4, scratcha, state
418         return
419
420 load_state_okay:
421         // load state from DSA into dsa_copy
422 //      move    9 to ctest0
423         move    memory 4, dsa, load_state_smc0 + 4
424 load_state_smc0:
425         move    memory dsa_load_len, 0, dsa_copy
426 //      move    20 to ctest0
427         return
428 save_state:
429         move    memory 4, dsa, save_state_smc0 + 8
430 save_state_smc0:
431         move    memory dsa_save_len, dsa_copy, 0
432         return
433
434 sigp_set:
435 //      int     SIR_NOTIFY_SIGP
436         move    ctest2 to sfbr                          // clear SIGP
437 issue_check:
438 //      int     SIR_NOTIFY_ISSUE_CHECK
439 //      move    1 to ctest0
440         move    memory 4, dsa_head, dsa
441 issue_check_loop:
442         call    load_state
443         move    memory 4, state, scratcha               // get dsastate in scratcha
444         move    scratcha0 to sfbr                       // and state variable in sfbr
445         jump    start, if STATE_ISSUE                   // right state
446         jump    wait_for_reselection, if STATE_END
447  //     move    4 to ctest0
448         move    memory 4, next, dsa                     // find next
449         jump    issue_check_loop
450
451
452 load_sync:
453         move    memory 4, sync, scratcha                // load the sync stuff
454         move    scratcha0 to sfbr                       // assuming load_state has been called
455         move    sfbr to scntl3
456         move    scratcha1 to sfbr
457         move    sfbr to sxfer
458  //     int     SIR_NOTIFY_LOAD_SYNC
459         return