entry.S 19 KB

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