sd53c8xx.n 12 KB

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