53c7xx.scr 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591
  1. #undef DEBUG
  2. #undef EVENTS
  3. #undef NO_SELECTION_TIMEOUT
  4. #define BIG_ENDIAN
  5. ; 53c710 driver. Modified from Drew Eckhardts driver
  6. ; for 53c810 by Richard Hirst [richard@sleepie.demon.co.uk]
  7. ;
  8. ; I have left the script for the 53c8xx family in here, as it is likely
  9. ; to be useful to see what I changed when bug hunting.
  10. ; NCR 53c810 driver, main script
  11. ; Sponsored by
  12. ; iX Multiuser Multitasking Magazine
  13. ; hm@ix.de
  14. ;
  15. ; Copyright 1993, 1994, 1995 Drew Eckhardt
  16. ; Visionary Computing
  17. ; (Unix and Linux consulting and custom programming)
  18. ; drew@PoohSticks.ORG
  19. ; +1 (303) 786-7975
  20. ;
  21. ; TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
  22. ;
  23. ; PRE-ALPHA
  24. ;
  25. ; For more information, please consult
  26. ;
  27. ; NCR 53C810
  28. ; PCI-SCSI I/O Processor
  29. ; Data Manual
  30. ;
  31. ; NCR 53C710
  32. ; SCSI I/O Processor
  33. ; Programmers Guide
  34. ;
  35. ; NCR Microelectronics
  36. ; 1635 Aeroplaza Drive
  37. ; Colorado Springs, CO 80916
  38. ; 1+ (719) 578-3400
  39. ;
  40. ; Toll free literature number
  41. ; +1 (800) 334-5454
  42. ;
  43. ; IMPORTANT : This code is self modifying due to the limitations of
  44. ; the NCR53c7,8xx series chips. Persons debugging this code with
  45. ; the remote debugger should take this into account, and NOT set
  46. ; breakpoints in modified instructions.
  47. ;
  48. ; Design:
  49. ; The NCR53c7,8xx family of SCSI chips are busmasters with an onboard
  50. ; microcontroller using a simple instruction set.
  51. ;
  52. ; So, to minimize the effects of interrupt latency, and to maximize
  53. ; throughput, this driver offloads the practical maximum amount
  54. ; of processing to the SCSI chip while still maintaining a common
  55. ; structure.
  56. ;
  57. ; Where tradeoffs were needed between efficiency on the older
  58. ; chips and the newer NCR53c800 series, the NCR53c800 series
  59. ; was chosen.
  60. ;
  61. ; While the NCR53c700 and NCR53c700-66 lacked the facilities to fully
  62. ; automate SCSI transfers without host processor intervention, this
  63. ; isn't the case with the NCR53c710 and newer chips which allow
  64. ;
  65. ; - reads and writes to the internal registers from within the SCSI
  66. ; scripts, allowing the SCSI SCRIPTS(tm) code to save processor
  67. ; state so that multiple threads of execution are possible, and also
  68. ; provide an ALU for loop control, etc.
  69. ;
  70. ; - table indirect addressing for some instructions. This allows
  71. ; pointers to be located relative to the DSA ((Data Structure
  72. ; Address) register.
  73. ;
  74. ; These features make it possible to implement a mailbox style interface,
  75. ; where the same piece of code is run to handle I/O for multiple threads
  76. ; at once minimizing our need to relocate code. Since the NCR53c700/
  77. ; NCR53c800 series have a unique combination of features, making a
  78. ; a standard ingoing/outgoing mailbox system, costly, I've modified it.
  79. ;
  80. ; - Mailboxes are a mixture of code and data. This lets us greatly
  81. ; simplify the NCR53c810 code and do things that would otherwise
  82. ; not be possible.
  83. ;
  84. ; The saved data pointer is now implemented as follows :
  85. ;
  86. ; Control flow has been architected such that if control reaches
  87. ; munge_save_data_pointer, on a restore pointers message or
  88. ; reconnection, a jump to the address formerly in the TEMP register
  89. ; will allow the SCSI command to resume execution.
  90. ;
  91. ;
  92. ; Note : the DSA structures must be aligned on 32 bit boundaries,
  93. ; since the source and destination of MOVE MEMORY instructions
  94. ; must share the same alignment and this is the alignment of the
  95. ; NCR registers.
  96. ;
  97. ; For some systems (MVME166, for example) dmode is always the same, so don't
  98. ; waste time writing it
  99. #if 1
  100. #define DMODE_MEMORY_TO_NCR
  101. #define DMODE_MEMORY_TO_MEMORY
  102. #define DMODE_NCR_TO_MEMORY
  103. #else
  104. #define DMODE_MEMORY_TO_NCR MOVE dmode_memory_to_ncr TO DMODE
  105. #define DMODE_MEMORY_TO_MEMORY MOVE dmode_memory_to_memory TO DMODE
  106. #define DMODE_NCR_TO_MEMORY MOVE dmode_ncr_to_memory TO DMODE
  107. #endif
  108. ABSOLUTE dsa_temp_lun = 0 ; Patch to lun for current dsa
  109. ABSOLUTE dsa_temp_next = 0 ; Patch to dsa next for current dsa
  110. ABSOLUTE dsa_temp_addr_next = 0 ; Patch to address of dsa next address
  111. ; for current dsa
  112. ABSOLUTE dsa_temp_sync = 0 ; Patch to address of per-target
  113. ; sync routine
  114. ABSOLUTE dsa_sscf_710 = 0 ; Patch to address of per-target
  115. ; sscf value (53c710)
  116. ABSOLUTE dsa_temp_target = 0 ; Patch to id for current dsa
  117. ABSOLUTE dsa_temp_addr_saved_pointer = 0; Patch to address of per-command
  118. ; saved data pointer
  119. ABSOLUTE dsa_temp_addr_residual = 0 ; Patch to address of per-command
  120. ; current residual code
  121. ABSOLUTE dsa_temp_addr_saved_residual = 0; Patch to address of per-command
  122. ; saved residual code
  123. ABSOLUTE dsa_temp_addr_new_value = 0 ; Address of value for JUMP operand
  124. ABSOLUTE dsa_temp_addr_array_value = 0 ; Address to copy to
  125. ABSOLUTE dsa_temp_addr_dsa_value = 0 ; Address of this DSA value
  126. ;
  127. ; Once a device has initiated reselection, we need to compare it
  128. ; against the singly linked list of commands which have disconnected
  129. ; and are pending reselection. These commands are maintained in
  130. ; an unordered singly linked list of DSA structures, through the
  131. ; DSA pointers at their 'centers' headed by the reconnect_dsa_head
  132. ; pointer.
  133. ;
  134. ; To avoid complications in removing commands from the list,
  135. ; I minimize the amount of expensive (at eight operations per
  136. ; addition @ 500-600ns each) pointer operations which must
  137. ; be done in the NCR driver by precomputing them on the
  138. ; host processor during dsa structure generation.
  139. ;
  140. ; The fixed-up per DSA code knows how to recognize the nexus
  141. ; associated with the corresponding SCSI command, and modifies
  142. ; the source and destination pointers for the MOVE MEMORY
  143. ; instruction which is executed when reselected_ok is called
  144. ; to remove the command from the list. Similarly, DSA is
  145. ; loaded with the address of the next DSA structure and
  146. ; reselected_check_next is called if a failure occurs.
  147. ;
  148. ; Perhaps more concisely, the net effect of the mess is
  149. ;
  150. ; for (dsa = reconnect_dsa_head, dest = &reconnect_dsa_head,
  151. ; src = NULL; dsa; dest = &dsa->next, dsa = dsa->next) {
  152. ; src = &dsa->next;
  153. ; if (target_id == dsa->id && target_lun == dsa->lun) {
  154. ; *dest = *src;
  155. ; break;
  156. ; }
  157. ; }
  158. ;
  159. ; if (!dsa)
  160. ; error (int_err_unexpected_reselect);
  161. ; else
  162. ; longjmp (dsa->jump_resume, 0);
  163. ;
  164. ;
  165. #if (CHIP != 700) && (CHIP != 70066)
  166. ; Define DSA structure used for mailboxes
  167. ENTRY dsa_code_template
  168. dsa_code_template:
  169. ENTRY dsa_code_begin
  170. dsa_code_begin:
  171. ; RGH: Don't care about TEMP and DSA here
  172. DMODE_MEMORY_TO_NCR
  173. MOVE MEMORY 4, dsa_temp_addr_dsa_value, addr_scratch
  174. DMODE_MEMORY_TO_MEMORY
  175. #if (CHIP == 710)
  176. MOVE MEMORY 4, addr_scratch, saved_dsa
  177. ; We are about to go and select the device, so must set SSCF bits
  178. MOVE MEMORY 4, dsa_sscf_710, addr_scratch
  179. #ifdef BIG_ENDIAN
  180. MOVE SCRATCH3 TO SFBR
  181. #else
  182. MOVE SCRATCH0 TO SFBR
  183. #endif
  184. MOVE SFBR TO SBCL
  185. MOVE MEMORY 4, saved_dsa, addr_dsa
  186. #else
  187. CALL scratch_to_dsa
  188. #endif
  189. CALL select
  190. ; Handle the phase mismatch which may have resulted from the
  191. ; MOVE FROM dsa_msgout if we returned here. The CLEAR ATN
  192. ; may or may not be necessary, and we should update script_asm.pl
  193. ; to handle multiple pieces.
  194. CLEAR ATN
  195. CLEAR ACK
  196. ; Replace second operand with address of JUMP instruction dest operand
  197. ; in schedule table for this DSA. Becomes dsa_jump_dest in 53c7,8xx.c.
  198. ENTRY dsa_code_fix_jump
  199. dsa_code_fix_jump:
  200. MOVE MEMORY 4, NOP_insn, 0
  201. JUMP select_done
  202. ; wrong_dsa loads the DSA register with the value of the dsa_next
  203. ; field.
  204. ;
  205. wrong_dsa:
  206. #if (CHIP == 710)
  207. ; NOTE DSA is corrupt when we arrive here!
  208. #endif
  209. ; Patch the MOVE MEMORY INSTRUCTION such that
  210. ; the destination address is the address of the OLD
  211. ; next pointer.
  212. ;
  213. MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok_patch + 8
  214. DMODE_MEMORY_TO_NCR
  215. ;
  216. ; Move the _contents_ of the next pointer into the DSA register as
  217. ; the next I_T_L or I_T_L_Q tupple to check against the established
  218. ; nexus.
  219. ;
  220. MOVE MEMORY 4, dsa_temp_next, addr_scratch
  221. DMODE_MEMORY_TO_MEMORY
  222. #if (CHIP == 710)
  223. MOVE MEMORY 4, addr_scratch, saved_dsa
  224. MOVE MEMORY 4, saved_dsa, addr_dsa
  225. #else
  226. CALL scratch_to_dsa
  227. #endif
  228. JUMP reselected_check_next
  229. ABSOLUTE dsa_save_data_pointer = 0
  230. ENTRY dsa_code_save_data_pointer
  231. dsa_code_save_data_pointer:
  232. #if (CHIP == 710)
  233. ; When we get here, TEMP has been saved in jump_temp+4, DSA is corrupt
  234. ; We MUST return with DSA correct
  235. MOVE MEMORY 4, jump_temp+4, dsa_temp_addr_saved_pointer
  236. ; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
  237. MOVE MEMORY 24, dsa_temp_addr_residual, dsa_temp_addr_saved_residual
  238. CLEAR ACK
  239. #ifdef DEBUG
  240. INT int_debug_saved
  241. #endif
  242. MOVE MEMORY 4, saved_dsa, addr_dsa
  243. JUMP jump_temp
  244. #else
  245. DMODE_NCR_TO_MEMORY
  246. MOVE MEMORY 4, addr_temp, dsa_temp_addr_saved_pointer
  247. DMODE_MEMORY_TO_MEMORY
  248. ; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
  249. MOVE MEMORY 24, dsa_temp_addr_residual, dsa_temp_addr_saved_residual
  250. CLEAR ACK
  251. #ifdef DEBUG
  252. INT int_debug_saved
  253. #endif
  254. RETURN
  255. #endif
  256. ABSOLUTE dsa_restore_pointers = 0
  257. ENTRY dsa_code_restore_pointers
  258. dsa_code_restore_pointers:
  259. #if (CHIP == 710)
  260. ; TEMP and DSA are corrupt when we get here, but who cares!
  261. MOVE MEMORY 4, dsa_temp_addr_saved_pointer, jump_temp + 4
  262. ; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
  263. MOVE MEMORY 24, dsa_temp_addr_saved_residual, dsa_temp_addr_residual
  264. CLEAR ACK
  265. ; Restore DSA, note we don't care about TEMP
  266. MOVE MEMORY 4, saved_dsa, addr_dsa
  267. #ifdef DEBUG
  268. INT int_debug_restored
  269. #endif
  270. JUMP jump_temp
  271. #else
  272. DMODE_MEMORY_TO_NCR
  273. MOVE MEMORY 4, dsa_temp_addr_saved_pointer, addr_temp
  274. DMODE_MEMORY_TO_MEMORY
  275. ; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
  276. MOVE MEMORY 24, dsa_temp_addr_saved_residual, dsa_temp_addr_residual
  277. CLEAR ACK
  278. #ifdef DEBUG
  279. INT int_debug_restored
  280. #endif
  281. RETURN
  282. #endif
  283. ABSOLUTE dsa_check_reselect = 0
  284. ; dsa_check_reselect determines whether or not the current target and
  285. ; lun match the current DSA
  286. ENTRY dsa_code_check_reselect
  287. dsa_code_check_reselect:
  288. #if (CHIP == 710)
  289. /* Arrives here with DSA correct */
  290. /* Assumes we are always ID 7 */
  291. MOVE LCRC TO SFBR ; LCRC has our ID and his ID bits set
  292. JUMP REL (wrong_dsa), IF NOT dsa_temp_target, AND MASK 0x80
  293. #else
  294. MOVE SSID TO SFBR ; SSID contains 3 bit target ID
  295. ; FIXME : we need to accommodate bit fielded and binary here for '7xx/'8xx chips
  296. JUMP REL (wrong_dsa), IF NOT dsa_temp_target, AND MASK 0xf8
  297. #endif
  298. ;
  299. ; Hack - move to scratch first, since SFBR is not writeable
  300. ; via the CPU and hence a MOVE MEMORY instruction.
  301. ;
  302. DMODE_MEMORY_TO_NCR
  303. MOVE MEMORY 1, reselected_identify, addr_scratch
  304. DMODE_MEMORY_TO_MEMORY
  305. #ifdef BIG_ENDIAN
  306. ; BIG ENDIAN ON MVME16x
  307. MOVE SCRATCH3 TO SFBR
  308. #else
  309. MOVE SCRATCH0 TO SFBR
  310. #endif
  311. ; FIXME : we need to accommodate bit fielded and binary here for '7xx/'8xx chips
  312. ; Are you sure about that? richard@sleepie.demon.co.uk
  313. JUMP REL (wrong_dsa), IF NOT dsa_temp_lun, AND MASK 0xf8
  314. ; Patch the MOVE MEMORY INSTRUCTION such that
  315. ; the source address is the address of this dsa's
  316. ; next pointer.
  317. MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok_patch + 4
  318. CALL reselected_ok
  319. #if (CHIP == 710)
  320. ; Restore DSA following memory moves in reselected_ok
  321. ; dsa_temp_sync doesn't really care about DSA, but it has an
  322. ; optional debug INT so a valid DSA is a good idea.
  323. MOVE MEMORY 4, saved_dsa, addr_dsa
  324. #endif
  325. CALL dsa_temp_sync
  326. ; Release ACK on the IDENTIFY message _after_ we've set the synchronous
  327. ; transfer parameters!
  328. CLEAR ACK
  329. ; Implicitly restore pointers on reselection, so a RETURN
  330. ; will transfer control back to the right spot.
  331. CALL REL (dsa_code_restore_pointers)
  332. RETURN
  333. ENTRY dsa_zero
  334. dsa_zero:
  335. ENTRY dsa_code_template_end
  336. dsa_code_template_end:
  337. ; Perform sanity check for dsa_fields_start == dsa_code_template_end -
  338. ; dsa_zero, puke.
  339. ABSOLUTE dsa_fields_start = 0 ; Sanity marker
  340. ; pad 48 bytes (fix this RSN)
  341. ABSOLUTE dsa_next = 48 ; len 4 Next DSA
  342. ; del 4 Previous DSA address
  343. ABSOLUTE dsa_cmnd = 56 ; len 4 Scsi_Cmnd * for this thread.
  344. ABSOLUTE dsa_select = 60 ; len 4 Device ID, Period, Offset for
  345. ; table indirect select
  346. ABSOLUTE dsa_msgout = 64 ; len 8 table indirect move parameter for
  347. ; select message
  348. ABSOLUTE dsa_cmdout = 72 ; len 8 table indirect move parameter for
  349. ; command
  350. ABSOLUTE dsa_dataout = 80 ; len 4 code pointer for dataout
  351. ABSOLUTE dsa_datain = 84 ; len 4 code pointer for datain
  352. ABSOLUTE dsa_msgin = 88 ; len 8 table indirect move for msgin
  353. ABSOLUTE dsa_status = 96 ; len 8 table indirect move for status byte
  354. ABSOLUTE dsa_msgout_other = 104 ; len 8 table indirect for normal message out
  355. ; (Synchronous transfer negotiation, etc).
  356. ABSOLUTE dsa_end = 112
  357. ABSOLUTE schedule = 0 ; Array of JUMP dsa_begin or JUMP (next),
  358. ; terminated by a call to JUMP wait_reselect
  359. ; Linked lists of DSA structures
  360. ABSOLUTE reconnect_dsa_head = 0 ; Link list of DSAs which can reconnect
  361. ABSOLUTE addr_reconnect_dsa_head = 0 ; Address of variable containing
  362. ; address of reconnect_dsa_head
  363. ; These select the source and destination of a MOVE MEMORY instruction
  364. ABSOLUTE dmode_memory_to_memory = 0x0
  365. ABSOLUTE dmode_memory_to_ncr = 0x0
  366. ABSOLUTE dmode_ncr_to_memory = 0x0
  367. ABSOLUTE addr_scratch = 0x0
  368. ABSOLUTE addr_temp = 0x0
  369. #if (CHIP == 710)
  370. ABSOLUTE saved_dsa = 0x0
  371. ABSOLUTE emulfly = 0x0
  372. ABSOLUTE addr_dsa = 0x0
  373. #endif
  374. #endif /* CHIP != 700 && CHIP != 70066 */
  375. ; Interrupts -
  376. ; MSB indicates type
  377. ; 0 handle error condition
  378. ; 1 handle message
  379. ; 2 handle normal condition
  380. ; 3 debugging interrupt
  381. ; 4 testing interrupt
  382. ; Next byte indicates specific error
  383. ; XXX not yet implemented, I'm not sure if I want to -
  384. ; Next byte indicates the routine the error occurred in
  385. ; The LSB indicates the specific place the error occurred
  386. ABSOLUTE int_err_unexpected_phase = 0x00000000 ; Unexpected phase encountered
  387. ABSOLUTE int_err_selected = 0x00010000 ; SELECTED (nee RESELECTED)
  388. ABSOLUTE int_err_unexpected_reselect = 0x00020000
  389. ABSOLUTE int_err_check_condition = 0x00030000
  390. ABSOLUTE int_err_no_phase = 0x00040000
  391. ABSOLUTE int_msg_wdtr = 0x01000000 ; WDTR message received
  392. ABSOLUTE int_msg_sdtr = 0x01010000 ; SDTR received
  393. ABSOLUTE int_msg_1 = 0x01020000 ; single byte special message
  394. ; received
  395. ABSOLUTE int_norm_select_complete = 0x02000000 ; Select complete, reprogram
  396. ; registers.
  397. ABSOLUTE int_norm_reselect_complete = 0x02010000 ; Nexus established
  398. ABSOLUTE int_norm_command_complete = 0x02020000 ; Command complete
  399. ABSOLUTE int_norm_disconnected = 0x02030000 ; Disconnected
  400. ABSOLUTE int_norm_aborted =0x02040000 ; Aborted *dsa
  401. ABSOLUTE int_norm_reset = 0x02050000 ; Generated BUS reset.
  402. ABSOLUTE int_norm_emulateintfly = 0x02060000 ; 53C710 Emulated intfly
  403. ABSOLUTE int_debug_break = 0x03000000 ; Break point
  404. #ifdef DEBUG
  405. ABSOLUTE int_debug_scheduled = 0x03010000 ; new I/O scheduled
  406. ABSOLUTE int_debug_idle = 0x03020000 ; scheduler is idle
  407. ABSOLUTE int_debug_dsa_loaded = 0x03030000 ; dsa reloaded
  408. ABSOLUTE int_debug_reselected = 0x03040000 ; NCR reselected
  409. ABSOLUTE int_debug_head = 0x03050000 ; issue head overwritten
  410. ABSOLUTE int_debug_disconnected = 0x03060000 ; disconnected
  411. ABSOLUTE int_debug_disconnect_msg = 0x03070000 ; got message to disconnect
  412. ABSOLUTE int_debug_dsa_schedule = 0x03080000 ; in dsa_schedule
  413. ABSOLUTE int_debug_reselect_check = 0x03090000 ; Check for reselection of DSA
  414. ABSOLUTE int_debug_reselected_ok = 0x030a0000 ; Reselection accepted
  415. #endif
  416. ABSOLUTE int_debug_panic = 0x030b0000 ; Panic driver
  417. #ifdef DEBUG
  418. ABSOLUTE int_debug_saved = 0x030c0000 ; save/restore pointers
  419. ABSOLUTE int_debug_restored = 0x030d0000
  420. ABSOLUTE int_debug_sync = 0x030e0000 ; Sanity check synchronous
  421. ; parameters.
  422. ABSOLUTE int_debug_datain = 0x030f0000 ; going into data in phase
  423. ; now.
  424. ABSOLUTE int_debug_check_dsa = 0x03100000 ; Sanity check DSA against
  425. ; SDID.
  426. #endif
  427. ABSOLUTE int_test_1 = 0x04000000 ; Test 1 complete
  428. ABSOLUTE int_test_2 = 0x04010000 ; Test 2 complete
  429. ABSOLUTE int_test_3 = 0x04020000 ; Test 3 complete
  430. ; These should start with 0x05000000, with low bits incrementing for
  431. ; each one.
  432. #ifdef EVENTS
  433. ABSOLUTE int_EVENT_SELECT = 0
  434. ABSOLUTE int_EVENT_DISCONNECT = 0
  435. ABSOLUTE int_EVENT_RESELECT = 0
  436. ABSOLUTE int_EVENT_COMPLETE = 0
  437. ABSOLUTE int_EVENT_IDLE = 0
  438. ABSOLUTE int_EVENT_SELECT_FAILED = 0
  439. ABSOLUTE int_EVENT_BEFORE_SELECT = 0
  440. ABSOLUTE int_EVENT_RESELECT_FAILED = 0
  441. #endif
  442. ABSOLUTE NCR53c7xx_msg_abort = 0 ; Pointer to abort message
  443. ABSOLUTE NCR53c7xx_msg_reject = 0 ; Pointer to reject message
  444. ABSOLUTE NCR53c7xx_zero = 0 ; long with zero in it, use for source
  445. ABSOLUTE NCR53c7xx_sink = 0 ; long to dump worthless data in
  446. ABSOLUTE NOP_insn = 0 ; NOP instruction
  447. ; Pointer to message, potentially multi-byte
  448. ABSOLUTE msg_buf = 0
  449. ; Pointer to holding area for reselection information
  450. ABSOLUTE reselected_identify = 0
  451. ABSOLUTE reselected_tag = 0
  452. ; Request sense command pointer, it's a 6 byte command, should
  453. ; be constant for all commands since we always want 16 bytes of
  454. ; sense and we don't need to change any fields as we did under
  455. ; SCSI-I when we actually cared about the LUN field.
  456. ;EXTERNAL NCR53c7xx_sense ; Request sense command
  457. #if (CHIP != 700) && (CHIP != 70066)
  458. ; dsa_schedule
  459. ; PURPOSE : after a DISCONNECT message has been received, and pointers
  460. ; saved, insert the current DSA structure at the head of the
  461. ; disconnected queue and fall through to the scheduler.
  462. ;
  463. ; CALLS : OK
  464. ;
  465. ; INPUTS : dsa - current DSA structure, reconnect_dsa_head - list
  466. ; of disconnected commands
  467. ;
  468. ; MODIFIES : SCRATCH, reconnect_dsa_head
  469. ;
  470. ; EXITS : always passes control to schedule
  471. ENTRY dsa_schedule
  472. dsa_schedule:
  473. #ifdef DEBUG
  474. INT int_debug_dsa_schedule
  475. #endif
  476. ;
  477. ; Calculate the address of the next pointer within the DSA
  478. ; structure of the command that is currently disconnecting
  479. ;
  480. #if (CHIP == 710)
  481. ; Read what should be the current DSA from memory - actual DSA
  482. ; register is probably corrupt
  483. MOVE MEMORY 4, saved_dsa, addr_scratch
  484. #else
  485. CALL dsa_to_scratch
  486. #endif
  487. MOVE SCRATCH0 + dsa_next TO SCRATCH0
  488. MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
  489. MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
  490. MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
  491. ; Point the next field of this DSA structure at the current disconnected
  492. ; list
  493. DMODE_NCR_TO_MEMORY
  494. MOVE MEMORY 4, addr_scratch, dsa_schedule_insert + 8
  495. DMODE_MEMORY_TO_MEMORY
  496. dsa_schedule_insert:
  497. MOVE MEMORY 4, reconnect_dsa_head, 0
  498. ; And update the head pointer.
  499. #if (CHIP == 710)
  500. ; Read what should be the current DSA from memory - actual DSA
  501. ; register is probably corrupt
  502. MOVE MEMORY 4, saved_dsa, addr_scratch
  503. #else
  504. CALL dsa_to_scratch
  505. #endif
  506. DMODE_NCR_TO_MEMORY
  507. MOVE MEMORY 4, addr_scratch, reconnect_dsa_head
  508. DMODE_MEMORY_TO_MEMORY
  509. /* Temporarily, see what happens. */
  510. #ifndef ORIGINAL
  511. #if (CHIP != 710)
  512. MOVE SCNTL2 & 0x7f TO SCNTL2
  513. #endif
  514. CLEAR ACK
  515. #endif
  516. #if (CHIP == 710)
  517. ; Time to correct DSA following memory move
  518. MOVE MEMORY 4, saved_dsa, addr_dsa
  519. #endif
  520. WAIT DISCONNECT
  521. #ifdef EVENTS
  522. INT int_EVENT_DISCONNECT;
  523. #endif
  524. #ifdef DEBUG
  525. INT int_debug_disconnected
  526. #endif
  527. JUMP schedule
  528. #endif
  529. ;
  530. ; select
  531. ;
  532. ; PURPOSE : establish a nexus for the SCSI command referenced by DSA.
  533. ; On success, the current DSA structure is removed from the issue
  534. ; queue. Usually, this is entered as a fall-through from schedule,
  535. ; although the contingent allegiance handling code will write
  536. ; the select entry address to the DSP to restart a command as a
  537. ; REQUEST SENSE. A message is sent (usually IDENTIFY, although
  538. ; additional SDTR or WDTR messages may be sent). COMMAND OUT
  539. ; is handled.
  540. ;
  541. ; INPUTS : DSA - SCSI command, issue_dsa_head
  542. ;
  543. ; CALLS : NOT OK
  544. ;
  545. ; MODIFIES : SCRATCH, issue_dsa_head
  546. ;
  547. ; EXITS : on reselection or selection, go to select_failed
  548. ; otherwise, RETURN so control is passed back to
  549. ; dsa_begin.
  550. ;
  551. ENTRY select
  552. select:
  553. #ifdef EVENTS
  554. INT int_EVENT_BEFORE_SELECT
  555. #endif
  556. #ifdef DEBUG
  557. INT int_debug_scheduled
  558. #endif
  559. CLEAR TARGET
  560. ; XXX
  561. ;
  562. ; In effect, SELECTION operations are backgrounded, with execution
  563. ; continuing until code which waits for REQ or a fatal interrupt is
  564. ; encountered.
  565. ;
  566. ; So, for more performance, we could overlap the code which removes
  567. ; the command from the NCRs issue queue with the selection, but
  568. ; at this point I don't want to deal with the error recovery.
  569. ;
  570. #if (CHIP != 700) && (CHIP != 70066)
  571. #if (CHIP == 710)
  572. ; Enable selection timer
  573. #ifdef NO_SELECTION_TIMEOUT
  574. MOVE CTEST7 & 0xff TO CTEST7
  575. #else
  576. MOVE CTEST7 & 0xef TO CTEST7
  577. #endif
  578. #endif
  579. SELECT ATN FROM dsa_select, select_failed
  580. JUMP select_msgout, WHEN MSG_OUT
  581. ENTRY select_msgout
  582. select_msgout:
  583. #if (CHIP == 710)
  584. ; Disable selection timer
  585. MOVE CTEST7 | 0x10 TO CTEST7
  586. #endif
  587. MOVE FROM dsa_msgout, WHEN MSG_OUT
  588. #else
  589. ENTRY select_msgout
  590. SELECT ATN 0, select_failed
  591. select_msgout:
  592. MOVE 0, 0, WHEN MSGOUT
  593. #endif
  594. #ifdef EVENTS
  595. INT int_EVENT_SELECT
  596. #endif
  597. RETURN
  598. ;
  599. ; select_done
  600. ;
  601. ; PURPOSE: continue on to normal data transfer; called as the exit
  602. ; point from dsa_begin.
  603. ;
  604. ; INPUTS: dsa
  605. ;
  606. ; CALLS: OK
  607. ;
  608. ;
  609. select_done:
  610. #if (CHIP == 710)
  611. ; NOTE DSA is corrupt when we arrive here!
  612. MOVE MEMORY 4, saved_dsa, addr_dsa
  613. #endif
  614. #ifdef DEBUG
  615. ENTRY select_check_dsa
  616. select_check_dsa:
  617. INT int_debug_check_dsa
  618. #endif
  619. ; After a successful selection, we should get either a CMD phase or
  620. ; some transfer request negotiation message.
  621. JUMP cmdout, WHEN CMD
  622. INT int_err_unexpected_phase, WHEN NOT MSG_IN
  623. select_msg_in:
  624. CALL msg_in, WHEN MSG_IN
  625. JUMP select_msg_in, WHEN MSG_IN
  626. cmdout:
  627. INT int_err_unexpected_phase, WHEN NOT CMD
  628. #if (CHIP == 700)
  629. INT int_norm_selected
  630. #endif
  631. ENTRY cmdout_cmdout
  632. cmdout_cmdout:
  633. #if (CHIP != 700) && (CHIP != 70066)
  634. MOVE FROM dsa_cmdout, WHEN CMD
  635. #else
  636. MOVE 0, 0, WHEN CMD
  637. #endif /* (CHIP != 700) && (CHIP != 70066) */
  638. ;
  639. ; data_transfer
  640. ; other_out
  641. ; other_in
  642. ; other_transfer
  643. ;
  644. ; PURPOSE : handle the main data transfer for a SCSI command in
  645. ; several parts. In the first part, data_transfer, DATA_IN
  646. ; and DATA_OUT phases are allowed, with the user provided
  647. ; code (usually dynamically generated based on the scatter/gather
  648. ; list associated with a SCSI command) called to handle these
  649. ; phases.
  650. ;
  651. ; After control has passed to one of the user provided
  652. ; DATA_IN or DATA_OUT routines, back calls are made to
  653. ; other_transfer_in or other_transfer_out to handle non-DATA IN
  654. ; and DATA OUT phases respectively, with the state of the active
  655. ; data pointer being preserved in TEMP.
  656. ;
  657. ; On completion, the user code passes control to other_transfer
  658. ; which causes DATA_IN and DATA_OUT to result in unexpected_phase
  659. ; interrupts so that data overruns may be trapped.
  660. ;
  661. ; INPUTS : DSA - SCSI command
  662. ;
  663. ; CALLS : OK in data_transfer_start, not ok in other_out and other_in, ok in
  664. ; other_transfer
  665. ;
  666. ; MODIFIES : SCRATCH
  667. ;
  668. ; EXITS : if STATUS IN is detected, signifying command completion,
  669. ; the NCR jumps to command_complete. If MSG IN occurs, a
  670. ; CALL is made to msg_in. Otherwise, other_transfer runs in
  671. ; an infinite loop.
  672. ;
  673. ENTRY data_transfer
  674. data_transfer:
  675. JUMP cmdout_cmdout, WHEN CMD
  676. CALL msg_in, WHEN MSG_IN
  677. INT int_err_unexpected_phase, WHEN MSG_OUT
  678. JUMP do_dataout, WHEN DATA_OUT
  679. JUMP do_datain, WHEN DATA_IN
  680. JUMP command_complete, WHEN STATUS
  681. JUMP data_transfer
  682. ENTRY end_data_transfer
  683. end_data_transfer:
  684. ;
  685. ; FIXME: On NCR53c700 and NCR53c700-66 chips, do_dataout/do_datain
  686. ; should be fixed up whenever the nexus changes so it can point to the
  687. ; correct routine for that command.
  688. ;
  689. #if (CHIP != 700) && (CHIP != 70066)
  690. ; Nasty jump to dsa->dataout
  691. do_dataout:
  692. #if (CHIP == 710)
  693. MOVE MEMORY 4, saved_dsa, addr_scratch
  694. #else
  695. CALL dsa_to_scratch
  696. #endif
  697. MOVE SCRATCH0 + dsa_dataout TO SCRATCH0
  698. MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
  699. MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
  700. MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
  701. DMODE_NCR_TO_MEMORY
  702. MOVE MEMORY 4, addr_scratch, dataout_to_jump + 4
  703. DMODE_MEMORY_TO_MEMORY
  704. dataout_to_jump:
  705. MOVE MEMORY 4, 0, dataout_jump + 4
  706. #if (CHIP == 710)
  707. ; Time to correct DSA following memory move
  708. MOVE MEMORY 4, saved_dsa, addr_dsa
  709. #endif
  710. dataout_jump:
  711. JUMP 0
  712. ; Nasty jump to dsa->dsain
  713. do_datain:
  714. #if (CHIP == 710)
  715. MOVE MEMORY 4, saved_dsa, addr_scratch
  716. #else
  717. CALL dsa_to_scratch
  718. #endif
  719. MOVE SCRATCH0 + dsa_datain TO SCRATCH0
  720. MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
  721. MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
  722. MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
  723. DMODE_NCR_TO_MEMORY
  724. MOVE MEMORY 4, addr_scratch, datain_to_jump + 4
  725. DMODE_MEMORY_TO_MEMORY
  726. ENTRY datain_to_jump
  727. datain_to_jump:
  728. MOVE MEMORY 4, 0, datain_jump + 4
  729. #if (CHIP == 710)
  730. ; Time to correct DSA following memory move
  731. MOVE MEMORY 4, saved_dsa, addr_dsa
  732. #endif
  733. #ifdef DEBUG
  734. INT int_debug_datain
  735. #endif
  736. datain_jump:
  737. JUMP 0
  738. #endif /* (CHIP != 700) && (CHIP != 70066) */
  739. ; Note that other_out and other_in loop until a non-data phase
  740. ; is discovered, so we only execute return statements when we
  741. ; can go on to the next data phase block move statement.
  742. ENTRY other_out
  743. other_out:
  744. #if 0
  745. INT 0x03ffdead
  746. #endif
  747. INT int_err_unexpected_phase, WHEN CMD
  748. JUMP msg_in_restart, WHEN MSG_IN
  749. INT int_err_unexpected_phase, WHEN MSG_OUT
  750. INT int_err_unexpected_phase, WHEN DATA_IN
  751. JUMP command_complete, WHEN STATUS
  752. JUMP other_out, WHEN NOT DATA_OUT
  753. #if (CHIP == 710)
  754. ; TEMP should be OK, as we got here from a call in the user dataout code.
  755. #endif
  756. RETURN
  757. ENTRY other_in
  758. other_in:
  759. #if 0
  760. INT 0x03ffdead
  761. #endif
  762. INT int_err_unexpected_phase, WHEN CMD
  763. JUMP msg_in_restart, WHEN MSG_IN
  764. INT int_err_unexpected_phase, WHEN MSG_OUT
  765. INT int_err_unexpected_phase, WHEN DATA_OUT
  766. JUMP command_complete, WHEN STATUS
  767. JUMP other_in, WHEN NOT DATA_IN
  768. #if (CHIP == 710)
  769. ; TEMP should be OK, as we got here from a call in the user datain code.
  770. #endif
  771. RETURN
  772. ENTRY other_transfer
  773. other_transfer:
  774. INT int_err_unexpected_phase, WHEN CMD
  775. CALL msg_in, WHEN MSG_IN
  776. INT int_err_unexpected_phase, WHEN MSG_OUT
  777. INT int_err_unexpected_phase, WHEN DATA_OUT
  778. INT int_err_unexpected_phase, WHEN DATA_IN
  779. JUMP command_complete, WHEN STATUS
  780. JUMP other_transfer
  781. ;
  782. ; msg_in_restart
  783. ; msg_in
  784. ; munge_msg
  785. ;
  786. ; PURPOSE : process messages from a target. msg_in is called when the
  787. ; caller hasn't read the first byte of the message. munge_message
  788. ; is called when the caller has read the first byte of the message,
  789. ; and left it in SFBR. msg_in_restart is called when the caller
  790. ; hasn't read the first byte of the message, and wishes RETURN
  791. ; to transfer control back to the address of the conditional
  792. ; CALL instruction rather than to the instruction after it.
  793. ;
  794. ; Various int_* interrupts are generated when the host system
  795. ; needs to intervene, as is the case with SDTR, WDTR, and
  796. ; INITIATE RECOVERY messages.
  797. ;
  798. ; When the host system handles one of these interrupts,
  799. ; it can respond by reentering at reject_message,
  800. ; which rejects the message and returns control to
  801. ; the caller of msg_in or munge_msg, accept_message
  802. ; which clears ACK and returns control, or reply_message
  803. ; which sends the message pointed to by the DSA
  804. ; msgout_other table indirect field.
  805. ;
  806. ; DISCONNECT messages are handled by moving the command
  807. ; to the reconnect_dsa_queue.
  808. #if (CHIP == 710)
  809. ; NOTE: DSA should be valid when we get here - we cannot save both it
  810. ; and TEMP in this routine.
  811. #endif
  812. ;
  813. ; INPUTS : DSA - SCSI COMMAND, SFBR - first byte of message (munge_msg
  814. ; only)
  815. ;
  816. ; CALLS : NO. The TEMP register isn't backed up to allow nested calls.
  817. ;
  818. ; MODIFIES : SCRATCH, DSA on DISCONNECT
  819. ;
  820. ; EXITS : On receipt of SAVE DATA POINTER, RESTORE POINTERS,
  821. ; and normal return from message handlers running under
  822. ; Linux, control is returned to the caller. Receipt
  823. ; of DISCONNECT messages pass control to dsa_schedule.
  824. ;
  825. ENTRY msg_in_restart
  826. msg_in_restart:
  827. ; XXX - hackish
  828. ;
  829. ; Since it's easier to debug changes to the statically
  830. ; compiled code, rather than the dynamically generated
  831. ; stuff, such as
  832. ;
  833. ; MOVE x, y, WHEN data_phase
  834. ; CALL other_z, WHEN NOT data_phase
  835. ; MOVE x, y, WHEN data_phase
  836. ;
  837. ; I'd like to have certain routines (notably the message handler)
  838. ; restart on the conditional call rather than the next instruction.
  839. ;
  840. ; So, subtract 8 from the return address
  841. MOVE TEMP0 + 0xf8 TO TEMP0
  842. MOVE TEMP1 + 0xff TO TEMP1 WITH CARRY
  843. MOVE TEMP2 + 0xff TO TEMP2 WITH CARRY
  844. MOVE TEMP3 + 0xff TO TEMP3 WITH CARRY
  845. ENTRY msg_in
  846. msg_in:
  847. MOVE 1, msg_buf, WHEN MSG_IN
  848. munge_msg:
  849. JUMP munge_extended, IF 0x01 ; EXTENDED MESSAGE
  850. JUMP munge_2, IF 0x20, AND MASK 0xdf ; two byte message
  851. ;
  852. ; XXX - I've seen a handful of broken SCSI devices which fail to issue
  853. ; a SAVE POINTERS message before disconnecting in the middle of
  854. ; a transfer, assuming that the DATA POINTER will be implicitly
  855. ; restored.
  856. ;
  857. ; Historically, I've often done an implicit save when the DISCONNECT
  858. ; message is processed. We may want to consider having the option of
  859. ; doing that here.
  860. ;
  861. JUMP munge_save_data_pointer, IF 0x02 ; SAVE DATA POINTER
  862. JUMP munge_restore_pointers, IF 0x03 ; RESTORE POINTERS
  863. JUMP munge_disconnect, IF 0x04 ; DISCONNECT
  864. INT int_msg_1, IF 0x07 ; MESSAGE REJECT
  865. INT int_msg_1, IF 0x0f ; INITIATE RECOVERY
  866. #ifdef EVENTS
  867. INT int_EVENT_SELECT_FAILED
  868. #endif
  869. JUMP reject_message
  870. munge_2:
  871. JUMP reject_message
  872. ;
  873. ; The SCSI standard allows targets to recover from transient
  874. ; error conditions by backing up the data pointer with a
  875. ; RESTORE POINTERS message.
  876. ;
  877. ; So, we must save and restore the _residual_ code as well as
  878. ; the current instruction pointer. Because of this messiness,
  879. ; it is simpler to put dynamic code in the dsa for this and to
  880. ; just do a simple jump down there.
  881. ;
  882. munge_save_data_pointer:
  883. #if (CHIP == 710)
  884. ; We have something in TEMP here, so first we must save that
  885. MOVE TEMP0 TO SFBR
  886. MOVE SFBR TO SCRATCH0
  887. MOVE TEMP1 TO SFBR
  888. MOVE SFBR TO SCRATCH1
  889. MOVE TEMP2 TO SFBR
  890. MOVE SFBR TO SCRATCH2
  891. MOVE TEMP3 TO SFBR
  892. MOVE SFBR TO SCRATCH3
  893. MOVE MEMORY 4, addr_scratch, jump_temp + 4
  894. ; Now restore DSA
  895. MOVE MEMORY 4, saved_dsa, addr_dsa
  896. #endif
  897. MOVE DSA0 + dsa_save_data_pointer TO SFBR
  898. MOVE SFBR TO SCRATCH0
  899. MOVE DSA1 + 0xff TO SFBR WITH CARRY
  900. MOVE SFBR TO SCRATCH1
  901. MOVE DSA2 + 0xff TO SFBR WITH CARRY
  902. MOVE SFBR TO SCRATCH2
  903. MOVE DSA3 + 0xff TO SFBR WITH CARRY
  904. MOVE SFBR TO SCRATCH3
  905. DMODE_NCR_TO_MEMORY
  906. MOVE MEMORY 4, addr_scratch, jump_dsa_save + 4
  907. DMODE_MEMORY_TO_MEMORY
  908. jump_dsa_save:
  909. JUMP 0
  910. munge_restore_pointers:
  911. #if (CHIP == 710)
  912. ; The code at dsa_restore_pointers will RETURN, but we don't care
  913. ; about TEMP here, as it will overwrite it anyway.
  914. #endif
  915. MOVE DSA0 + dsa_restore_pointers TO SFBR
  916. MOVE SFBR TO SCRATCH0
  917. MOVE DSA1 + 0xff TO SFBR WITH CARRY
  918. MOVE SFBR TO SCRATCH1
  919. MOVE DSA2 + 0xff TO SFBR WITH CARRY
  920. MOVE SFBR TO SCRATCH2
  921. MOVE DSA3 + 0xff TO SFBR WITH CARRY
  922. MOVE SFBR TO SCRATCH3
  923. DMODE_NCR_TO_MEMORY
  924. MOVE MEMORY 4, addr_scratch, jump_dsa_restore + 4
  925. DMODE_MEMORY_TO_MEMORY
  926. jump_dsa_restore:
  927. JUMP 0
  928. munge_disconnect:
  929. #ifdef DEBUG
  930. INT int_debug_disconnect_msg
  931. #endif
  932. /*
  933. * Before, we overlapped processing with waiting for disconnect, but
  934. * debugging was beginning to appear messy. Temporarily move things
  935. * to just before the WAIT DISCONNECT.
  936. */
  937. #ifdef ORIGINAL
  938. #if (CHIP == 710)
  939. ; Following clears Unexpected Disconnect bit. What do we do?
  940. #else
  941. MOVE SCNTL2 & 0x7f TO SCNTL2
  942. #endif
  943. CLEAR ACK
  944. #endif
  945. #if (CHIP != 700) && (CHIP != 70066)
  946. JUMP dsa_schedule
  947. #else
  948. WAIT DISCONNECT
  949. INT int_norm_disconnected
  950. #endif
  951. munge_extended:
  952. CLEAR ACK
  953. INT int_err_unexpected_phase, WHEN NOT MSG_IN
  954. MOVE 1, msg_buf + 1, WHEN MSG_IN
  955. JUMP munge_extended_2, IF 0x02
  956. JUMP munge_extended_3, IF 0x03
  957. JUMP reject_message
  958. munge_extended_2:
  959. CLEAR ACK
  960. MOVE 1, msg_buf + 2, WHEN MSG_IN
  961. JUMP reject_message, IF NOT 0x02 ; Must be WDTR
  962. CLEAR ACK
  963. MOVE 1, msg_buf + 3, WHEN MSG_IN
  964. INT int_msg_wdtr
  965. munge_extended_3:
  966. CLEAR ACK
  967. MOVE 1, msg_buf + 2, WHEN MSG_IN
  968. JUMP reject_message, IF NOT 0x01 ; Must be SDTR
  969. CLEAR ACK
  970. MOVE 2, msg_buf + 3, WHEN MSG_IN
  971. INT int_msg_sdtr
  972. ENTRY reject_message
  973. reject_message:
  974. SET ATN
  975. CLEAR ACK
  976. MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT
  977. RETURN
  978. ENTRY accept_message
  979. accept_message:
  980. CLEAR ATN
  981. CLEAR ACK
  982. RETURN
  983. ENTRY respond_message
  984. respond_message:
  985. SET ATN
  986. CLEAR ACK
  987. MOVE FROM dsa_msgout_other, WHEN MSG_OUT
  988. RETURN
  989. ;
  990. ; command_complete
  991. ;
  992. ; PURPOSE : handle command termination when STATUS IN is detected by reading
  993. ; a status byte followed by a command termination message.
  994. ;
  995. ; Normal termination results in an INTFLY instruction, and
  996. ; the host system can pick out which command terminated by
  997. ; examining the MESSAGE and STATUS buffers of all currently
  998. ; executing commands;
  999. ;
  1000. ; Abnormal (CHECK_CONDITION) termination results in an
  1001. ; int_err_check_condition interrupt so that a REQUEST SENSE
  1002. ; command can be issued out-of-order so that no other command
  1003. ; clears the contingent allegiance condition.
  1004. ;
  1005. ;
  1006. ; INPUTS : DSA - command
  1007. ;
  1008. ; CALLS : OK
  1009. ;
  1010. ; EXITS : On successful termination, control is passed to schedule.
  1011. ; On abnormal termination, the user will usually modify the
  1012. ; DSA fields and corresponding buffers and return control
  1013. ; to select.
  1014. ;
  1015. ENTRY command_complete
  1016. command_complete:
  1017. MOVE FROM dsa_status, WHEN STATUS
  1018. #if (CHIP != 700) && (CHIP != 70066)
  1019. MOVE SFBR TO SCRATCH0 ; Save status
  1020. #endif /* (CHIP != 700) && (CHIP != 70066) */
  1021. ENTRY command_complete_msgin
  1022. command_complete_msgin:
  1023. MOVE FROM dsa_msgin, WHEN MSG_IN
  1024. ; Indicate that we should be expecting a disconnect
  1025. #if (CHIP != 710)
  1026. MOVE SCNTL2 & 0x7f TO SCNTL2
  1027. #else
  1028. ; Above code cleared the Unexpected Disconnect bit, what do we do?
  1029. #endif
  1030. CLEAR ACK
  1031. #if (CHIP != 700) && (CHIP != 70066)
  1032. WAIT DISCONNECT
  1033. ;
  1034. ; The SCSI specification states that when a UNIT ATTENTION condition
  1035. ; is pending, as indicated by a CHECK CONDITION status message,
  1036. ; the target shall revert to asynchronous transfers. Since
  1037. ; synchronous transfers parameters are maintained on a per INITIATOR/TARGET
  1038. ; basis, and returning control to our scheduler could work on a command
  1039. ; running on another lun on that target using the old parameters, we must
  1040. ; interrupt the host processor to get them changed, or change them ourselves.
  1041. ;
  1042. ; Once SCSI-II tagged queueing is implemented, things will be even more
  1043. ; hairy, since contingent allegiance conditions exist on a per-target/lun
  1044. ; basis, and issuing a new command with a different tag would clear it.
  1045. ; In these cases, we must interrupt the host processor to get a request
  1046. ; added to the HEAD of the queue with the request sense command, or we
  1047. ; must automatically issue the request sense command.
  1048. #if 0
  1049. MOVE SCRATCH0 TO SFBR
  1050. JUMP command_failed, IF 0x02
  1051. #endif
  1052. #if (CHIP == 710)
  1053. #if defined(MVME16x_INTFLY)
  1054. ; For MVME16x (ie CHIP=710) we will force an INTFLY by triggering a software
  1055. ; interrupt (SW7). We can use SCRATCH, as we are about to jump to
  1056. ; schedule, which corrupts it anyway. Will probably remove this later,
  1057. ; but want to check performance effects first.
  1058. #define INTFLY_ADDR 0xfff40070
  1059. MOVE 0 TO SCRATCH0
  1060. MOVE 0x80 TO SCRATCH1
  1061. MOVE 0 TO SCRATCH2
  1062. MOVE 0 TO SCRATCH3
  1063. MOVE MEMORY 4, addr_scratch, INTFLY_ADDR
  1064. #else
  1065. INT int_norm_emulateintfly
  1066. #endif
  1067. #else
  1068. INTFLY
  1069. #endif
  1070. #endif /* (CHIP != 700) && (CHIP != 70066) */
  1071. #if (CHIP == 710)
  1072. ; Time to correct DSA following memory move
  1073. MOVE MEMORY 4, saved_dsa, addr_dsa
  1074. #endif
  1075. #ifdef EVENTS
  1076. INT int_EVENT_COMPLETE
  1077. #endif
  1078. #if (CHIP != 700) && (CHIP != 70066)
  1079. JUMP schedule
  1080. command_failed:
  1081. INT int_err_check_condition
  1082. #else
  1083. INT int_norm_command_complete
  1084. #endif
  1085. ;
  1086. ; wait_reselect
  1087. ;
  1088. ; PURPOSE : This is essentially the idle routine, where control lands
  1089. ; when there are no new processes to schedule. wait_reselect
  1090. ; waits for reselection, selection, and new commands.
  1091. ;
  1092. ; When a successful reselection occurs, with the aid
  1093. ; of fixed up code in each DSA, wait_reselect walks the
  1094. ; reconnect_dsa_queue, asking each dsa if the target ID
  1095. ; and LUN match its.
  1096. ;
  1097. ; If a match is found, a call is made back to reselected_ok,
  1098. ; which through the miracles of self modifying code, extracts
  1099. ; the found DSA from the reconnect_dsa_queue and then
  1100. ; returns control to the DSAs thread of execution.
  1101. ;
  1102. ; INPUTS : NONE
  1103. ;
  1104. ; CALLS : OK
  1105. ;
  1106. ; MODIFIES : DSA,
  1107. ;
  1108. ; EXITS : On successful reselection, control is returned to the
  1109. ; DSA which called reselected_ok. If the WAIT RESELECT
  1110. ; was interrupted by a new commands arrival signaled by
  1111. ; SIG_P, control is passed to schedule. If the NCR is
  1112. ; selected, the host system is interrupted with an
  1113. ; int_err_selected which is usually responded to by
  1114. ; setting DSP to the target_abort address.
  1115. ENTRY wait_reselect
  1116. wait_reselect:
  1117. #ifdef EVENTS
  1118. int int_EVENT_IDLE
  1119. #endif
  1120. #ifdef DEBUG
  1121. int int_debug_idle
  1122. #endif
  1123. WAIT RESELECT wait_reselect_failed
  1124. reselected:
  1125. #ifdef EVENTS
  1126. int int_EVENT_RESELECT
  1127. #endif
  1128. CLEAR TARGET
  1129. DMODE_MEMORY_TO_MEMORY
  1130. ; Read all data needed to reestablish the nexus -
  1131. MOVE 1, reselected_identify, WHEN MSG_IN
  1132. ; We used to CLEAR ACK here.
  1133. #if (CHIP != 700) && (CHIP != 70066)
  1134. #ifdef DEBUG
  1135. int int_debug_reselected
  1136. #endif
  1137. ; Point DSA at the current head of the disconnected queue.
  1138. DMODE_MEMORY_TO_NCR
  1139. MOVE MEMORY 4, reconnect_dsa_head, addr_scratch
  1140. DMODE_MEMORY_TO_MEMORY
  1141. #if (CHIP == 710)
  1142. MOVE MEMORY 4, addr_scratch, saved_dsa
  1143. #else
  1144. CALL scratch_to_dsa
  1145. #endif
  1146. ; Fix the update-next pointer so that the reconnect_dsa_head
  1147. ; pointer is the one that will be updated if this DSA is a hit
  1148. ; and we remove it from the queue.
  1149. MOVE MEMORY 4, addr_reconnect_dsa_head, reselected_ok_patch + 8
  1150. #if (CHIP == 710)
  1151. ; Time to correct DSA following memory move
  1152. MOVE MEMORY 4, saved_dsa, addr_dsa
  1153. #endif
  1154. ENTRY reselected_check_next
  1155. reselected_check_next:
  1156. #ifdef DEBUG
  1157. INT int_debug_reselect_check
  1158. #endif
  1159. ; Check for a NULL pointer.
  1160. MOVE DSA0 TO SFBR
  1161. JUMP reselected_not_end, IF NOT 0
  1162. MOVE DSA1 TO SFBR
  1163. JUMP reselected_not_end, IF NOT 0
  1164. MOVE DSA2 TO SFBR
  1165. JUMP reselected_not_end, IF NOT 0
  1166. MOVE DSA3 TO SFBR
  1167. JUMP reselected_not_end, IF NOT 0
  1168. INT int_err_unexpected_reselect
  1169. reselected_not_end:
  1170. ;
  1171. ; XXX the ALU is only eight bits wide, and the assembler
  1172. ; wont do the dirt work for us. As long as dsa_check_reselect
  1173. ; is negative, we need to sign extend with 1 bits to the full
  1174. ; 32 bit width of the address.
  1175. ;
  1176. ; A potential work around would be to have a known alignment
  1177. ; of the DSA structure such that the base address plus
  1178. ; dsa_check_reselect doesn't require carrying from bytes
  1179. ; higher than the LSB.
  1180. ;
  1181. MOVE DSA0 TO SFBR
  1182. MOVE SFBR + dsa_check_reselect TO SCRATCH0
  1183. MOVE DSA1 TO SFBR
  1184. MOVE SFBR + 0xff TO SCRATCH1 WITH CARRY
  1185. MOVE DSA2 TO SFBR
  1186. MOVE SFBR + 0xff TO SCRATCH2 WITH CARRY
  1187. MOVE DSA3 TO SFBR
  1188. MOVE SFBR + 0xff TO SCRATCH3 WITH CARRY
  1189. DMODE_NCR_TO_MEMORY
  1190. MOVE MEMORY 4, addr_scratch, reselected_check + 4
  1191. DMODE_MEMORY_TO_MEMORY
  1192. #if (CHIP == 710)
  1193. ; Time to correct DSA following memory move
  1194. MOVE MEMORY 4, saved_dsa, addr_dsa
  1195. #endif
  1196. reselected_check:
  1197. JUMP 0
  1198. ;
  1199. ;
  1200. #if (CHIP == 710)
  1201. ; We have problems here - the memory move corrupts TEMP and DSA. This
  1202. ; routine is called from DSA code, and patched from many places. Scratch
  1203. ; is probably free when it is called.
  1204. ; We have to:
  1205. ; copy temp to scratch, one byte at a time
  1206. ; write scratch to patch a jump in place of the return
  1207. ; do the move memory
  1208. ; jump to the patched in return address
  1209. ; DSA is corrupt when we get here, and can be left corrupt
  1210. ENTRY reselected_ok
  1211. reselected_ok:
  1212. MOVE TEMP0 TO SFBR
  1213. MOVE SFBR TO SCRATCH0
  1214. MOVE TEMP1 TO SFBR
  1215. MOVE SFBR TO SCRATCH1
  1216. MOVE TEMP2 TO SFBR
  1217. MOVE SFBR TO SCRATCH2
  1218. MOVE TEMP3 TO SFBR
  1219. MOVE SFBR TO SCRATCH3
  1220. MOVE MEMORY 4, addr_scratch, reselected_ok_jump + 4
  1221. reselected_ok_patch:
  1222. MOVE MEMORY 4, 0, 0
  1223. reselected_ok_jump:
  1224. JUMP 0
  1225. #else
  1226. ENTRY reselected_ok
  1227. reselected_ok:
  1228. reselected_ok_patch:
  1229. MOVE MEMORY 4, 0, 0 ; Patched : first word
  1230. ; is address of
  1231. ; successful dsa_next
  1232. ; Second word is last
  1233. ; unsuccessful dsa_next,
  1234. ; starting with
  1235. ; dsa_reconnect_head
  1236. ; We used to CLEAR ACK here.
  1237. #ifdef DEBUG
  1238. INT int_debug_reselected_ok
  1239. #endif
  1240. #ifdef DEBUG
  1241. INT int_debug_check_dsa
  1242. #endif
  1243. RETURN ; Return control to where
  1244. #endif
  1245. #else
  1246. INT int_norm_reselected
  1247. #endif /* (CHIP != 700) && (CHIP != 70066) */
  1248. selected:
  1249. INT int_err_selected;
  1250. ;
  1251. ; A select or reselect failure can be caused by one of two conditions :
  1252. ; 1. SIG_P was set. This will be the case if the user has written
  1253. ; a new value to a previously NULL head of the issue queue.
  1254. ;
  1255. ; 2. The NCR53c810 was selected or reselected by another device.
  1256. ;
  1257. ; 3. The bus was already busy since we were selected or reselected
  1258. ; before starting the command.
  1259. wait_reselect_failed:
  1260. #ifdef EVENTS
  1261. INT int_EVENT_RESELECT_FAILED
  1262. #endif
  1263. ; Check selected bit.
  1264. #if (CHIP == 710)
  1265. ; Must work out how to tell if we are selected....
  1266. #else
  1267. MOVE SIST0 & 0x20 TO SFBR
  1268. JUMP selected, IF 0x20
  1269. #endif
  1270. ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
  1271. MOVE CTEST2 & 0x40 TO SFBR
  1272. JUMP schedule, IF 0x40
  1273. ; Check connected bit.
  1274. ; FIXME: this needs to change if we support target mode
  1275. MOVE ISTAT & 0x08 TO SFBR
  1276. JUMP reselected, IF 0x08
  1277. ; FIXME : Something bogus happened, and we shouldn't fail silently.
  1278. #if 0
  1279. JUMP schedule
  1280. #else
  1281. INT int_debug_panic
  1282. #endif
  1283. select_failed:
  1284. #if (CHIP == 710)
  1285. ; Disable selection timer
  1286. MOVE CTEST7 | 0x10 TO CTEST7
  1287. #endif
  1288. #ifdef EVENTS
  1289. int int_EVENT_SELECT_FAILED
  1290. #endif
  1291. ; Otherwise, mask the selected and reselected bits off SIST0
  1292. #if (CHIP ==710)
  1293. ; Let's assume we don't get selected for now
  1294. MOVE SSTAT0 & 0x10 TO SFBR
  1295. #else
  1296. MOVE SIST0 & 0x30 TO SFBR
  1297. JUMP selected, IF 0x20
  1298. #endif
  1299. JUMP reselected, IF 0x10
  1300. ; If SIGP is set, the user just gave us another command, and
  1301. ; we should restart or return to the scheduler.
  1302. ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
  1303. MOVE CTEST2 & 0x40 TO SFBR
  1304. JUMP select, IF 0x40
  1305. ; Check connected bit.
  1306. ; FIXME: this needs to change if we support target mode
  1307. ; FIXME: is this really necessary?
  1308. MOVE ISTAT & 0x08 TO SFBR
  1309. JUMP reselected, IF 0x08
  1310. ; FIXME : Something bogus happened, and we shouldn't fail silently.
  1311. #if 0
  1312. JUMP schedule
  1313. #else
  1314. INT int_debug_panic
  1315. #endif
  1316. ;
  1317. ; test_1
  1318. ; test_2
  1319. ;
  1320. ; PURPOSE : run some verification tests on the NCR. test_1
  1321. ; copies test_src to test_dest and interrupts the host
  1322. ; processor, testing for cache coherency and interrupt
  1323. ; problems in the processes.
  1324. ;
  1325. ; test_2 runs a command with offsets relative to the
  1326. ; DSA on entry, and is useful for miscellaneous experimentation.
  1327. ;
  1328. ; Verify that interrupts are working correctly and that we don't
  1329. ; have a cache invalidation problem.
  1330. ABSOLUTE test_src = 0, test_dest = 0
  1331. ENTRY test_1
  1332. test_1:
  1333. MOVE MEMORY 4, test_src, test_dest
  1334. INT int_test_1
  1335. ;
  1336. ; Run arbitrary commands, with test code establishing a DSA
  1337. ;
  1338. ENTRY test_2
  1339. test_2:
  1340. CLEAR TARGET
  1341. #if (CHIP == 710)
  1342. ; Enable selection timer
  1343. #ifdef NO_SELECTION_TIMEOUT
  1344. MOVE CTEST7 & 0xff TO CTEST7
  1345. #else
  1346. MOVE CTEST7 & 0xef TO CTEST7
  1347. #endif
  1348. #endif
  1349. SELECT ATN FROM 0, test_2_fail
  1350. JUMP test_2_msgout, WHEN MSG_OUT
  1351. ENTRY test_2_msgout
  1352. test_2_msgout:
  1353. #if (CHIP == 710)
  1354. ; Disable selection timer
  1355. MOVE CTEST7 | 0x10 TO CTEST7
  1356. #endif
  1357. MOVE FROM 8, WHEN MSG_OUT
  1358. MOVE FROM 16, WHEN CMD
  1359. MOVE FROM 24, WHEN DATA_IN
  1360. MOVE FROM 32, WHEN STATUS
  1361. MOVE FROM 40, WHEN MSG_IN
  1362. #if (CHIP != 710)
  1363. MOVE SCNTL2 & 0x7f TO SCNTL2
  1364. #endif
  1365. CLEAR ACK
  1366. WAIT DISCONNECT
  1367. test_2_fail:
  1368. #if (CHIP == 710)
  1369. ; Disable selection timer
  1370. MOVE CTEST7 | 0x10 TO CTEST7
  1371. #endif
  1372. INT int_test_2
  1373. ENTRY debug_break
  1374. debug_break:
  1375. INT int_debug_break
  1376. ;
  1377. ; initiator_abort
  1378. ; target_abort
  1379. ;
  1380. ; PURPOSE : Abort the currently established nexus from with initiator
  1381. ; or target mode.
  1382. ;
  1383. ;
  1384. ENTRY target_abort
  1385. target_abort:
  1386. SET TARGET
  1387. DISCONNECT
  1388. CLEAR TARGET
  1389. JUMP schedule
  1390. ENTRY initiator_abort
  1391. initiator_abort:
  1392. SET ATN
  1393. ;
  1394. ; The SCSI-I specification says that targets may go into MSG out at
  1395. ; their leisure upon receipt of the ATN single. On all versions of the
  1396. ; specification, we can't change phases until REQ transitions true->false,
  1397. ; so we need to sink/source one byte of data to allow the transition.
  1398. ;
  1399. ; For the sake of safety, we'll only source one byte of data in all
  1400. ; cases, but to accommodate the SCSI-I dain bramage, we'll sink an
  1401. ; arbitrary number of bytes.
  1402. JUMP spew_cmd, WHEN CMD
  1403. JUMP eat_msgin, WHEN MSG_IN
  1404. JUMP eat_datain, WHEN DATA_IN
  1405. JUMP eat_status, WHEN STATUS
  1406. JUMP spew_dataout, WHEN DATA_OUT
  1407. JUMP sated
  1408. spew_cmd:
  1409. MOVE 1, NCR53c7xx_zero, WHEN CMD
  1410. JUMP sated
  1411. eat_msgin:
  1412. MOVE 1, NCR53c7xx_sink, WHEN MSG_IN
  1413. JUMP eat_msgin, WHEN MSG_IN
  1414. JUMP sated
  1415. eat_status:
  1416. MOVE 1, NCR53c7xx_sink, WHEN STATUS
  1417. JUMP eat_status, WHEN STATUS
  1418. JUMP sated
  1419. eat_datain:
  1420. MOVE 1, NCR53c7xx_sink, WHEN DATA_IN
  1421. JUMP eat_datain, WHEN DATA_IN
  1422. JUMP sated
  1423. spew_dataout:
  1424. MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT
  1425. sated:
  1426. #if (CHIP != 710)
  1427. MOVE SCNTL2 & 0x7f TO SCNTL2
  1428. #endif
  1429. MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
  1430. WAIT DISCONNECT
  1431. INT int_norm_aborted
  1432. #if (CHIP != 710)
  1433. ;
  1434. ; dsa_to_scratch
  1435. ; scratch_to_dsa
  1436. ;
  1437. ; PURPOSE :
  1438. ; The NCR chips cannot do a move memory instruction with the DSA register
  1439. ; as the source or destination. So, we provide a couple of subroutines
  1440. ; that let us switch between the DSA register and scratch register.
  1441. ;
  1442. ; Memory moves to/from the DSPS register also don't work, but we
  1443. ; don't use them.
  1444. ;
  1445. ;
  1446. dsa_to_scratch:
  1447. MOVE DSA0 TO SFBR
  1448. MOVE SFBR TO SCRATCH0
  1449. MOVE DSA1 TO SFBR
  1450. MOVE SFBR TO SCRATCH1
  1451. MOVE DSA2 TO SFBR
  1452. MOVE SFBR TO SCRATCH2
  1453. MOVE DSA3 TO SFBR
  1454. MOVE SFBR TO SCRATCH3
  1455. RETURN
  1456. scratch_to_dsa:
  1457. MOVE SCRATCH0 TO SFBR
  1458. MOVE SFBR TO DSA0
  1459. MOVE SCRATCH1 TO SFBR
  1460. MOVE SFBR TO DSA1
  1461. MOVE SCRATCH2 TO SFBR
  1462. MOVE SFBR TO DSA2
  1463. MOVE SCRATCH3 TO SFBR
  1464. MOVE SFBR TO DSA3
  1465. RETURN
  1466. #endif
  1467. #if (CHIP == 710)
  1468. ; Little patched jump, used to overcome problems with TEMP getting
  1469. ; corrupted on memory moves.
  1470. jump_temp:
  1471. JUMP 0
  1472. #endif