entry.S 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. /*
  2. * arch/alpha/kernel/entry.S
  3. *
  4. * Kernel entry-points.
  5. */
  6. #include <asm/asm-offsets.h>
  7. #include <asm/thread_info.h>
  8. #include <asm/pal.h>
  9. #include <asm/errno.h>
  10. #include <asm/unistd.h>
  11. .text
  12. .set noat
  13. /* Stack offsets. */
  14. #define SP_OFF 184
  15. #define SWITCH_STACK_SIZE 320
  16. /*
  17. * This defines the normal kernel pt-regs layout.
  18. *
  19. * regs 9-15 preserved by C code
  20. * regs 16-18 saved by PAL-code
  21. * regs 29-30 saved and set up by PAL-code
  22. * JRP - Save regs 16-18 in a special area of the stack, so that
  23. * the palcode-provided values are available to the signal handler.
  24. */
  25. #define SAVE_ALL \
  26. subq $sp, SP_OFF, $sp; \
  27. stq $0, 0($sp); \
  28. stq $1, 8($sp); \
  29. stq $2, 16($sp); \
  30. stq $3, 24($sp); \
  31. stq $4, 32($sp); \
  32. stq $28, 144($sp); \
  33. lda $2, alpha_mv; \
  34. stq $5, 40($sp); \
  35. stq $6, 48($sp); \
  36. stq $7, 56($sp); \
  37. stq $8, 64($sp); \
  38. stq $19, 72($sp); \
  39. stq $20, 80($sp); \
  40. stq $21, 88($sp); \
  41. ldq $2, HAE_CACHE($2); \
  42. stq $22, 96($sp); \
  43. stq $23, 104($sp); \
  44. stq $24, 112($sp); \
  45. stq $25, 120($sp); \
  46. stq $26, 128($sp); \
  47. stq $27, 136($sp); \
  48. stq $2, 152($sp); \
  49. stq $16, 160($sp); \
  50. stq $17, 168($sp); \
  51. stq $18, 176($sp)
  52. #define RESTORE_ALL \
  53. lda $19, alpha_mv; \
  54. ldq $0, 0($sp); \
  55. ldq $1, 8($sp); \
  56. ldq $2, 16($sp); \
  57. ldq $3, 24($sp); \
  58. ldq $21, 152($sp); \
  59. ldq $20, HAE_CACHE($19); \
  60. ldq $4, 32($sp); \
  61. ldq $5, 40($sp); \
  62. ldq $6, 48($sp); \
  63. ldq $7, 56($sp); \
  64. subq $20, $21, $20; \
  65. ldq $8, 64($sp); \
  66. beq $20, 99f; \
  67. ldq $20, HAE_REG($19); \
  68. stq $21, HAE_CACHE($19); \
  69. stq $21, 0($20); \
  70. 99:; \
  71. ldq $19, 72($sp); \
  72. ldq $20, 80($sp); \
  73. ldq $21, 88($sp); \
  74. ldq $22, 96($sp); \
  75. ldq $23, 104($sp); \
  76. ldq $24, 112($sp); \
  77. ldq $25, 120($sp); \
  78. ldq $26, 128($sp); \
  79. ldq $27, 136($sp); \
  80. ldq $28, 144($sp); \
  81. addq $sp, SP_OFF, $sp
  82. /*
  83. * Non-syscall kernel entry points.
  84. */
  85. .align 4
  86. .globl entInt
  87. .ent entInt
  88. entInt:
  89. SAVE_ALL
  90. lda $8, 0x3fff
  91. lda $26, ret_from_sys_call
  92. bic $sp, $8, $8
  93. mov $sp, $19
  94. jsr $31, do_entInt
  95. .end entInt
  96. .align 4
  97. .globl entArith
  98. .ent entArith
  99. entArith:
  100. SAVE_ALL
  101. lda $8, 0x3fff
  102. lda $26, ret_from_sys_call
  103. bic $sp, $8, $8
  104. mov $sp, $18
  105. jsr $31, do_entArith
  106. .end entArith
  107. .align 4
  108. .globl entMM
  109. .ent entMM
  110. entMM:
  111. SAVE_ALL
  112. /* save $9 - $15 so the inline exception code can manipulate them. */
  113. subq $sp, 56, $sp
  114. stq $9, 0($sp)
  115. stq $10, 8($sp)
  116. stq $11, 16($sp)
  117. stq $12, 24($sp)
  118. stq $13, 32($sp)
  119. stq $14, 40($sp)
  120. stq $15, 48($sp)
  121. addq $sp, 56, $19
  122. /* handle the fault */
  123. lda $8, 0x3fff
  124. bic $sp, $8, $8
  125. jsr $26, do_page_fault
  126. /* reload the registers after the exception code played. */
  127. ldq $9, 0($sp)
  128. ldq $10, 8($sp)
  129. ldq $11, 16($sp)
  130. ldq $12, 24($sp)
  131. ldq $13, 32($sp)
  132. ldq $14, 40($sp)
  133. ldq $15, 48($sp)
  134. addq $sp, 56, $sp
  135. /* finish up the syscall as normal. */
  136. br ret_from_sys_call
  137. .end entMM
  138. .align 4
  139. .globl entIF
  140. .ent entIF
  141. entIF:
  142. SAVE_ALL
  143. lda $8, 0x3fff
  144. lda $26, ret_from_sys_call
  145. bic $sp, $8, $8
  146. mov $sp, $17
  147. jsr $31, do_entIF
  148. .end entIF
  149. .align 4
  150. .globl entUna
  151. .ent entUna
  152. entUna:
  153. lda $sp, -256($sp)
  154. stq $0, 0($sp)
  155. ldq $0, 256($sp) /* get PS */
  156. stq $1, 8($sp)
  157. stq $2, 16($sp)
  158. stq $3, 24($sp)
  159. and $0, 8, $0 /* user mode? */
  160. stq $4, 32($sp)
  161. bne $0, entUnaUser /* yup -> do user-level unaligned fault */
  162. stq $5, 40($sp)
  163. stq $6, 48($sp)
  164. stq $7, 56($sp)
  165. stq $8, 64($sp)
  166. stq $9, 72($sp)
  167. stq $10, 80($sp)
  168. stq $11, 88($sp)
  169. stq $12, 96($sp)
  170. stq $13, 104($sp)
  171. stq $14, 112($sp)
  172. stq $15, 120($sp)
  173. /* 16-18 PAL-saved */
  174. stq $19, 152($sp)
  175. stq $20, 160($sp)
  176. stq $21, 168($sp)
  177. stq $22, 176($sp)
  178. stq $23, 184($sp)
  179. stq $24, 192($sp)
  180. stq $25, 200($sp)
  181. stq $26, 208($sp)
  182. stq $27, 216($sp)
  183. stq $28, 224($sp)
  184. mov $sp, $19
  185. stq $gp, 232($sp)
  186. lda $8, 0x3fff
  187. stq $31, 248($sp)
  188. bic $sp, $8, $8
  189. jsr $26, do_entUna
  190. ldq $0, 0($sp)
  191. ldq $1, 8($sp)
  192. ldq $2, 16($sp)
  193. ldq $3, 24($sp)
  194. ldq $4, 32($sp)
  195. ldq $5, 40($sp)
  196. ldq $6, 48($sp)
  197. ldq $7, 56($sp)
  198. ldq $8, 64($sp)
  199. ldq $9, 72($sp)
  200. ldq $10, 80($sp)
  201. ldq $11, 88($sp)
  202. ldq $12, 96($sp)
  203. ldq $13, 104($sp)
  204. ldq $14, 112($sp)
  205. ldq $15, 120($sp)
  206. /* 16-18 PAL-saved */
  207. ldq $19, 152($sp)
  208. ldq $20, 160($sp)
  209. ldq $21, 168($sp)
  210. ldq $22, 176($sp)
  211. ldq $23, 184($sp)
  212. ldq $24, 192($sp)
  213. ldq $25, 200($sp)
  214. ldq $26, 208($sp)
  215. ldq $27, 216($sp)
  216. ldq $28, 224($sp)
  217. ldq $gp, 232($sp)
  218. lda $sp, 256($sp)
  219. call_pal PAL_rti
  220. .end entUna
  221. .align 4
  222. .ent entUnaUser
  223. entUnaUser:
  224. ldq $0, 0($sp) /* restore original $0 */
  225. lda $sp, 256($sp) /* pop entUna's stack frame */
  226. SAVE_ALL /* setup normal kernel stack */
  227. lda $sp, -56($sp)
  228. stq $9, 0($sp)
  229. stq $10, 8($sp)
  230. stq $11, 16($sp)
  231. stq $12, 24($sp)
  232. stq $13, 32($sp)
  233. stq $14, 40($sp)
  234. stq $15, 48($sp)
  235. lda $8, 0x3fff
  236. addq $sp, 56, $19
  237. bic $sp, $8, $8
  238. jsr $26, do_entUnaUser
  239. ldq $9, 0($sp)
  240. ldq $10, 8($sp)
  241. ldq $11, 16($sp)
  242. ldq $12, 24($sp)
  243. ldq $13, 32($sp)
  244. ldq $14, 40($sp)
  245. ldq $15, 48($sp)
  246. lda $sp, 56($sp)
  247. br ret_from_sys_call
  248. .end entUnaUser
  249. .align 4
  250. .globl entDbg
  251. .ent entDbg
  252. entDbg:
  253. SAVE_ALL
  254. lda $8, 0x3fff
  255. lda $26, ret_from_sys_call
  256. bic $sp, $8, $8
  257. mov $sp, $16
  258. jsr $31, do_entDbg
  259. .end entDbg
  260. /*
  261. * The system call entry point is special. Most importantly, it looks
  262. * like a function call to userspace as far as clobbered registers. We
  263. * do preserve the argument registers (for syscall restarts) and $26
  264. * (for leaf syscall functions).
  265. *
  266. * So much for theory. We don't take advantage of this yet.
  267. *
  268. * Note that a0-a2 are not saved by PALcode as with the other entry points.
  269. */
  270. .align 4
  271. .globl entSys
  272. .globl ret_from_sys_call
  273. .ent entSys
  274. entSys:
  275. SAVE_ALL
  276. lda $8, 0x3fff
  277. bic $sp, $8, $8
  278. lda $4, NR_SYSCALLS($31)
  279. stq $16, SP_OFF+24($sp)
  280. lda $5, sys_call_table
  281. lda $27, sys_ni_syscall
  282. cmpult $0, $4, $4
  283. ldl $3, TI_FLAGS($8)
  284. stq $17, SP_OFF+32($sp)
  285. s8addq $0, $5, $5
  286. stq $18, SP_OFF+40($sp)
  287. blbs $3, strace
  288. beq $4, 1f
  289. ldq $27, 0($5)
  290. 1: jsr $26, ($27), alpha_ni_syscall
  291. ldgp $gp, 0($26)
  292. blt $0, $syscall_error /* the call failed */
  293. stq $0, 0($sp)
  294. stq $31, 72($sp) /* a3=0 => no error */
  295. .align 4
  296. ret_from_sys_call:
  297. cmovne $26, 0, $19 /* $19 = 0 => non-restartable */
  298. ldq $0, SP_OFF($sp)
  299. and $0, 8, $0
  300. beq $0, ret_to_kernel
  301. ret_to_user:
  302. /* Make sure need_resched and sigpending don't change between
  303. sampling and the rti. */
  304. lda $16, 7
  305. call_pal PAL_swpipl
  306. ldl $5, TI_FLAGS($8)
  307. and $5, _TIF_WORK_MASK, $2
  308. bne $2, work_pending
  309. restore_all:
  310. RESTORE_ALL
  311. call_pal PAL_rti
  312. ret_to_kernel:
  313. lda $16, 7
  314. call_pal PAL_swpipl
  315. br restore_all
  316. .align 3
  317. $syscall_error:
  318. /*
  319. * Some system calls (e.g., ptrace) can return arbitrary
  320. * values which might normally be mistaken as error numbers.
  321. * Those functions must zero $0 (v0) directly in the stack
  322. * frame to indicate that a negative return value wasn't an
  323. * error number..
  324. */
  325. ldq $19, 0($sp) /* old syscall nr (zero if success) */
  326. beq $19, $ret_success
  327. ldq $20, 72($sp) /* .. and this a3 */
  328. subq $31, $0, $0 /* with error in v0 */
  329. addq $31, 1, $1 /* set a3 for errno return */
  330. stq $0, 0($sp)
  331. mov $31, $26 /* tell "ret_from_sys_call" we can restart */
  332. stq $1, 72($sp) /* a3 for return */
  333. br ret_from_sys_call
  334. $ret_success:
  335. stq $0, 0($sp)
  336. stq $31, 72($sp) /* a3=0 => no error */
  337. br ret_from_sys_call
  338. .end entSys
  339. /*
  340. * Do all cleanup when returning from all interrupts and system calls.
  341. *
  342. * Arguments:
  343. * $5: TI_FLAGS.
  344. * $8: current.
  345. * $19: The old syscall number, or zero if this is not a return
  346. * from a syscall that errored and is possibly restartable.
  347. * $20: The old a3 value
  348. */
  349. .align 4
  350. .ent work_pending
  351. work_pending:
  352. and $5, _TIF_NEED_RESCHED, $2
  353. beq $2, $work_notifysig
  354. $work_resched:
  355. subq $sp, 16, $sp
  356. stq $19, 0($sp) /* save syscall nr */
  357. stq $20, 8($sp) /* and error indication (a3) */
  358. jsr $26, schedule
  359. ldq $19, 0($sp)
  360. ldq $20, 8($sp)
  361. addq $sp, 16, $sp
  362. /* Make sure need_resched and sigpending don't change between
  363. sampling and the rti. */
  364. lda $16, 7
  365. call_pal PAL_swpipl
  366. ldl $5, TI_FLAGS($8)
  367. and $5, _TIF_WORK_MASK, $2
  368. beq $2, restore_all
  369. and $5, _TIF_NEED_RESCHED, $2
  370. bne $2, $work_resched
  371. $work_notifysig:
  372. mov $sp, $16
  373. bsr $1, do_switch_stack
  374. mov $sp, $17
  375. mov $5, $18
  376. mov $19, $9 /* save old syscall number */
  377. mov $20, $10 /* save old a3 */
  378. and $5, _TIF_SIGPENDING, $2
  379. cmovne $2, 0, $9 /* we don't want double syscall restarts */
  380. jsr $26, do_notify_resume
  381. mov $9, $19
  382. mov $10, $20
  383. bsr $1, undo_switch_stack
  384. br ret_to_user
  385. .end work_pending
  386. /*
  387. * PTRACE syscall handler
  388. */
  389. .align 4
  390. .ent strace
  391. strace:
  392. /* set up signal stack, call syscall_trace */
  393. bsr $1, do_switch_stack
  394. jsr $26, syscall_trace
  395. bsr $1, undo_switch_stack
  396. /* get the system call number and the arguments back.. */
  397. ldq $0, 0($sp)
  398. ldq $16, SP_OFF+24($sp)
  399. ldq $17, SP_OFF+32($sp)
  400. ldq $18, SP_OFF+40($sp)
  401. ldq $19, 72($sp)
  402. ldq $20, 80($sp)
  403. ldq $21, 88($sp)
  404. /* get the system call pointer.. */
  405. lda $1, NR_SYSCALLS($31)
  406. lda $2, sys_call_table
  407. lda $27, alpha_ni_syscall
  408. cmpult $0, $1, $1
  409. s8addq $0, $2, $2
  410. beq $1, 1f
  411. ldq $27, 0($2)
  412. 1: jsr $26, ($27), sys_gettimeofday
  413. ret_from_straced:
  414. ldgp $gp, 0($26)
  415. /* check return.. */
  416. blt $0, $strace_error /* the call failed */
  417. stq $31, 72($sp) /* a3=0 => no error */
  418. $strace_success:
  419. stq $0, 0($sp) /* save return value */
  420. bsr $1, do_switch_stack
  421. jsr $26, syscall_trace
  422. bsr $1, undo_switch_stack
  423. br $31, ret_from_sys_call
  424. .align 3
  425. $strace_error:
  426. ldq $19, 0($sp) /* old syscall nr (zero if success) */
  427. beq $19, $strace_success
  428. ldq $20, 72($sp) /* .. and this a3 */
  429. subq $31, $0, $0 /* with error in v0 */
  430. addq $31, 1, $1 /* set a3 for errno return */
  431. stq $0, 0($sp)
  432. stq $1, 72($sp) /* a3 for return */
  433. bsr $1, do_switch_stack
  434. mov $19, $9 /* save old syscall number */
  435. mov $20, $10 /* save old a3 */
  436. jsr $26, syscall_trace
  437. mov $9, $19
  438. mov $10, $20
  439. bsr $1, undo_switch_stack
  440. mov $31, $26 /* tell "ret_from_sys_call" we can restart */
  441. br ret_from_sys_call
  442. .end strace
  443. /*
  444. * Save and restore the switch stack -- aka the balance of the user context.
  445. */
  446. .align 4
  447. .ent do_switch_stack
  448. do_switch_stack:
  449. lda $sp, -SWITCH_STACK_SIZE($sp)
  450. stq $9, 0($sp)
  451. stq $10, 8($sp)
  452. stq $11, 16($sp)
  453. stq $12, 24($sp)
  454. stq $13, 32($sp)
  455. stq $14, 40($sp)
  456. stq $15, 48($sp)
  457. stq $26, 56($sp)
  458. stt $f0, 64($sp)
  459. stt $f1, 72($sp)
  460. stt $f2, 80($sp)
  461. stt $f3, 88($sp)
  462. stt $f4, 96($sp)
  463. stt $f5, 104($sp)
  464. stt $f6, 112($sp)
  465. stt $f7, 120($sp)
  466. stt $f8, 128($sp)
  467. stt $f9, 136($sp)
  468. stt $f10, 144($sp)
  469. stt $f11, 152($sp)
  470. stt $f12, 160($sp)
  471. stt $f13, 168($sp)
  472. stt $f14, 176($sp)
  473. stt $f15, 184($sp)
  474. stt $f16, 192($sp)
  475. stt $f17, 200($sp)
  476. stt $f18, 208($sp)
  477. stt $f19, 216($sp)
  478. stt $f20, 224($sp)
  479. stt $f21, 232($sp)
  480. stt $f22, 240($sp)
  481. stt $f23, 248($sp)
  482. stt $f24, 256($sp)
  483. stt $f25, 264($sp)
  484. stt $f26, 272($sp)
  485. stt $f27, 280($sp)
  486. mf_fpcr $f0 # get fpcr
  487. stt $f28, 288($sp)
  488. stt $f29, 296($sp)
  489. stt $f30, 304($sp)
  490. stt $f0, 312($sp) # save fpcr in slot of $f31
  491. ldt $f0, 64($sp) # dont let "do_switch_stack" change fp state.
  492. ret $31, ($1), 1
  493. .end do_switch_stack
  494. .align 4
  495. .ent undo_switch_stack
  496. undo_switch_stack:
  497. ldq $9, 0($sp)
  498. ldq $10, 8($sp)
  499. ldq $11, 16($sp)
  500. ldq $12, 24($sp)
  501. ldq $13, 32($sp)
  502. ldq $14, 40($sp)
  503. ldq $15, 48($sp)
  504. ldq $26, 56($sp)
  505. ldt $f30, 312($sp) # get saved fpcr
  506. ldt $f0, 64($sp)
  507. ldt $f1, 72($sp)
  508. ldt $f2, 80($sp)
  509. ldt $f3, 88($sp)
  510. mt_fpcr $f30 # install saved fpcr
  511. ldt $f4, 96($sp)
  512. ldt $f5, 104($sp)
  513. ldt $f6, 112($sp)
  514. ldt $f7, 120($sp)
  515. ldt $f8, 128($sp)
  516. ldt $f9, 136($sp)
  517. ldt $f10, 144($sp)
  518. ldt $f11, 152($sp)
  519. ldt $f12, 160($sp)
  520. ldt $f13, 168($sp)
  521. ldt $f14, 176($sp)
  522. ldt $f15, 184($sp)
  523. ldt $f16, 192($sp)
  524. ldt $f17, 200($sp)
  525. ldt $f18, 208($sp)
  526. ldt $f19, 216($sp)
  527. ldt $f20, 224($sp)
  528. ldt $f21, 232($sp)
  529. ldt $f22, 240($sp)
  530. ldt $f23, 248($sp)
  531. ldt $f24, 256($sp)
  532. ldt $f25, 264($sp)
  533. ldt $f26, 272($sp)
  534. ldt $f27, 280($sp)
  535. ldt $f28, 288($sp)
  536. ldt $f29, 296($sp)
  537. ldt $f30, 304($sp)
  538. lda $sp, SWITCH_STACK_SIZE($sp)
  539. ret $31, ($1), 1
  540. .end undo_switch_stack
  541. /*
  542. * The meat of the context switch code.
  543. */
  544. .align 4
  545. .globl alpha_switch_to
  546. .ent alpha_switch_to
  547. alpha_switch_to:
  548. .prologue 0
  549. bsr $1, do_switch_stack
  550. call_pal PAL_swpctx
  551. lda $8, 0x3fff
  552. bsr $1, undo_switch_stack
  553. bic $sp, $8, $8
  554. mov $17, $0
  555. ret
  556. .end alpha_switch_to
  557. /*
  558. * New processes begin life here.
  559. */
  560. .globl ret_from_fork
  561. .align 4
  562. .ent ret_from_fork
  563. ret_from_fork:
  564. lda $26, ret_from_sys_call
  565. mov $17, $16
  566. jmp $31, schedule_tail
  567. .end ret_from_fork
  568. /*
  569. * kernel_thread(fn, arg, clone_flags)
  570. */
  571. .align 4
  572. .globl kernel_thread
  573. .ent kernel_thread
  574. kernel_thread:
  575. /* We can be called from a module. */
  576. ldgp $gp, 0($27)
  577. .prologue 1
  578. subq $sp, SP_OFF+6*8, $sp
  579. br $1, 2f /* load start address */
  580. /* We've now "returned" from a fake system call. */
  581. unop
  582. blt $0, 1f /* error? */
  583. ldi $1, 0x3fff
  584. beq $20, 1f /* parent or child? */
  585. bic $sp, $1, $8 /* in child. */
  586. jsr $26, ($27)
  587. ldgp $gp, 0($26)
  588. mov $0, $16
  589. mov $31, $26
  590. jmp $31, sys_exit
  591. 1: ret /* in parent. */
  592. .align 4
  593. 2: /* Fake a system call stack frame, as we can't do system calls
  594. from kernel space. Note that we store FN and ARG as they
  595. need to be set up in the child for the call. Also store $8
  596. and $26 for use in the parent. */
  597. stq $31, SP_OFF($sp) /* ps */
  598. stq $1, SP_OFF+8($sp) /* pc */
  599. stq $gp, SP_OFF+16($sp) /* gp */
  600. stq $16, 136($sp) /* $27; FN for child */
  601. stq $17, SP_OFF+24($sp) /* $16; ARG for child */
  602. stq $8, 64($sp) /* $8 */
  603. stq $26, 128($sp) /* $26 */
  604. /* Avoid the HAE being gratuitously wrong, to avoid restoring it. */
  605. ldq $2, alpha_mv+HAE_CACHE
  606. stq $2, 152($sp) /* HAE */
  607. /* Shuffle FLAGS to the front; add CLONE_VM. */
  608. ldi $1, CLONE_VM|CLONE_UNTRACED
  609. or $18, $1, $16
  610. bsr $26, sys_clone
  611. /* We don't actually care for a3 success widgetry in the kernel.
  612. Not for positive errno values. */
  613. stq $0, 0($sp) /* $0 */
  614. br ret_to_kernel
  615. .end kernel_thread
  616. /*
  617. * kernel_execve(path, argv, envp)
  618. */
  619. .align 4
  620. .globl kernel_execve
  621. .ent kernel_execve
  622. kernel_execve:
  623. /* We can be called from a module. */
  624. ldgp $gp, 0($27)
  625. lda $sp, -(32+SIZEOF_PT_REGS+8)($sp)
  626. .frame $sp, 32+SIZEOF_PT_REGS+8, $26, 0
  627. stq $26, 0($sp)
  628. stq $16, 8($sp)
  629. stq $17, 16($sp)
  630. stq $18, 24($sp)
  631. .prologue 1
  632. lda $16, 32($sp)
  633. lda $17, 0
  634. lda $18, SIZEOF_PT_REGS
  635. bsr $26, memset !samegp
  636. /* Avoid the HAE being gratuitously wrong, which would cause us
  637. to do the whole turn off interrupts thing and restore it. */
  638. ldq $2, alpha_mv+HAE_CACHE
  639. stq $2, 152+32($sp)
  640. ldq $16, 8($sp)
  641. ldq $17, 16($sp)
  642. ldq $18, 24($sp)
  643. lda $19, 32($sp)
  644. bsr $26, do_execve !samegp
  645. ldq $26, 0($sp)
  646. bne $0, 1f /* error! */
  647. /* Move the temporary pt_regs struct from its current location
  648. to the top of the kernel stack frame. See copy_thread for
  649. details for a normal process. */
  650. lda $16, 0x4000 - SIZEOF_PT_REGS($8)
  651. lda $17, 32($sp)
  652. lda $18, SIZEOF_PT_REGS
  653. bsr $26, memmove !samegp
  654. /* Take that over as our new stack frame and visit userland! */
  655. lda $sp, 0x4000 - SIZEOF_PT_REGS($8)
  656. br $31, ret_from_sys_call
  657. 1: lda $sp, 32+SIZEOF_PT_REGS+8($sp)
  658. ret
  659. .end kernel_execve
  660. /*
  661. * Special system calls. Most of these are special in that they either
  662. * have to play switch_stack games or in some way use the pt_regs struct.
  663. */
  664. .align 4
  665. .globl sys_fork
  666. .ent sys_fork
  667. sys_fork:
  668. .prologue 0
  669. mov $sp, $21
  670. bsr $1, do_switch_stack
  671. bis $31, SIGCHLD, $16
  672. mov $31, $17
  673. mov $31, $18
  674. mov $31, $19
  675. mov $31, $20
  676. jsr $26, alpha_clone
  677. bsr $1, undo_switch_stack
  678. ret
  679. .end sys_fork
  680. .align 4
  681. .globl sys_clone
  682. .ent sys_clone
  683. sys_clone:
  684. .prologue 0
  685. mov $sp, $21
  686. bsr $1, do_switch_stack
  687. /* $16, $17, $18, $19, $20 come from the user. */
  688. jsr $26, alpha_clone
  689. bsr $1, undo_switch_stack
  690. ret
  691. .end sys_clone
  692. .align 4
  693. .globl sys_vfork
  694. .ent sys_vfork
  695. sys_vfork:
  696. .prologue 0
  697. mov $sp, $16
  698. bsr $1, do_switch_stack
  699. jsr $26, alpha_vfork
  700. bsr $1, undo_switch_stack
  701. ret
  702. .end sys_vfork
  703. .align 4
  704. .globl sys_sigreturn
  705. .ent sys_sigreturn
  706. sys_sigreturn:
  707. .prologue 0
  708. lda $9, ret_from_straced
  709. cmpult $26, $9, $9
  710. mov $sp, $17
  711. lda $18, -SWITCH_STACK_SIZE($sp)
  712. lda $sp, -SWITCH_STACK_SIZE($sp)
  713. jsr $26, do_sigreturn
  714. bne $9, 1f
  715. jsr $26, syscall_trace
  716. 1: br $1, undo_switch_stack
  717. br ret_from_sys_call
  718. .end sys_sigreturn
  719. .align 4
  720. .globl sys_rt_sigreturn
  721. .ent sys_rt_sigreturn
  722. sys_rt_sigreturn:
  723. .prologue 0
  724. lda $9, ret_from_straced
  725. cmpult $26, $9, $9
  726. mov $sp, $17
  727. lda $18, -SWITCH_STACK_SIZE($sp)
  728. lda $sp, -SWITCH_STACK_SIZE($sp)
  729. jsr $26, do_rt_sigreturn
  730. bne $9, 1f
  731. jsr $26, syscall_trace
  732. 1: br $1, undo_switch_stack
  733. br ret_from_sys_call
  734. .end sys_rt_sigreturn
  735. .align 4
  736. .globl sys_sethae
  737. .ent sys_sethae
  738. sys_sethae:
  739. .prologue 0
  740. stq $16, 152($sp)
  741. ret
  742. .end sys_sethae
  743. .align 4
  744. .globl osf_getpriority
  745. .ent osf_getpriority
  746. osf_getpriority:
  747. lda $sp, -16($sp)
  748. stq $26, 0($sp)
  749. .prologue 0
  750. jsr $26, sys_getpriority
  751. ldq $26, 0($sp)
  752. blt $0, 1f
  753. /* Return value is the unbiased priority, i.e. 20 - prio.
  754. This does result in negative return values, so signal
  755. no error by writing into the R0 slot. */
  756. lda $1, 20
  757. stq $31, 16($sp)
  758. subl $1, $0, $0
  759. unop
  760. 1: lda $sp, 16($sp)
  761. ret
  762. .end osf_getpriority
  763. .align 4
  764. .globl sys_getxuid
  765. .ent sys_getxuid
  766. sys_getxuid:
  767. .prologue 0
  768. ldq $2, TI_TASK($8)
  769. ldq $3, TASK_CRED($2)
  770. ldl $0, CRED_UID($3)
  771. ldl $1, CRED_EUID($3)
  772. stq $1, 80($sp)
  773. ret
  774. .end sys_getxuid
  775. .align 4
  776. .globl sys_getxgid
  777. .ent sys_getxgid
  778. sys_getxgid:
  779. .prologue 0
  780. ldq $2, TI_TASK($8)
  781. ldq $3, TASK_CRED($2)
  782. ldl $0, CRED_GID($3)
  783. ldl $1, CRED_EGID($3)
  784. stq $1, 80($sp)
  785. ret
  786. .end sys_getxgid
  787. .align 4
  788. .globl sys_getxpid
  789. .ent sys_getxpid
  790. sys_getxpid:
  791. .prologue 0
  792. ldq $2, TI_TASK($8)
  793. /* See linux/kernel/timer.c sys_getppid for discussion
  794. about this loop. */
  795. ldq $3, TASK_GROUP_LEADER($2)
  796. ldq $4, TASK_REAL_PARENT($3)
  797. ldl $0, TASK_TGID($2)
  798. 1: ldl $1, TASK_TGID($4)
  799. #ifdef CONFIG_SMP
  800. mov $4, $5
  801. mb
  802. ldq $3, TASK_GROUP_LEADER($2)
  803. ldq $4, TASK_REAL_PARENT($3)
  804. cmpeq $4, $5, $5
  805. beq $5, 1b
  806. #endif
  807. stq $1, 80($sp)
  808. ret
  809. .end sys_getxpid
  810. .align 4
  811. .globl sys_alpha_pipe
  812. .ent sys_alpha_pipe
  813. sys_alpha_pipe:
  814. lda $sp, -16($sp)
  815. stq $26, 0($sp)
  816. .prologue 0
  817. mov $31, $17
  818. lda $16, 8($sp)
  819. jsr $26, do_pipe_flags
  820. ldq $26, 0($sp)
  821. bne $0, 1f
  822. /* The return values are in $0 and $20. */
  823. ldl $1, 12($sp)
  824. ldl $0, 8($sp)
  825. stq $1, 80+16($sp)
  826. 1: lda $sp, 16($sp)
  827. ret
  828. .end sys_alpha_pipe
  829. .align 4
  830. .globl sys_execve
  831. .ent sys_execve
  832. sys_execve:
  833. .prologue 0
  834. mov $sp, $19
  835. jmp $31, do_sys_execve
  836. .end sys_execve
  837. .align 4
  838. .globl alpha_ni_syscall
  839. .ent alpha_ni_syscall
  840. alpha_ni_syscall:
  841. .prologue 0
  842. /* Special because it also implements overflow handling via
  843. syscall number 0. And if you recall, zero is a special
  844. trigger for "not an error". Store large non-zero there. */
  845. lda $0, -ENOSYS
  846. unop
  847. stq $0, 0($sp)
  848. ret
  849. .end alpha_ni_syscall