entry.S 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * arch/alpha/kernel/entry.S
  4. *
  5. * Kernel entry-points.
  6. */
  7. #include <asm/asm-offsets.h>
  8. #include <asm/thread_info.h>
  9. #include <asm/pal.h>
  10. #include <asm/errno.h>
  11. #include <asm/unistd.h>
  12. .text
  13. .set noat
  14. .cfi_sections .debug_frame
  15. .macro CFI_START_OSF_FRAME func
  16. .align 4
  17. .globl \func
  18. .type \func,@function
  19. \func:
  20. .cfi_startproc simple
  21. .cfi_return_column 64
  22. .cfi_def_cfa $sp, 48
  23. .cfi_rel_offset 64, 8
  24. .cfi_rel_offset $gp, 16
  25. .cfi_rel_offset $16, 24
  26. .cfi_rel_offset $17, 32
  27. .cfi_rel_offset $18, 40
  28. .endm
  29. .macro CFI_END_OSF_FRAME func
  30. .cfi_endproc
  31. .size \func, . - \func
  32. .endm
  33. /*
  34. * This defines the normal kernel pt-regs layout.
  35. *
  36. * regs 9-15 preserved by C code
  37. * regs 16-18 saved by PAL-code
  38. * regs 29-30 saved and set up by PAL-code
  39. * JRP - Save regs 16-18 in a special area of the stack, so that
  40. * the palcode-provided values are available to the signal handler.
  41. */
  42. .macro SAVE_ALL
  43. subq $sp, SP_OFF, $sp
  44. .cfi_adjust_cfa_offset SP_OFF
  45. stq $0, 0($sp)
  46. stq $1, 8($sp)
  47. stq $2, 16($sp)
  48. stq $3, 24($sp)
  49. stq $4, 32($sp)
  50. stq $28, 144($sp)
  51. .cfi_rel_offset $0, 0
  52. .cfi_rel_offset $1, 8
  53. .cfi_rel_offset $2, 16
  54. .cfi_rel_offset $3, 24
  55. .cfi_rel_offset $4, 32
  56. .cfi_rel_offset $28, 144
  57. lda $2, alpha_mv
  58. stq $5, 40($sp)
  59. stq $6, 48($sp)
  60. stq $7, 56($sp)
  61. stq $8, 64($sp)
  62. stq $19, 72($sp)
  63. stq $20, 80($sp)
  64. stq $21, 88($sp)
  65. ldq $2, HAE_CACHE($2)
  66. stq $22, 96($sp)
  67. stq $23, 104($sp)
  68. stq $24, 112($sp)
  69. stq $25, 120($sp)
  70. stq $26, 128($sp)
  71. stq $27, 136($sp)
  72. stq $2, 152($sp)
  73. stq $16, 160($sp)
  74. stq $17, 168($sp)
  75. stq $18, 176($sp)
  76. .cfi_rel_offset $5, 40
  77. .cfi_rel_offset $6, 48
  78. .cfi_rel_offset $7, 56
  79. .cfi_rel_offset $8, 64
  80. .cfi_rel_offset $19, 72
  81. .cfi_rel_offset $20, 80
  82. .cfi_rel_offset $21, 88
  83. .cfi_rel_offset $22, 96
  84. .cfi_rel_offset $23, 104
  85. .cfi_rel_offset $24, 112
  86. .cfi_rel_offset $25, 120
  87. .cfi_rel_offset $26, 128
  88. .cfi_rel_offset $27, 136
  89. .endm
  90. .macro RESTORE_ALL
  91. lda $19, alpha_mv
  92. ldq $0, 0($sp)
  93. ldq $1, 8($sp)
  94. ldq $2, 16($sp)
  95. ldq $3, 24($sp)
  96. ldq $21, 152($sp)
  97. ldq $20, HAE_CACHE($19)
  98. ldq $4, 32($sp)
  99. ldq $5, 40($sp)
  100. ldq $6, 48($sp)
  101. ldq $7, 56($sp)
  102. subq $20, $21, $20
  103. ldq $8, 64($sp)
  104. beq $20, 99f
  105. ldq $20, HAE_REG($19)
  106. stq $21, HAE_CACHE($19)
  107. stq $21, 0($20)
  108. 99: ldq $19, 72($sp)
  109. ldq $20, 80($sp)
  110. ldq $21, 88($sp)
  111. ldq $22, 96($sp)
  112. ldq $23, 104($sp)
  113. ldq $24, 112($sp)
  114. ldq $25, 120($sp)
  115. ldq $26, 128($sp)
  116. ldq $27, 136($sp)
  117. ldq $28, 144($sp)
  118. addq $sp, SP_OFF, $sp
  119. .cfi_restore $0
  120. .cfi_restore $1
  121. .cfi_restore $2
  122. .cfi_restore $3
  123. .cfi_restore $4
  124. .cfi_restore $5
  125. .cfi_restore $6
  126. .cfi_restore $7
  127. .cfi_restore $8
  128. .cfi_restore $19
  129. .cfi_restore $20
  130. .cfi_restore $21
  131. .cfi_restore $22
  132. .cfi_restore $23
  133. .cfi_restore $24
  134. .cfi_restore $25
  135. .cfi_restore $26
  136. .cfi_restore $27
  137. .cfi_restore $28
  138. .cfi_adjust_cfa_offset -SP_OFF
  139. .endm
  140. .macro DO_SWITCH_STACK
  141. bsr $1, do_switch_stack
  142. .cfi_adjust_cfa_offset SWITCH_STACK_SIZE
  143. .cfi_rel_offset $9, 0
  144. .cfi_rel_offset $10, 8
  145. .cfi_rel_offset $11, 16
  146. .cfi_rel_offset $12, 24
  147. .cfi_rel_offset $13, 32
  148. .cfi_rel_offset $14, 40
  149. .cfi_rel_offset $15, 48
  150. .endm
  151. .macro UNDO_SWITCH_STACK
  152. bsr $1, undo_switch_stack
  153. .cfi_restore $9
  154. .cfi_restore $10
  155. .cfi_restore $11
  156. .cfi_restore $12
  157. .cfi_restore $13
  158. .cfi_restore $14
  159. .cfi_restore $15
  160. .cfi_adjust_cfa_offset -SWITCH_STACK_SIZE
  161. .endm
  162. /*
  163. * Non-syscall kernel entry points.
  164. */
  165. CFI_START_OSF_FRAME entInt
  166. SAVE_ALL
  167. lda $8, 0x3fff
  168. lda $26, ret_from_sys_call
  169. bic $sp, $8, $8
  170. mov $sp, $19
  171. jsr $31, do_entInt
  172. CFI_END_OSF_FRAME entInt
  173. CFI_START_OSF_FRAME entArith
  174. SAVE_ALL
  175. lda $8, 0x3fff
  176. lda $26, ret_from_sys_call
  177. bic $sp, $8, $8
  178. mov $sp, $18
  179. jsr $31, do_entArith
  180. CFI_END_OSF_FRAME entArith
  181. CFI_START_OSF_FRAME entMM
  182. SAVE_ALL
  183. /* save $9 - $15 so the inline exception code can manipulate them. */
  184. subq $sp, 64, $sp
  185. .cfi_adjust_cfa_offset 64
  186. stq $9, 0($sp)
  187. stq $10, 8($sp)
  188. stq $11, 16($sp)
  189. stq $12, 24($sp)
  190. stq $13, 32($sp)
  191. stq $14, 40($sp)
  192. stq $15, 48($sp)
  193. .cfi_rel_offset $9, 0
  194. .cfi_rel_offset $10, 8
  195. .cfi_rel_offset $11, 16
  196. .cfi_rel_offset $12, 24
  197. .cfi_rel_offset $13, 32
  198. .cfi_rel_offset $14, 40
  199. .cfi_rel_offset $15, 48
  200. addq $sp, 64, $19
  201. /* handle the fault */
  202. lda $8, 0x3fff
  203. bic $sp, $8, $8
  204. jsr $26, do_page_fault
  205. /* reload the registers after the exception code played. */
  206. ldq $9, 0($sp)
  207. ldq $10, 8($sp)
  208. ldq $11, 16($sp)
  209. ldq $12, 24($sp)
  210. ldq $13, 32($sp)
  211. ldq $14, 40($sp)
  212. ldq $15, 48($sp)
  213. addq $sp, 64, $sp
  214. .cfi_restore $9
  215. .cfi_restore $10
  216. .cfi_restore $11
  217. .cfi_restore $12
  218. .cfi_restore $13
  219. .cfi_restore $14
  220. .cfi_restore $15
  221. .cfi_adjust_cfa_offset -64
  222. /* finish up the syscall as normal. */
  223. br ret_from_sys_call
  224. CFI_END_OSF_FRAME entMM
  225. CFI_START_OSF_FRAME entIF
  226. SAVE_ALL
  227. lda $8, 0x3fff
  228. lda $26, ret_from_sys_call
  229. bic $sp, $8, $8
  230. mov $sp, $17
  231. jsr $31, do_entIF
  232. CFI_END_OSF_FRAME entIF
  233. CFI_START_OSF_FRAME entUna
  234. lda $sp, -256($sp)
  235. .cfi_adjust_cfa_offset 256
  236. stq $0, 0($sp)
  237. .cfi_rel_offset $0, 0
  238. .cfi_remember_state
  239. ldq $0, 256($sp) /* get PS */
  240. stq $1, 8($sp)
  241. stq $2, 16($sp)
  242. stq $3, 24($sp)
  243. and $0, 8, $0 /* user mode? */
  244. stq $4, 32($sp)
  245. bne $0, entUnaUser /* yup -> do user-level unaligned fault */
  246. stq $5, 40($sp)
  247. stq $6, 48($sp)
  248. stq $7, 56($sp)
  249. stq $8, 64($sp)
  250. stq $9, 72($sp)
  251. stq $10, 80($sp)
  252. stq $11, 88($sp)
  253. stq $12, 96($sp)
  254. stq $13, 104($sp)
  255. stq $14, 112($sp)
  256. stq $15, 120($sp)
  257. /* 16-18 PAL-saved */
  258. stq $19, 152($sp)
  259. stq $20, 160($sp)
  260. stq $21, 168($sp)
  261. stq $22, 176($sp)
  262. stq $23, 184($sp)
  263. stq $24, 192($sp)
  264. stq $25, 200($sp)
  265. stq $26, 208($sp)
  266. stq $27, 216($sp)
  267. stq $28, 224($sp)
  268. mov $sp, $19
  269. stq $gp, 232($sp)
  270. .cfi_rel_offset $1, 1*8
  271. .cfi_rel_offset $2, 2*8
  272. .cfi_rel_offset $3, 3*8
  273. .cfi_rel_offset $4, 4*8
  274. .cfi_rel_offset $5, 5*8
  275. .cfi_rel_offset $6, 6*8
  276. .cfi_rel_offset $7, 7*8
  277. .cfi_rel_offset $8, 8*8
  278. .cfi_rel_offset $9, 9*8
  279. .cfi_rel_offset $10, 10*8
  280. .cfi_rel_offset $11, 11*8
  281. .cfi_rel_offset $12, 12*8
  282. .cfi_rel_offset $13, 13*8
  283. .cfi_rel_offset $14, 14*8
  284. .cfi_rel_offset $15, 15*8
  285. .cfi_rel_offset $19, 19*8
  286. .cfi_rel_offset $20, 20*8
  287. .cfi_rel_offset $21, 21*8
  288. .cfi_rel_offset $22, 22*8
  289. .cfi_rel_offset $23, 23*8
  290. .cfi_rel_offset $24, 24*8
  291. .cfi_rel_offset $25, 25*8
  292. .cfi_rel_offset $26, 26*8
  293. .cfi_rel_offset $27, 27*8
  294. .cfi_rel_offset $28, 28*8
  295. .cfi_rel_offset $29, 29*8
  296. lda $8, 0x3fff
  297. stq $31, 248($sp)
  298. bic $sp, $8, $8
  299. jsr $26, do_entUna
  300. ldq $0, 0($sp)
  301. ldq $1, 8($sp)
  302. ldq $2, 16($sp)
  303. ldq $3, 24($sp)
  304. ldq $4, 32($sp)
  305. ldq $5, 40($sp)
  306. ldq $6, 48($sp)
  307. ldq $7, 56($sp)
  308. ldq $8, 64($sp)
  309. ldq $9, 72($sp)
  310. ldq $10, 80($sp)
  311. ldq $11, 88($sp)
  312. ldq $12, 96($sp)
  313. ldq $13, 104($sp)
  314. ldq $14, 112($sp)
  315. ldq $15, 120($sp)
  316. /* 16-18 PAL-saved */
  317. ldq $19, 152($sp)
  318. ldq $20, 160($sp)
  319. ldq $21, 168($sp)
  320. ldq $22, 176($sp)
  321. ldq $23, 184($sp)
  322. ldq $24, 192($sp)
  323. ldq $25, 200($sp)
  324. ldq $26, 208($sp)
  325. ldq $27, 216($sp)
  326. ldq $28, 224($sp)
  327. ldq $gp, 232($sp)
  328. lda $sp, 256($sp)
  329. .cfi_restore $1
  330. .cfi_restore $2
  331. .cfi_restore $3
  332. .cfi_restore $4
  333. .cfi_restore $5
  334. .cfi_restore $6
  335. .cfi_restore $7
  336. .cfi_restore $8
  337. .cfi_restore $9
  338. .cfi_restore $10
  339. .cfi_restore $11
  340. .cfi_restore $12
  341. .cfi_restore $13
  342. .cfi_restore $14
  343. .cfi_restore $15
  344. .cfi_restore $19
  345. .cfi_restore $20
  346. .cfi_restore $21
  347. .cfi_restore $22
  348. .cfi_restore $23
  349. .cfi_restore $24
  350. .cfi_restore $25
  351. .cfi_restore $26
  352. .cfi_restore $27
  353. .cfi_restore $28
  354. .cfi_restore $29
  355. .cfi_adjust_cfa_offset -256
  356. call_pal PAL_rti
  357. .align 4
  358. entUnaUser:
  359. .cfi_restore_state
  360. ldq $0, 0($sp) /* restore original $0 */
  361. lda $sp, 256($sp) /* pop entUna's stack frame */
  362. .cfi_restore $0
  363. .cfi_adjust_cfa_offset -256
  364. SAVE_ALL /* setup normal kernel stack */
  365. lda $sp, -64($sp)
  366. .cfi_adjust_cfa_offset 64
  367. stq $9, 0($sp)
  368. stq $10, 8($sp)
  369. stq $11, 16($sp)
  370. stq $12, 24($sp)
  371. stq $13, 32($sp)
  372. stq $14, 40($sp)
  373. stq $15, 48($sp)
  374. .cfi_rel_offset $9, 0
  375. .cfi_rel_offset $10, 8
  376. .cfi_rel_offset $11, 16
  377. .cfi_rel_offset $12, 24
  378. .cfi_rel_offset $13, 32
  379. .cfi_rel_offset $14, 40
  380. .cfi_rel_offset $15, 48
  381. lda $8, 0x3fff
  382. addq $sp, 64, $19
  383. bic $sp, $8, $8
  384. jsr $26, do_entUnaUser
  385. ldq $9, 0($sp)
  386. ldq $10, 8($sp)
  387. ldq $11, 16($sp)
  388. ldq $12, 24($sp)
  389. ldq $13, 32($sp)
  390. ldq $14, 40($sp)
  391. ldq $15, 48($sp)
  392. lda $sp, 64($sp)
  393. .cfi_restore $9
  394. .cfi_restore $10
  395. .cfi_restore $11
  396. .cfi_restore $12
  397. .cfi_restore $13
  398. .cfi_restore $14
  399. .cfi_restore $15
  400. .cfi_adjust_cfa_offset -64
  401. br ret_from_sys_call
  402. CFI_END_OSF_FRAME entUna
  403. CFI_START_OSF_FRAME entDbg
  404. SAVE_ALL
  405. lda $8, 0x3fff
  406. lda $26, ret_from_sys_call
  407. bic $sp, $8, $8
  408. mov $sp, $16
  409. jsr $31, do_entDbg
  410. CFI_END_OSF_FRAME entDbg
  411. /*
  412. * The system call entry point is special. Most importantly, it looks
  413. * like a function call to userspace as far as clobbered registers. We
  414. * do preserve the argument registers (for syscall restarts) and $26
  415. * (for leaf syscall functions).
  416. *
  417. * So much for theory. We don't take advantage of this yet.
  418. *
  419. * Note that a0-a2 are not saved by PALcode as with the other entry points.
  420. */
  421. .align 4
  422. .globl entSys
  423. .type entSys, @function
  424. .cfi_startproc simple
  425. .cfi_return_column 64
  426. .cfi_def_cfa $sp, 48
  427. .cfi_rel_offset 64, 8
  428. .cfi_rel_offset $gp, 16
  429. entSys:
  430. SAVE_ALL
  431. lda $8, 0x3fff
  432. bic $sp, $8, $8
  433. lda $4, NR_syscalls($31)
  434. stq $16, SP_OFF+24($sp)
  435. lda $5, sys_call_table
  436. lda $27, sys_ni_syscall
  437. cmpult $0, $4, $4
  438. ldl $3, TI_FLAGS($8)
  439. stq $17, SP_OFF+32($sp)
  440. s8addq $0, $5, $5
  441. stq $18, SP_OFF+40($sp)
  442. .cfi_rel_offset $16, SP_OFF+24
  443. .cfi_rel_offset $17, SP_OFF+32
  444. .cfi_rel_offset $18, SP_OFF+40
  445. #ifdef CONFIG_AUDITSYSCALL
  446. lda $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
  447. and $3, $6, $3
  448. bne $3, strace
  449. #else
  450. blbs $3, strace /* check for SYSCALL_TRACE in disguise */
  451. #endif
  452. beq $4, 1f
  453. ldq $27, 0($5)
  454. 1: jsr $26, ($27), sys_ni_syscall
  455. ldgp $gp, 0($26)
  456. blt $0, $syscall_error /* the call failed */
  457. $ret_success:
  458. stq $0, 0($sp)
  459. stq $31, 72($sp) /* a3=0 => no error */
  460. .align 4
  461. .globl ret_from_sys_call
  462. ret_from_sys_call:
  463. cmovne $26, 0, $18 /* $18 = 0 => non-restartable */
  464. ldq $0, SP_OFF($sp)
  465. and $0, 8, $0
  466. beq $0, ret_to_kernel
  467. ret_to_user:
  468. /* Make sure need_resched and sigpending don't change between
  469. sampling and the rti. */
  470. lda $16, 7
  471. call_pal PAL_swpipl
  472. ldl $17, TI_FLAGS($8)
  473. and $17, _TIF_WORK_MASK, $2
  474. bne $2, work_pending
  475. restore_all:
  476. ldl $2, TI_STATUS($8)
  477. and $2, TS_SAVED_FP | TS_RESTORE_FP, $3
  478. bne $3, restore_fpu
  479. restore_other:
  480. .cfi_remember_state
  481. RESTORE_ALL
  482. call_pal PAL_rti
  483. ret_to_kernel:
  484. .cfi_restore_state
  485. lda $16, 7
  486. call_pal PAL_swpipl
  487. br restore_other
  488. .align 3
  489. $syscall_error:
  490. /*
  491. * Some system calls (e.g., ptrace) can return arbitrary
  492. * values which might normally be mistaken as error numbers.
  493. * Those functions must zero $0 (v0) directly in the stack
  494. * frame to indicate that a negative return value wasn't an
  495. * error number..
  496. */
  497. ldq $18, 0($sp) /* old syscall nr (zero if success) */
  498. beq $18, $ret_success
  499. ldq $19, 72($sp) /* .. and this a3 */
  500. subq $31, $0, $0 /* with error in v0 */
  501. addq $31, 1, $1 /* set a3 for errno return */
  502. stq $0, 0($sp)
  503. mov $31, $26 /* tell "ret_from_sys_call" we can restart */
  504. stq $1, 72($sp) /* a3 for return */
  505. br ret_from_sys_call
  506. /*
  507. * Do all cleanup when returning from all interrupts and system calls.
  508. *
  509. * Arguments:
  510. * $8: current.
  511. * $17: TI_FLAGS.
  512. * $18: The old syscall number, or zero if this is not a return
  513. * from a syscall that errored and is possibly restartable.
  514. * $19: The old a3 value
  515. */
  516. .align 4
  517. .type work_pending, @function
  518. work_pending:
  519. and $17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL, $2
  520. bne $2, $work_notifysig
  521. $work_resched:
  522. /*
  523. * We can get here only if we returned from syscall without SIGPENDING
  524. * or got through work_notifysig already. Either case means no syscall
  525. * restarts for us, so let $18 and $19 burn.
  526. */
  527. jsr $26, schedule
  528. mov 0, $18
  529. br ret_to_user
  530. $work_notifysig:
  531. mov $sp, $16
  532. DO_SWITCH_STACK
  533. jsr $26, do_work_pending
  534. UNDO_SWITCH_STACK
  535. br restore_all
  536. /*
  537. * PTRACE syscall handler
  538. */
  539. .align 4
  540. .type strace, @function
  541. strace:
  542. /* set up signal stack, call syscall_trace */
  543. // NB: if anyone adds preemption, this block will need to be protected
  544. ldl $1, TI_STATUS($8)
  545. and $1, TS_SAVED_FP, $3
  546. or $1, TS_SAVED_FP, $2
  547. bne $3, 1f
  548. stl $2, TI_STATUS($8)
  549. bsr $26, __save_fpu
  550. 1:
  551. DO_SWITCH_STACK
  552. jsr $26, syscall_trace_enter /* returns the syscall number */
  553. UNDO_SWITCH_STACK
  554. /* get the arguments back.. */
  555. ldq $16, SP_OFF+24($sp)
  556. ldq $17, SP_OFF+32($sp)
  557. ldq $18, SP_OFF+40($sp)
  558. ldq $19, 72($sp)
  559. ldq $20, 80($sp)
  560. ldq $21, 88($sp)
  561. /* get the system call pointer.. */
  562. lda $1, NR_syscalls($31)
  563. lda $2, sys_call_table
  564. lda $27, sys_ni_syscall
  565. cmpult $0, $1, $1
  566. s8addq $0, $2, $2
  567. beq $1, 1f
  568. ldq $27, 0($2)
  569. 1: jsr $26, ($27), sys_gettimeofday
  570. ret_from_straced:
  571. ldgp $gp, 0($26)
  572. /* check return.. */
  573. blt $0, $strace_error /* the call failed */
  574. $strace_success:
  575. stq $31, 72($sp) /* a3=0 => no error */
  576. stq $0, 0($sp) /* save return value */
  577. DO_SWITCH_STACK
  578. jsr $26, syscall_trace_leave
  579. UNDO_SWITCH_STACK
  580. br $31, ret_from_sys_call
  581. .align 3
  582. $strace_error:
  583. ldq $18, 0($sp) /* old syscall nr (zero if success) */
  584. beq $18, $strace_success
  585. ldq $19, 72($sp) /* .. and this a3 */
  586. subq $31, $0, $0 /* with error in v0 */
  587. addq $31, 1, $1 /* set a3 for errno return */
  588. stq $0, 0($sp)
  589. stq $1, 72($sp) /* a3 for return */
  590. DO_SWITCH_STACK
  591. mov $18, $9 /* save old syscall number */
  592. mov $19, $10 /* save old a3 */
  593. jsr $26, syscall_trace_leave
  594. mov $9, $18
  595. mov $10, $19
  596. UNDO_SWITCH_STACK
  597. mov $31, $26 /* tell "ret_from_sys_call" we can restart */
  598. br ret_from_sys_call
  599. CFI_END_OSF_FRAME entSys
  600. /*
  601. * Save and restore the switch stack -- aka the balance of the user context.
  602. */
  603. .align 4
  604. .type do_switch_stack, @function
  605. .cfi_startproc simple
  606. .cfi_return_column 64
  607. .cfi_def_cfa $sp, 0
  608. .cfi_register 64, $1
  609. do_switch_stack:
  610. lda $sp, -SWITCH_STACK_SIZE($sp)
  611. .cfi_adjust_cfa_offset SWITCH_STACK_SIZE
  612. stq $9, 0($sp)
  613. stq $10, 8($sp)
  614. stq $11, 16($sp)
  615. stq $12, 24($sp)
  616. stq $13, 32($sp)
  617. stq $14, 40($sp)
  618. stq $15, 48($sp)
  619. stq $26, 56($sp)
  620. ret $31, ($1), 1
  621. .cfi_endproc
  622. .size do_switch_stack, .-do_switch_stack
  623. .align 4
  624. .type undo_switch_stack, @function
  625. .cfi_startproc simple
  626. .cfi_def_cfa $sp, 0
  627. .cfi_register 64, $1
  628. undo_switch_stack:
  629. ldq $9, 0($sp)
  630. ldq $10, 8($sp)
  631. ldq $11, 16($sp)
  632. ldq $12, 24($sp)
  633. ldq $13, 32($sp)
  634. ldq $14, 40($sp)
  635. ldq $15, 48($sp)
  636. ldq $26, 56($sp)
  637. lda $sp, SWITCH_STACK_SIZE($sp)
  638. ret $31, ($1), 1
  639. .cfi_endproc
  640. .size undo_switch_stack, .-undo_switch_stack
  641. #define FR(n) n * 8 + TI_FP($8)
  642. .align 4
  643. .globl __save_fpu
  644. .type __save_fpu, @function
  645. __save_fpu:
  646. #define V(n) stt $f##n, FR(n)
  647. V( 0); V( 1); V( 2); V( 3)
  648. V( 4); V( 5); V( 6); V( 7)
  649. V( 8); V( 9); V(10); V(11)
  650. V(12); V(13); V(14); V(15)
  651. V(16); V(17); V(18); V(19)
  652. V(20); V(21); V(22); V(23)
  653. V(24); V(25); V(26); V(27)
  654. mf_fpcr $f0 # get fpcr
  655. V(28); V(29); V(30)
  656. stt $f0, FR(31) # save fpcr in slot of $f31
  657. ldt $f0, FR(0) # don't let "__save_fpu" change fp state.
  658. ret
  659. #undef V
  660. .size __save_fpu, .-__save_fpu
  661. .align 4
  662. restore_fpu:
  663. and $3, TS_RESTORE_FP, $3
  664. bic $2, TS_SAVED_FP | TS_RESTORE_FP, $2
  665. beq $3, 1f
  666. #define V(n) ldt $f##n, FR(n)
  667. ldt $f30, FR(31) # get saved fpcr
  668. V( 0); V( 1); V( 2); V( 3)
  669. mt_fpcr $f30 # install saved fpcr
  670. V( 4); V( 5); V( 6); V( 7)
  671. V( 8); V( 9); V(10); V(11)
  672. V(12); V(13); V(14); V(15)
  673. V(16); V(17); V(18); V(19)
  674. V(20); V(21); V(22); V(23)
  675. V(24); V(25); V(26); V(27)
  676. V(28); V(29); V(30)
  677. 1: stl $2, TI_STATUS($8)
  678. br restore_other
  679. #undef V
  680. /*
  681. * The meat of the context switch code.
  682. */
  683. .align 4
  684. .globl alpha_switch_to
  685. .type alpha_switch_to, @function
  686. .cfi_startproc
  687. alpha_switch_to:
  688. DO_SWITCH_STACK
  689. ldl $1, TI_STATUS($8)
  690. and $1, TS_RESTORE_FP, $3
  691. bne $3, 1f
  692. or $1, TS_RESTORE_FP | TS_SAVED_FP, $2
  693. and $1, TS_SAVED_FP, $3
  694. stl $2, TI_STATUS($8)
  695. bne $3, 1f
  696. bsr $26, __save_fpu
  697. 1:
  698. call_pal PAL_swpctx
  699. lda $8, 0x3fff
  700. UNDO_SWITCH_STACK
  701. bic $sp, $8, $8
  702. mov $17, $0
  703. ret
  704. .cfi_endproc
  705. .size alpha_switch_to, .-alpha_switch_to
  706. /*
  707. * New processes begin life here.
  708. */
  709. .globl ret_from_fork
  710. .align 4
  711. .ent ret_from_fork
  712. ret_from_fork:
  713. lda $26, ret_to_user
  714. mov $17, $16
  715. jmp $31, schedule_tail
  716. .end ret_from_fork
  717. /*
  718. * ... and new kernel threads - here
  719. */
  720. .align 4
  721. .globl ret_from_kernel_thread
  722. .ent ret_from_kernel_thread
  723. ret_from_kernel_thread:
  724. mov $17, $16
  725. jsr $26, schedule_tail
  726. mov $9, $27
  727. mov $10, $16
  728. jsr $26, ($9)
  729. br $31, ret_to_user
  730. .end ret_from_kernel_thread
  731. /*
  732. * Special system calls. Most of these are special in that they either
  733. * have to play switch_stack games.
  734. */
  735. .macro fork_like name
  736. .align 4
  737. .globl alpha_\name
  738. .ent alpha_\name
  739. alpha_\name:
  740. .prologue 0
  741. bsr $1, do_switch_stack
  742. // NB: if anyone adds preemption, this block will need to be protected
  743. ldl $1, TI_STATUS($8)
  744. and $1, TS_SAVED_FP, $3
  745. or $1, TS_SAVED_FP, $2
  746. bne $3, 1f
  747. stl $2, TI_STATUS($8)
  748. bsr $26, __save_fpu
  749. 1:
  750. jsr $26, sys_\name
  751. ldq $26, 56($sp)
  752. lda $sp, SWITCH_STACK_SIZE($sp)
  753. ret
  754. .end alpha_\name
  755. .endm
  756. fork_like fork
  757. fork_like vfork
  758. fork_like clone
  759. fork_like clone3
  760. .macro sigreturn_like name
  761. .align 4
  762. .globl sys_\name
  763. .ent sys_\name
  764. sys_\name:
  765. .prologue 0
  766. lda $9, ret_from_straced
  767. cmpult $26, $9, $9
  768. lda $sp, -SWITCH_STACK_SIZE($sp)
  769. jsr $26, do_\name
  770. bne $9, 1f
  771. jsr $26, syscall_trace_leave
  772. 1: br $1, undo_switch_stack
  773. br ret_from_sys_call
  774. .end sys_\name
  775. .endm
  776. sigreturn_like sigreturn
  777. sigreturn_like rt_sigreturn
  778. .align 4
  779. .globl alpha_syscall_zero
  780. .ent alpha_syscall_zero
  781. alpha_syscall_zero:
  782. .prologue 0
  783. /* Special because it needs to do something opposite to
  784. force_successful_syscall_return(). We use the saved
  785. syscall number for that, zero meaning "not an error".
  786. That works nicely, but for real syscall 0 we need to
  787. make sure that this logics doesn't get confused.
  788. Store a non-zero there - -ENOSYS we need in register
  789. for our return value will do just fine.
  790. */
  791. lda $0, -ENOSYS
  792. unop
  793. stq $0, 0($sp)
  794. ret
  795. .end alpha_syscall_zero