tbipcx.S 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. /*
  2. * tbipcx.S
  3. *
  4. * Copyright (C) 2001, 2002, 2007, 2009, 2012 Imagination Technologies.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it under
  7. * the terms of the GNU General Public License version 2 as published by the
  8. * Free Software Foundation.
  9. *
  10. * Asyncronous trigger handling including exceptions
  11. */
  12. .file "tbipcx.S"
  13. #include <asm/metag_regs.h>
  14. #include <asm/tbx.h>
  15. /* BEGIN HACK */
  16. /* define these for now while doing inital conversion to GAS
  17. will fix properly later */
  18. /* Signal identifiers always have the TBID_SIGNAL_BIT set and contain the
  19. following related bit-fields */
  20. #define TBID_SIGNUM_S 2
  21. /* END HACK */
  22. #ifdef METAC_1_0
  23. /* Ax.4 is saved in TBICTX */
  24. #define A0_4 ,A0.4
  25. #else
  26. /* Ax.4 is NOT saved in TBICTX */
  27. #define A0_4
  28. #endif
  29. /* Size of the TBICTX structure */
  30. #define TBICTX_BYTES ((TBICTX_AX_REGS*8)+TBICTX_AX)
  31. #ifdef METAC_1_1
  32. #ifndef BOOTROM
  33. #ifndef SPECIAL_BUILD
  34. /* Jump straight into the boot ROM version of this code */
  35. #define CODE_USES_BOOTROM
  36. #endif
  37. #endif
  38. #endif
  39. /* Define space needed for CATCH buffer state in traditional units */
  40. #define CATCH_ENTRIES 5
  41. #define CATCH_ENTRY_BYTES 16
  42. #ifndef CODE_USES_BOOTROM
  43. #define A0GblIStP A0.15 /* PTBICTX for current thread in PRIV system */
  44. #define A1GblIGbP A1.15 /* Interrupt A1GbP value in PRIV system */
  45. #endif
  46. /*
  47. * TBIRES __TBIASyncTrigger( TBIRES State )
  48. */
  49. .text
  50. .balign 4
  51. .global ___TBIASyncTrigger
  52. .type ___TBIASyncTrigger,function
  53. ___TBIASyncTrigger:
  54. #ifdef CODE_USES_BOOTROM
  55. MOVT D0Re0,#HI(LINCORE_BASE)
  56. JUMP D0Re0,#0xA0
  57. #else
  58. MOV D0FrT,A0FrP /* Boing entry sequence */
  59. ADD A0FrP,A0StP,#0
  60. SETL [A0StP++],D0FrT,D1RtP
  61. MOV D0Re0,PCX /* Check for repeat call */
  62. MOVT D0FrT,#HI(___TBIBoingRTI+4)
  63. ADD D0FrT,D0FrT,#LO(___TBIBoingRTI+4)
  64. CMP D0Re0,D0FrT
  65. BEQ ___TBIBoingExit /* Already set up - come out */
  66. ADD D1Ar1,D1Ar1,#7 /* PRIV system stack here */
  67. MOV A0.2,A0StP /* else push context here */
  68. MOVS D0Re0,D0Ar2 /* Return in user mode? */
  69. ANDMB D1Ar1,D1Ar1,#0xfff8 /* align priv stack to 64-bit */
  70. MOV D1Re0,D1Ar1 /* and set result to arg */
  71. MOVMI A0.2,D1Ar1 /* use priv stack if PRIV set */
  72. /*
  73. * Generate an initial TBICTX to return to our own current call context
  74. */
  75. MOVT D1Ar5,#HI(___TBIBoingExit) /* Go here to return */
  76. ADD D1Ar5,D1Ar5,#LO(___TBIBoingExit)
  77. ADD A0.3,A0.2,#TBICTX_DX /* DX Save area */
  78. ANDT D0Ar2,D0Ar2,#TBICTX_PRIV_BIT /* Extract PRIV bit */
  79. MOVT D0Ar6,#TBICTX_SOFT_BIT /* Only soft thread state */
  80. ADD D0Ar6,D0Ar6,D0Ar2 /* Add in PRIV bit if requested */
  81. SETL [A0.2],D0Ar6,D1Ar5 /* Push header fields */
  82. ADD D0FrT,A0.2,#TBICTX_AX /* Address AX save area */
  83. MSETL [A0.3],D0Re0,D0Ar6,D0Ar4,D0Ar2,D0FrT,D0.5,D0.6,D0.7
  84. MOV D0Ar6,#0
  85. MOV D1Ar5,#0
  86. SETL [A0.3++],D0Ar6,D1Ar5 /* Zero CT register states */
  87. SETL [A0.3++],D0Ar6,D1Ar5
  88. MSETL [D0FrT],A0StP,A0FrP,A0.2,A0.3 A0_4 /* Save AX regs */
  89. MOV A0FrP,A0.2 /* Restore me! */
  90. B ___TBIResume
  91. .size ___TBIASyncTrigger,.-___TBIASyncTrigger
  92. /*
  93. * Optimised return to handler for META Core
  94. */
  95. ___TBIBoingRTH:
  96. RTH /* Go to background level */
  97. MOVT A0.2, #HI($Lpcx_target)
  98. ADD A0.2,A0.2,#LO($Lpcx_target)
  99. MOV PCX,A0.2 /* Setup PCX for interrupts */
  100. MOV PC,D1Re0 /* Jump to handler */
  101. /*
  102. * This is where the code below needs to jump to wait for outermost interrupt
  103. * event in a non-privilege mode system (single shared interrupt stack).
  104. */
  105. ___TBIBoingPCX:
  106. MGETL A0StP,A0FrP,A0.2,A0.3 A0_4,[D1Re0] /* Restore AX regs */
  107. MOV TXSTATUS,D0Re0 /* Restore flags */
  108. GETL D0Re0,D1Re0,[D1Re0+#TBICTX_DX-TBICTX_BYTES]
  109. ___TBIBoingRTI:
  110. RTI /* Wait for interrupt */
  111. $Lpcx_target:
  112. /*
  113. * Save initial interrupt state on current stack
  114. */
  115. SETL [A0StP+#TBICTX_DX],D0Re0,D1Re0 /* Save key registers */
  116. ADD D1Re0,A0StP,#TBICTX_AX /* Address AX save area */
  117. MOV D0Re0,TXSTATUS /* Read TXSTATUS into D0Re0 */
  118. MOV TXSTATUS,#0 /* Clear TXSTATUS */
  119. MSETL [D1Re0],A0StP,A0FrP,A0.2,A0.3 A0_4 /* Save AX critical regs */
  120. /*
  121. * Register state at this point is-
  122. *
  123. * D0Re0 - Old TXSTATUS with PRIV and CBUF bits set if appropriate
  124. * A0StP - Is call stack frame and base of TBICTX being generated
  125. * A1GbP - Is valid static access link
  126. */
  127. ___TBIBoing:
  128. LOCK0 /* Make sure we have no locks! */
  129. ADD A1.2,A0StP,#TBICTX_DX+(8*1) /* Address DX.1 save area */
  130. MOV A0FrP,A0StP /* Setup frame pointer */
  131. MSETL [A1.2],D0Ar6,D0Ar4,D0Ar2,D0FrT,D0.5,D0.6,D0.7
  132. MOV D0Ar4,TXRPT /* Save critical CT regs */
  133. MOV D1Ar3,TXBPOBITS
  134. MOV D1Ar1,TXDIVTIME /* Calc catch buffer pSrc */
  135. MOV D0Ar2,TXMODE
  136. MOV TXMODE,#0 /* Clear TXMODE */
  137. #ifdef TXDIVTIME_RPDIRTY_BIT
  138. TSTT D1Ar1,#HI(TXDIVTIME_RPDIRTY_BIT)/* NZ = RPDIRTY */
  139. MOVT D0Ar6,#TBICTX_CBRP_BIT
  140. ORNZ D0Re0,D0Re0,D0Ar6 /* Set CBRP if RPDIRTY set */
  141. #endif
  142. MSETL [A1.2],D0Ar4,D0Ar2 /* Save CT regs state */
  143. MOV D0Ar2,D0Re0 /* Copy TXSTATUS */
  144. ANDMT D0Ar2,D0Ar2,#TBICTX_CBUF_BIT+TBICTX_CBRP_BIT
  145. #ifdef TBI_1_4
  146. MOVT D1Ar1,#TBICTX_FPAC_BIT /* Copy FPActive into FPAC */
  147. TSTT D0Re0,#HI(TXSTATUS_FPACTIVE_BIT)
  148. ORNZ D0Ar2,D0Ar2,D1Ar1
  149. #endif
  150. MOV D1Ar1,PCX /* Read CurrPC */
  151. ORT D0Ar2,D0Ar2,#TBICTX_CRIT_BIT /* SaveMask + CRIT bit */
  152. SETL [A0FrP+#TBICTX_Flags],D0Ar2,D1Ar1 /* Set pCtx header fields */
  153. /*
  154. * Completed context save, now we need to make a call to an interrupt handler
  155. *
  156. * D0Re0 - holds PRIV, WAIT, CBUF flags, HALT reason if appropriate
  157. * A0FrP - interrupt stack frame and base of TBICTX being generated
  158. * A0StP - same as A0FrP
  159. */
  160. ___TBIBoingWait:
  161. /* Reserve space for TBICTX and CBUF */
  162. ADD A0StP,A0StP,#TBICTX_BYTES+(CATCH_ENTRY_BYTES*CATCH_ENTRIES)
  163. MOV D0Ar4,TXSTATI /* Read the Triggers data */
  164. MOV D1Ar3,TXDIVTIME /* Read IRQEnc bits */
  165. MOV D0Ar2,D0Re0 /* Copy PRIV and WAIT flags */
  166. ANDT D0Ar2,D0Ar2,#TBICTX_PRIV_BIT+TBICTX_WAIT_BIT+TBICTX_CBUF_BIT
  167. #ifdef TBI_1_4
  168. MOVT D1Ar5,#TBICTX_FPAC_BIT /* Copy FPActive into FPAC */
  169. TSTT D0Re0,#HI(TXSTATUS_FPACTIVE_BIT)
  170. ORNZ D0Ar2,D0Ar2,D1Ar5
  171. #endif
  172. ANDT D1Ar3,D1Ar3,#HI(TXDIVTIME_IRQENC_BITS)
  173. LSR D1Ar3,D1Ar3,#TXDIVTIME_IRQENC_S
  174. AND TXSTATI,D0Ar4,#TXSTATI_BGNDHALT_BIT/* Ack any HALT seen */
  175. ANDS D0Ar4,D0Ar4,#0xFFFF-TXSTATI_BGNDHALT_BIT /* Only seen HALT? */
  176. ORT D0Ar2,D0Ar2,#TBICTX_CRIT_BIT /* Set CRIT */
  177. #ifndef BOOTROM
  178. MOVT A1LbP,#HI(___pTBIs)
  179. ADD A1LbP,A1LbP,#LO(___pTBIs)
  180. GETL D1Ar5,D0Ar6,[A1LbP] /* D0Ar6 = ___pTBIs[1] */
  181. #else
  182. /*
  183. * For BOOTROM support ___pTBIs must be allocated at offset 0 vs A1GbP
  184. */
  185. GETL D1Ar5,D0Ar6,[A1GbP] /* D0Ar6 = ___pTBIs[1] */
  186. #endif
  187. BZ ___TBIBoingHalt /* Yes: Service HALT */
  188. /*
  189. * Encode interrupt as signal vector, strip away same/lower TXMASKI bits
  190. */
  191. MOV D1Ar1,#1 /* Generate mask for this bit */
  192. MOV D0Re0,TXMASKI /* Get interrupt mask */
  193. LSL TXSTATI,D1Ar1,D1Ar3 /* Acknowledge trigger */
  194. AND TXMASKI,D0Re0,#TXSTATI_BGNDHALT_BIT /* Only allow HALTs */
  195. OR D0Ar2,D0Ar2,D0Re0 /* Set TBIRES.Sig.TrigMask */
  196. ADD D1Ar3,D1Ar3,#TBID_SIGNUM_TRT /* Offset into interrupt sigs */
  197. LSL D0Re0,D1Ar3,#TBID_SIGNUM_S /* Generate offset from SigNum */
  198. /*
  199. * This is a key moment we are about to call the handler, register state is
  200. * as follows-
  201. *
  202. * D0Re0 - Handler vector (SigNum<<TBID_SIGNUM_S)
  203. * D0Ar2 - TXMASKI:TBICTX_CRIT_BIT with optional CBUF and PRIV bits
  204. * D1Ar3 - SigNum
  205. * D0Ar4 - State read from TXSTATI
  206. * D1Ar5 - Inst for SWITCH trigger case only, otherwise undefined
  207. * D0Ar6 - pTBI
  208. */
  209. ___TBIBoingVec:
  210. ADD D0Re0,D0Re0,#TBI_fnSigs /* Offset into signal table */
  211. GETD D1Re0,[D0Ar6+D0Re0] /* Get address for Handler */
  212. /*
  213. * Call handler at interrupt level, when it returns simply resume execution
  214. * of state indicated by D1Re0.
  215. */
  216. MOV D1Ar1,A0FrP /* Pass in pCtx */
  217. CALLR D1RtP,___TBIBoingRTH /* Use RTH to invoke handler */
  218. /*
  219. * Perform critical state restore and execute background thread.
  220. *
  221. * A0FrP - is pointer to TBICTX structure to resume
  222. * D0Re0 - contains additional TXMASKI triggers
  223. */
  224. .text
  225. .balign 4
  226. #ifdef BOOTROM
  227. .global ___TBIResume
  228. #endif
  229. ___TBIResume:
  230. /*
  231. * New META IP method
  232. */
  233. RTH /* Go to interrupt level */
  234. MOV D0Ar4,TXMASKI /* Read TXMASKI */
  235. OR TXMASKI,D0Ar4,D0Re0 /* -Write-Modify TXMASKI */
  236. GETL D0Re0,D1Re0,[A0FrP+#TBICTX_Flags]/* Get Flags:SaveMask, CurrPC */
  237. MOV A0StP,A0FrP /* Position stack pointer */
  238. MOV D0Ar2,TXPOLLI /* Read pending triggers */
  239. MOV PCX,D1Re0 /* Set resumption PC */
  240. TST D0Ar2,#0xFFFF /* Any pending triggers? */
  241. BNZ ___TBIBoingWait /* Yes: Go for triggers */
  242. TSTT D0Re0,#TBICTX_WAIT_BIT /* Do we WAIT anyway? */
  243. BNZ ___TBIBoingWait /* Yes: Go for triggers */
  244. LSLS D1Ar5,D0Re0,#1 /* Test XCBF (MI) & PRIV (CS)? */
  245. ADD D1Re0,A0FrP,#TBICTX_CurrRPT /* Address CT save area */
  246. ADD A0StP,A0FrP,#TBICTX_DX+(8*1) /* Address DX.1 save area */
  247. MGETL A0.2,A0.3,[D1Re0] /* Get CT reg states */
  248. MOV D1Ar3,A1.3 /* Copy old TXDIVTIME */
  249. BPL ___TBIResCrit /* No: Skip logic */
  250. ADD D0Ar4,A0FrP,#TBICTX_BYTES /* Source is after TBICTX */
  251. ANDST D1Ar3,D1Ar3,#HI(TXDIVTIME_RPMASK_BITS)/* !Z if RPDIRTY */
  252. MGETL D0.5,D0.6,[D0Ar4] /* Read Catch state */
  253. MOV TXCATCH0,D0.5 /* Restore TXCATCHn */
  254. MOV TXCATCH1,D1.5
  255. MOV TXCATCH2,D0.6
  256. MOV TXCATCH3,D1.6
  257. BZ ___TBIResCrit
  258. MOV D0Ar2,#(1*8)
  259. LSRS D1Ar3,D1Ar3,#TXDIVTIME_RPMASK_S+1 /* 2nd RPMASK bit -> bit 0 */
  260. ADD RA,D0Ar4,#(0*8) /* Re-read read pipeline */
  261. ADDNZ RA,D0Ar4,D0Ar2 /* If Bit 0 set issue RA */
  262. LSRS D1Ar3,D1Ar3,#2 /* Bit 1 -> C, Bit 2 -> Bit 0 */
  263. ADD D0Ar2,D0Ar2,#8
  264. ADDCS RA,D0Ar4,D0Ar2 /* If C issue RA */
  265. ADD D0Ar2,D0Ar2,#8
  266. ADDNZ RA,D0Ar4,D0Ar2 /* If Bit 0 set issue RA */
  267. LSRS D1Ar3,D1Ar3,#2 /* Bit 1 -> C, Bit 2 -> Bit 0 */
  268. ADD D0Ar2,D0Ar2,#8
  269. ADDCS RA,D0Ar4,D0Ar2 /* If C issue RA */
  270. ADD D0Ar2,D0Ar2,#8
  271. ADDNZ RA,D0Ar4,D0Ar2 /* If Bit 0 set issue RA */
  272. MOV TXDIVTIME,A1.3 /* Set RPDIRTY again */
  273. ___TBIResCrit:
  274. LSLS D1Ar5,D0Re0,#1 /* Test XCBF (MI) & PRIV (CS)? */
  275. #ifdef TBI_1_4
  276. ANDT D1Ar5,D1Ar5,#(TBICTX_FPAC_BIT*2)
  277. LSL D0Ar6,D1Ar5,#3 /* Convert FPAC into FPACTIVE */
  278. #endif
  279. ANDMT D0Re0,D0Re0,#TBICTX_CBUF_BIT /* Keep CBUF bit from SaveMask */
  280. #ifdef TBI_1_4
  281. OR D0Re0,D0Re0,D0Ar6 /* Combine FPACTIVE with others */
  282. #endif
  283. MGETL D0Ar6,D0Ar4,D0Ar2,D0FrT,D0.5,D0.6,D0.7,[A0StP] /* Restore DX */
  284. MOV TXRPT,A0.2 /* Restore CT regs */
  285. MOV TXBPOBITS,A1.2
  286. MOV TXMODE,A0.3
  287. BCC ___TBIBoingPCX /* Do non-PRIV wait! */
  288. MOV A1GblIGbP,A1GbP /* Save A1GbP too */
  289. MGETL A0StP,A0FrP,A0.2,A0.3 A0_4,[D1Re0] /* Restore AX regs */
  290. /*
  291. * Wait for the first interrupt/exception trigger in a privilege mode system
  292. * (interrupt stack area for current TASK to be pointed to by A0GblIStP
  293. * or per_cpu__stack_save[hwthread_id]).
  294. */
  295. MOV TXSTATUS,D0Re0 /* Restore flags */
  296. MOV D0Re0,TXPRIVEXT /* Set TXPRIVEXT_TXTOGGLEI_BIT */
  297. SUB D1Re0,D1Re0,#TBICTX_BYTES /* TBICTX is top of int stack */
  298. #ifdef TBX_PERCPU_SP_SAVE
  299. SWAP D1Ar3,A1GbP
  300. MOV D1Ar3,TXENABLE /* Which thread are we? */
  301. AND D1Ar3,D1Ar3,#TXENABLE_THREAD_BITS
  302. LSR D1Ar3,D1Ar3,#TXENABLE_THREAD_S-2
  303. ADDT D1Ar3,D1Ar3,#HI(_per_cpu__stack_save)
  304. ADD D1Ar3,D1Ar3,#LO(_per_cpu__stack_save)
  305. SETD [D1Ar3],D1Re0
  306. SWAP D1Ar3,A1GbP
  307. #else
  308. MOV A0GblIStP, D1Re0
  309. #endif
  310. OR D0Re0,D0Re0,#TXPRIVEXT_TXTOGGLEI_BIT
  311. MOV TXPRIVEXT,D0Re0 /* Cannot set TXPRIVEXT if !priv */
  312. GETL D0Re0,D1Re0,[D1Re0+#TBICTX_DX]
  313. RTI /* Wait for interrupt */
  314. /*
  315. * Save initial interrupt state on A0GblIStP, switch to A0GblIStP if
  316. * BOOTROM code, save and switch to [A1GbP] otherwise.
  317. */
  318. ___TBIBoingPCXP:
  319. #ifdef TBX_PERCPU_SP_SAVE
  320. SWAP D1Ar3,A1GbP /* Get PRIV stack base */
  321. MOV D1Ar3,TXENABLE /* Which thread are we? */
  322. AND D1Ar3,D1Ar3,#TXENABLE_THREAD_BITS
  323. LSR D1Ar3,D1Ar3,#TXENABLE_THREAD_S-2
  324. ADDT D1Ar3,D1Ar3,#HI(_per_cpu__stack_save)
  325. ADD D1Ar3,D1Ar3,#LO(_per_cpu__stack_save)
  326. GETD D1Ar3,[D1Ar3]
  327. #else
  328. SWAP D1Ar3,A0GblIStP /* Get PRIV stack base */
  329. #endif
  330. SETL [D1Ar3+#TBICTX_DX],D0Re0,D1Re0 /* Save key registers */
  331. MOV D0Re0,TXPRIVEXT /* Clear TXPRIVEXT_TXTOGGLEI_BIT */
  332. ADD D1Re0,D1Ar3,#TBICTX_AX /* Address AX save area */
  333. ANDMB D0Re0,D0Re0,#0xFFFF-TXPRIVEXT_TXTOGGLEI_BIT
  334. MOV TXPRIVEXT,D0Re0 /* Cannot set TXPRIVEXT if !priv */
  335. MOV D0Re0,TXSTATUS /* Read TXSTATUS into D0Re0 */
  336. MOV TXSTATUS,#0 /* Clear TXSTATUS */
  337. MSETL [D1Re0],A0StP,A0FrP,A0.2,A0.3 A0_4 /* Save AX critical regs */
  338. MOV A0StP,D1Ar3 /* Switch stacks */
  339. #ifdef TBX_PERCPU_SP_SAVE
  340. MOV D1Ar3,A1GbP /* Get D1Ar2 back */
  341. #else
  342. MOV D1Ar3,A0GblIStP /* Get D1Ar2 back */
  343. #endif
  344. ORT D0Re0,D0Re0,#TBICTX_PRIV_BIT /* Add PRIV to TXSTATUS */
  345. MOV A1GbP,A1GblIGbP /* Restore A1GbP */
  346. B ___TBIBoing /* Enter common handler code */
  347. /*
  348. * At this point we know it's a background HALT case we are handling.
  349. * The restored TXSTATUS always needs to have zero in the reason bits.
  350. */
  351. ___TBIBoingHalt:
  352. MOV D0Ar4,TXMASKI /* Get interrupt mask */
  353. ANDST D0Re0,D0Re0,#HI(TXSTATUS_MAJOR_HALT_BITS+TXSTATUS_MEM_FAULT_BITS)
  354. AND TXMASKI,D0Ar4,#TXSTATI_BGNDHALT_BIT /* Only allow HALTs */
  355. AND D0Ar4,D0Ar4,#0xFFFF-TXSTATI_BGNDHALT_BIT /* What ints are off? */
  356. OR D0Ar2,D0Ar2,D0Ar4 /* Set TBIRES.Sig.TrigMask */
  357. MOV D0Ar4,#TXSTATI_BGNDHALT_BIT /* This was the trigger state */
  358. LSR D1Ar3,D0Re0,#TXSTATUS_MAJOR_HALT_S
  359. MOV D0Re0,#TBID_SIGNUM_XXF<<TBID_SIGNUM_S
  360. BNZ ___TBIBoingVec /* Jump to XXF exception handler */
  361. /*
  362. * Only the SWITCH cases are left, PCX must be valid
  363. */
  364. #ifdef TBI_1_4
  365. MOV D1Ar5,TXPRIVEXT
  366. TST D1Ar5,#TXPRIVEXT_MINIMON_BIT
  367. LSR D1Ar3,D1Ar1,#1 /* Shift needed for MINIM paths (fill stall) */
  368. BZ $Lmeta /* If META only, skip */
  369. TSTT D1Ar1,#HI(0x00800000)
  370. ANDMT D1Ar3,D1Ar3,#HI(0x007FFFFF >> 1)/* Shifted mask for large MINIM */
  371. ANDT D1Ar1,D1Ar1,#HI(0xFFE00000) /* Static mask for small MINIM */
  372. BZ $Llarge_minim /* If large MINIM */
  373. $Lsmall_minim:
  374. TSTT D1Ar3,#HI(0x00100000 >> 1)
  375. ANDMT D1Ar3,D1Ar3,#HI(0x001FFFFF >> 1)/* Correct shifted mask for large MINIM */
  376. ADDZ D1Ar1,D1Ar1,D1Ar3 /* If META rgn, add twice to undo LSR #1 */
  377. B $Lrecombine
  378. $Llarge_minim:
  379. ANDST D1Ar1,D1Ar1,#HI(0xFF800000) /* Correct static mask for small MINIM */
  380. /* Z=0 (Cannot place code at NULL) */
  381. $Lrecombine:
  382. ADD D1Ar1,D1Ar1,D1Ar3 /* Combine static and shifted parts */
  383. $Lmeta:
  384. GETW D1Ar5,[D1Ar1++] /* META: lo-16, MINIM: lo-16 (all-16 if short) */
  385. GETW D1Ar3,[D1Ar1] /* META: hi-16, MINIM: hi-16 (only if long) */
  386. MOV D1Re0,D1Ar5
  387. XOR D1Re0,D1Re0,#0x4000
  388. LSLSNZ D1Re0,D1Re0,#(32-14) /* MINIM: If long C=0, if short C=1 */
  389. LSLCC D1Ar3,D1Ar3,#16 /* META/MINIM long: Move hi-16 up */
  390. LSLCS D1Ar3,D1Ar5,#16 /* MINIM short: Dup all-16 */
  391. ADD D1Ar5,D1Ar5,D1Ar3 /* ALL: Combine both 16-bit parts */
  392. #else
  393. GETD D1Ar5,[D1Ar1] /* Read instruction for switch */
  394. #endif
  395. LSR D1Ar3,D1Ar5,#22 /* Convert into signal number */
  396. AND D1Ar3,D1Ar3,#TBID_SIGNUM_SW3-TBID_SIGNUM_SW0
  397. LSL D0Re0,D1Ar3,#TBID_SIGNUM_S /* Generate offset from SigNum */
  398. B ___TBIBoingVec /* Jump to switch handler */
  399. /*
  400. * Exit from TBIASyncTrigger call
  401. */
  402. ___TBIBoingExit:
  403. GETL D0FrT,D1RtP,[A0FrP++] /* Restore state from frame */
  404. SUB A0StP,A0FrP,#8 /* Unwind stack */
  405. MOV A0FrP,D0FrT /* Last memory read completes */
  406. MOV PC,D1RtP /* Return to caller */
  407. #endif /* ifdef CODE_USES_BOOTROM */
  408. .size ___TBIResume,.-___TBIResume
  409. #ifndef BOOTROM
  410. /*
  411. * void __TBIASyncResume( TBIRES State )
  412. */
  413. .text
  414. .balign 4
  415. .global ___TBIASyncResume
  416. .type ___TBIASyncResume,function
  417. ___TBIASyncResume:
  418. /*
  419. * Perform CRIT|SOFT state restore and execute background thread.
  420. */
  421. MOV D1Ar3,D1Ar1 /* Restore this context */
  422. MOV D0Re0,D0Ar2 /* Carry in additional triggers */
  423. /* Reserve space for TBICTX */
  424. ADD D1Ar3,D1Ar3,#TBICTX_BYTES+(CATCH_ENTRY_BYTES*CATCH_ENTRIES)
  425. MOV A0StP,D1Ar3 /* Enter with protection of */
  426. MOV A0FrP,D1Ar1 /* TBICTX on our stack */
  427. #ifdef CODE_USES_BOOTROM
  428. MOVT D1Ar1,#HI(LINCORE_BASE)
  429. JUMP D1Ar1,#0xA4
  430. #else
  431. B ___TBIResume
  432. #endif
  433. .size ___TBIASyncResume,.-___TBIASyncResume
  434. #endif /* ifndef BOOTROM */
  435. /*
  436. * End of tbipcx.S
  437. */