entry.S 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957
  1. /*
  2. * arch/alpha/kernel/entry.S
  3. *
  4. * Kernel entry-points.
  5. */
  6. #include <linux/config.h>
  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. /* Stack offsets. */
  15. #define SP_OFF 184
  16. #define SWITCH_STACK_SIZE 320
  17. /*
  18. * This defines the normal kernel pt-regs layout.
  19. *
  20. * regs 9-15 preserved by C code
  21. * regs 16-18 saved by PAL-code
  22. * regs 29-30 saved and set up by PAL-code
  23. * JRP - Save regs 16-18 in a special area of the stack, so that
  24. * the palcode-provided values are available to the signal handler.
  25. */
  26. #define SAVE_ALL \
  27. subq $sp, SP_OFF, $sp; \
  28. stq $0, 0($sp); \
  29. stq $1, 8($sp); \
  30. stq $2, 16($sp); \
  31. stq $3, 24($sp); \
  32. stq $4, 32($sp); \
  33. stq $28, 144($sp); \
  34. lda $2, alpha_mv; \
  35. stq $5, 40($sp); \
  36. stq $6, 48($sp); \
  37. stq $7, 56($sp); \
  38. stq $8, 64($sp); \
  39. stq $19, 72($sp); \
  40. stq $20, 80($sp); \
  41. stq $21, 88($sp); \
  42. ldq $2, HAE_CACHE($2); \
  43. stq $22, 96($sp); \
  44. stq $23, 104($sp); \
  45. stq $24, 112($sp); \
  46. stq $25, 120($sp); \
  47. stq $26, 128($sp); \
  48. stq $27, 136($sp); \
  49. stq $2, 152($sp); \
  50. stq $16, 160($sp); \
  51. stq $17, 168($sp); \
  52. stq $18, 176($sp)
  53. #define RESTORE_ALL \
  54. lda $19, alpha_mv; \
  55. ldq $0, 0($sp); \
  56. ldq $1, 8($sp); \
  57. ldq $2, 16($sp); \
  58. ldq $3, 24($sp); \
  59. ldq $21, 152($sp); \
  60. ldq $20, HAE_CACHE($19); \
  61. ldq $4, 32($sp); \
  62. ldq $5, 40($sp); \
  63. ldq $6, 48($sp); \
  64. ldq $7, 56($sp); \
  65. subq $20, $21, $20; \
  66. ldq $8, 64($sp); \
  67. beq $20, 99f; \
  68. ldq $20, HAE_REG($19); \
  69. stq $21, HAE_CACHE($19); \
  70. stq $21, 0($20); \
  71. ldq $0, 0($sp); \
  72. ldq $1, 8($sp); \
  73. 99:; \
  74. ldq $19, 72($sp); \
  75. ldq $20, 80($sp); \
  76. ldq $21, 88($sp); \
  77. ldq $22, 96($sp); \
  78. ldq $23, 104($sp); \
  79. ldq $24, 112($sp); \
  80. ldq $25, 120($sp); \
  81. ldq $26, 128($sp); \
  82. ldq $27, 136($sp); \
  83. ldq $28, 144($sp); \
  84. addq $sp, SP_OFF, $sp
  85. /*
  86. * Non-syscall kernel entry points.
  87. */
  88. .align 4
  89. .globl entInt
  90. .ent entInt
  91. entInt:
  92. SAVE_ALL
  93. lda $8, 0x3fff
  94. lda $26, ret_from_sys_call
  95. bic $sp, $8, $8
  96. mov $sp, $19
  97. jsr $31, do_entInt
  98. .end entInt
  99. .align 4
  100. .globl entArith
  101. .ent entArith
  102. entArith:
  103. SAVE_ALL
  104. lda $8, 0x3fff
  105. lda $26, ret_from_sys_call
  106. bic $sp, $8, $8
  107. mov $sp, $18
  108. jsr $31, do_entArith
  109. .end entArith
  110. .align 4
  111. .globl entMM
  112. .ent entMM
  113. entMM:
  114. SAVE_ALL
  115. /* save $9 - $15 so the inline exception code can manipulate them. */
  116. subq $sp, 56, $sp
  117. stq $9, 0($sp)
  118. stq $10, 8($sp)
  119. stq $11, 16($sp)
  120. stq $12, 24($sp)
  121. stq $13, 32($sp)
  122. stq $14, 40($sp)
  123. stq $15, 48($sp)
  124. addq $sp, 56, $19
  125. /* handle the fault */
  126. lda $8, 0x3fff
  127. bic $sp, $8, $8
  128. jsr $26, do_page_fault
  129. /* reload the registers after the exception code played. */
  130. ldq $9, 0($sp)
  131. ldq $10, 8($sp)
  132. ldq $11, 16($sp)
  133. ldq $12, 24($sp)
  134. ldq $13, 32($sp)
  135. ldq $14, 40($sp)
  136. ldq $15, 48($sp)
  137. addq $sp, 56, $sp
  138. /* finish up the syscall as normal. */
  139. br ret_from_sys_call
  140. .end entMM
  141. .align 4
  142. .globl entIF
  143. .ent entIF
  144. entIF:
  145. SAVE_ALL
  146. lda $8, 0x3fff
  147. lda $26, ret_from_sys_call
  148. bic $sp, $8, $8
  149. mov $sp, $17
  150. jsr $31, do_entIF
  151. .end entIF
  152. .align 4
  153. .globl entUna
  154. .ent entUna
  155. entUna:
  156. lda $sp, -256($sp)
  157. stq $0, 0($sp)
  158. ldq $0, 256($sp) /* get PS */
  159. stq $1, 8($sp)
  160. stq $2, 16($sp)
  161. stq $3, 24($sp)
  162. and $0, 8, $0 /* user mode? */
  163. stq $4, 32($sp)
  164. bne $0, entUnaUser /* yup -> do user-level unaligned fault */
  165. stq $5, 40($sp)
  166. stq $6, 48($sp)
  167. stq $7, 56($sp)
  168. stq $8, 64($sp)
  169. stq $9, 72($sp)
  170. stq $10, 80($sp)
  171. stq $11, 88($sp)
  172. stq $12, 96($sp)
  173. stq $13, 104($sp)
  174. stq $14, 112($sp)
  175. stq $15, 120($sp)
  176. /* 16-18 PAL-saved */
  177. stq $19, 152($sp)
  178. stq $20, 160($sp)
  179. stq $21, 168($sp)
  180. stq $22, 176($sp)
  181. stq $23, 184($sp)
  182. stq $24, 192($sp)
  183. stq $25, 200($sp)
  184. stq $26, 208($sp)
  185. stq $27, 216($sp)
  186. stq $28, 224($sp)
  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_from_reschedule:
  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 $5, 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: Error indication.
  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, $17
  371. br $1, do_switch_stack
  372. mov $5, $21
  373. mov $sp, $18
  374. mov $31, $16
  375. jsr $26, do_notify_resume
  376. bsr $1, undo_switch_stack
  377. br restore_all
  378. .end work_pending
  379. /*
  380. * PTRACE syscall handler
  381. */
  382. .align 4
  383. .ent strace
  384. strace:
  385. /* set up signal stack, call syscall_trace */
  386. bsr $1, do_switch_stack
  387. jsr $26, syscall_trace
  388. bsr $1, undo_switch_stack
  389. /* get the system call number and the arguments back.. */
  390. ldq $0, 0($sp)
  391. ldq $16, SP_OFF+24($sp)
  392. ldq $17, SP_OFF+32($sp)
  393. ldq $18, SP_OFF+40($sp)
  394. ldq $19, 72($sp)
  395. ldq $20, 80($sp)
  396. ldq $21, 88($sp)
  397. /* get the system call pointer.. */
  398. lda $1, NR_SYSCALLS($31)
  399. lda $2, sys_call_table
  400. lda $27, alpha_ni_syscall
  401. cmpult $0, $1, $1
  402. s8addq $0, $2, $2
  403. beq $1, 1f
  404. ldq $27, 0($2)
  405. 1: jsr $26, ($27), sys_gettimeofday
  406. ldgp $gp, 0($26)
  407. /* check return.. */
  408. blt $0, $strace_error /* the call failed */
  409. stq $31, 72($sp) /* a3=0 => no error */
  410. $strace_success:
  411. stq $0, 0($sp) /* save return value */
  412. bsr $1, do_switch_stack
  413. jsr $26, syscall_trace
  414. bsr $1, undo_switch_stack
  415. br $31, ret_from_sys_call
  416. .align 3
  417. $strace_error:
  418. ldq $19, 0($sp) /* old syscall nr (zero if success) */
  419. beq $19, $strace_success
  420. ldq $20, 72($sp) /* .. and this a3 */
  421. subq $31, $0, $0 /* with error in v0 */
  422. addq $31, 1, $1 /* set a3 for errno return */
  423. stq $0, 0($sp)
  424. stq $1, 72($sp) /* a3 for return */
  425. bsr $1, do_switch_stack
  426. mov $19, $9 /* save old syscall number */
  427. mov $20, $10 /* save old a3 */
  428. jsr $26, syscall_trace
  429. mov $9, $19
  430. mov $10, $20
  431. bsr $1, undo_switch_stack
  432. mov $31, $26 /* tell "ret_from_sys_call" we can restart */
  433. br ret_from_sys_call
  434. .end strace
  435. /*
  436. * Save and restore the switch stack -- aka the balance of the user context.
  437. */
  438. .align 4
  439. .ent do_switch_stack
  440. do_switch_stack:
  441. lda $sp, -SWITCH_STACK_SIZE($sp)
  442. stq $9, 0($sp)
  443. stq $10, 8($sp)
  444. stq $11, 16($sp)
  445. stq $12, 24($sp)
  446. stq $13, 32($sp)
  447. stq $14, 40($sp)
  448. stq $15, 48($sp)
  449. stq $26, 56($sp)
  450. stt $f0, 64($sp)
  451. stt $f1, 72($sp)
  452. stt $f2, 80($sp)
  453. stt $f3, 88($sp)
  454. stt $f4, 96($sp)
  455. stt $f5, 104($sp)
  456. stt $f6, 112($sp)
  457. stt $f7, 120($sp)
  458. stt $f8, 128($sp)
  459. stt $f9, 136($sp)
  460. stt $f10, 144($sp)
  461. stt $f11, 152($sp)
  462. stt $f12, 160($sp)
  463. stt $f13, 168($sp)
  464. stt $f14, 176($sp)
  465. stt $f15, 184($sp)
  466. stt $f16, 192($sp)
  467. stt $f17, 200($sp)
  468. stt $f18, 208($sp)
  469. stt $f19, 216($sp)
  470. stt $f20, 224($sp)
  471. stt $f21, 232($sp)
  472. stt $f22, 240($sp)
  473. stt $f23, 248($sp)
  474. stt $f24, 256($sp)
  475. stt $f25, 264($sp)
  476. stt $f26, 272($sp)
  477. stt $f27, 280($sp)
  478. mf_fpcr $f0 # get fpcr
  479. stt $f28, 288($sp)
  480. stt $f29, 296($sp)
  481. stt $f30, 304($sp)
  482. stt $f0, 312($sp) # save fpcr in slot of $f31
  483. ldt $f0, 64($sp) # dont let "do_switch_stack" change fp state.
  484. ret $31, ($1), 1
  485. .end do_switch_stack
  486. .align 4
  487. .ent undo_switch_stack
  488. undo_switch_stack:
  489. ldq $9, 0($sp)
  490. ldq $10, 8($sp)
  491. ldq $11, 16($sp)
  492. ldq $12, 24($sp)
  493. ldq $13, 32($sp)
  494. ldq $14, 40($sp)
  495. ldq $15, 48($sp)
  496. ldq $26, 56($sp)
  497. ldt $f30, 312($sp) # get saved fpcr
  498. ldt $f0, 64($sp)
  499. ldt $f1, 72($sp)
  500. ldt $f2, 80($sp)
  501. ldt $f3, 88($sp)
  502. mt_fpcr $f30 # install saved fpcr
  503. ldt $f4, 96($sp)
  504. ldt $f5, 104($sp)
  505. ldt $f6, 112($sp)
  506. ldt $f7, 120($sp)
  507. ldt $f8, 128($sp)
  508. ldt $f9, 136($sp)
  509. ldt $f10, 144($sp)
  510. ldt $f11, 152($sp)
  511. ldt $f12, 160($sp)
  512. ldt $f13, 168($sp)
  513. ldt $f14, 176($sp)
  514. ldt $f15, 184($sp)
  515. ldt $f16, 192($sp)
  516. ldt $f17, 200($sp)
  517. ldt $f18, 208($sp)
  518. ldt $f19, 216($sp)
  519. ldt $f20, 224($sp)
  520. ldt $f21, 232($sp)
  521. ldt $f22, 240($sp)
  522. ldt $f23, 248($sp)
  523. ldt $f24, 256($sp)
  524. ldt $f25, 264($sp)
  525. ldt $f26, 272($sp)
  526. ldt $f27, 280($sp)
  527. ldt $f28, 288($sp)
  528. ldt $f29, 296($sp)
  529. ldt $f30, 304($sp)
  530. lda $sp, SWITCH_STACK_SIZE($sp)
  531. ret $31, ($1), 1
  532. .end undo_switch_stack
  533. /*
  534. * The meat of the context switch code.
  535. */
  536. .align 4
  537. .globl alpha_switch_to
  538. .ent alpha_switch_to
  539. alpha_switch_to:
  540. .prologue 0
  541. bsr $1, do_switch_stack
  542. call_pal PAL_swpctx
  543. lda $8, 0x3fff
  544. bsr $1, undo_switch_stack
  545. bic $sp, $8, $8
  546. mov $17, $0
  547. ret
  548. .end alpha_switch_to
  549. /*
  550. * New processes begin life here.
  551. */
  552. .globl ret_from_fork
  553. .align 4
  554. .ent ret_from_fork
  555. ret_from_fork:
  556. lda $26, ret_from_sys_call
  557. mov $17, $16
  558. jmp $31, schedule_tail
  559. .end ret_from_fork
  560. /*
  561. * kernel_thread(fn, arg, clone_flags)
  562. */
  563. .align 4
  564. .globl kernel_thread
  565. .ent kernel_thread
  566. kernel_thread:
  567. /* We can be called from a module. */
  568. ldgp $gp, 0($27)
  569. .prologue 1
  570. subq $sp, SP_OFF+6*8, $sp
  571. br $1, 2f /* load start address */
  572. /* We've now "returned" from a fake system call. */
  573. unop
  574. blt $0, 1f /* error? */
  575. ldi $1, 0x3fff
  576. beq $20, 1f /* parent or child? */
  577. bic $sp, $1, $8 /* in child. */
  578. jsr $26, ($27)
  579. ldgp $gp, 0($26)
  580. mov $0, $16
  581. mov $31, $26
  582. jmp $31, sys_exit
  583. 1: ret /* in parent. */
  584. .align 4
  585. 2: /* Fake a system call stack frame, as we can't do system calls
  586. from kernel space. Note that we store FN and ARG as they
  587. need to be set up in the child for the call. Also store $8
  588. and $26 for use in the parent. */
  589. stq $31, SP_OFF($sp) /* ps */
  590. stq $1, SP_OFF+8($sp) /* pc */
  591. stq $gp, SP_OFF+16($sp) /* gp */
  592. stq $16, 136($sp) /* $27; FN for child */
  593. stq $17, SP_OFF+24($sp) /* $16; ARG for child */
  594. stq $8, 64($sp) /* $8 */
  595. stq $26, 128($sp) /* $26 */
  596. /* Avoid the HAE being gratuitously wrong, to avoid restoring it. */
  597. ldq $2, alpha_mv+HAE_CACHE
  598. stq $2, 152($sp) /* HAE */
  599. /* Shuffle FLAGS to the front; add CLONE_VM. */
  600. ldi $1, CLONE_VM|CLONE_UNTRACED
  601. or $18, $1, $16
  602. bsr $26, sys_clone
  603. /* We don't actually care for a3 success widgetry in the kernel.
  604. Not for positive errno values. */
  605. stq $0, 0($sp) /* $0 */
  606. br restore_all
  607. .end kernel_thread
  608. /*
  609. * execve(path, argv, envp)
  610. */
  611. .align 4
  612. .globl execve
  613. .ent execve
  614. execve:
  615. /* We can be called from a module. */
  616. ldgp $gp, 0($27)
  617. lda $sp, -(32+SIZEOF_PT_REGS+8)($sp)
  618. .frame $sp, 32+SIZEOF_PT_REGS+8, $26, 0
  619. stq $26, 0($sp)
  620. stq $16, 8($sp)
  621. stq $17, 16($sp)
  622. stq $18, 24($sp)
  623. .prologue 1
  624. lda $16, 32($sp)
  625. lda $17, 0
  626. lda $18, SIZEOF_PT_REGS
  627. bsr $26, memset !samegp
  628. /* Avoid the HAE being gratuitously wrong, which would cause us
  629. to do the whole turn off interrupts thing and restore it. */
  630. ldq $2, alpha_mv+HAE_CACHE
  631. stq $2, 152+32($sp)
  632. ldq $16, 8($sp)
  633. ldq $17, 16($sp)
  634. ldq $18, 24($sp)
  635. lda $19, 32($sp)
  636. bsr $26, do_execve !samegp
  637. ldq $26, 0($sp)
  638. bne $0, 1f /* error! */
  639. /* Move the temporary pt_regs struct from its current location
  640. to the top of the kernel stack frame. See copy_thread for
  641. details for a normal process. */
  642. lda $16, 0x4000 - SIZEOF_PT_REGS($8)
  643. lda $17, 32($sp)
  644. lda $18, SIZEOF_PT_REGS
  645. bsr $26, memmove !samegp
  646. /* Take that over as our new stack frame and visit userland! */
  647. lda $sp, 0x4000 - SIZEOF_PT_REGS($8)
  648. br $31, ret_from_sys_call
  649. 1: lda $sp, 32+SIZEOF_PT_REGS+8($sp)
  650. ret
  651. .end execve
  652. /*
  653. * Special system calls. Most of these are special in that they either
  654. * have to play switch_stack games or in some way use the pt_regs struct.
  655. */
  656. .align 4
  657. .globl sys_fork
  658. .ent sys_fork
  659. sys_fork:
  660. .prologue 0
  661. mov $sp, $21
  662. bsr $1, do_switch_stack
  663. bis $31, SIGCHLD, $16
  664. mov $31, $17
  665. mov $31, $18
  666. mov $31, $19
  667. mov $31, $20
  668. jsr $26, alpha_clone
  669. bsr $1, undo_switch_stack
  670. ret
  671. .end sys_fork
  672. .align 4
  673. .globl sys_clone
  674. .ent sys_clone
  675. sys_clone:
  676. .prologue 0
  677. mov $sp, $21
  678. bsr $1, do_switch_stack
  679. /* $16, $17, $18, $19, $20 come from the user. */
  680. jsr $26, alpha_clone
  681. bsr $1, undo_switch_stack
  682. ret
  683. .end sys_clone
  684. .align 4
  685. .globl sys_vfork
  686. .ent sys_vfork
  687. sys_vfork:
  688. .prologue 0
  689. mov $sp, $16
  690. bsr $1, do_switch_stack
  691. jsr $26, alpha_vfork
  692. bsr $1, undo_switch_stack
  693. ret
  694. .end sys_vfork
  695. .align 4
  696. .globl sys_sigreturn
  697. .ent sys_sigreturn
  698. sys_sigreturn:
  699. .prologue 0
  700. mov $sp, $17
  701. lda $18, -SWITCH_STACK_SIZE($sp)
  702. lda $sp, -SWITCH_STACK_SIZE($sp)
  703. jsr $26, do_sigreturn
  704. br $1, undo_switch_stack
  705. br ret_from_sys_call
  706. .end sys_sigreturn
  707. .align 4
  708. .globl sys_rt_sigreturn
  709. .ent sys_rt_sigreturn
  710. sys_rt_sigreturn:
  711. .prologue 0
  712. mov $sp, $17
  713. lda $18, -SWITCH_STACK_SIZE($sp)
  714. lda $sp, -SWITCH_STACK_SIZE($sp)
  715. jsr $26, do_rt_sigreturn
  716. br $1, undo_switch_stack
  717. br ret_from_sys_call
  718. .end sys_rt_sigreturn
  719. .align 4
  720. .globl sys_sigsuspend
  721. .ent sys_sigsuspend
  722. sys_sigsuspend:
  723. .prologue 0
  724. mov $sp, $17
  725. br $1, do_switch_stack
  726. mov $sp, $18
  727. subq $sp, 16, $sp
  728. stq $26, 0($sp)
  729. jsr $26, do_sigsuspend
  730. ldq $26, 0($sp)
  731. lda $sp, SWITCH_STACK_SIZE+16($sp)
  732. ret
  733. .end sys_sigsuspend
  734. .align 4
  735. .globl sys_rt_sigsuspend
  736. .ent sys_rt_sigsuspend
  737. sys_rt_sigsuspend:
  738. .prologue 0
  739. mov $sp, $18
  740. br $1, do_switch_stack
  741. mov $sp, $19
  742. subq $sp, 16, $sp
  743. stq $26, 0($sp)
  744. jsr $26, do_rt_sigsuspend
  745. ldq $26, 0($sp)
  746. lda $sp, SWITCH_STACK_SIZE+16($sp)
  747. ret
  748. .end sys_rt_sigsuspend
  749. .align 4
  750. .globl sys_sethae
  751. .ent sys_sethae
  752. sys_sethae:
  753. .prologue 0
  754. stq $16, 152($sp)
  755. ret
  756. .end sys_sethae
  757. .align 4
  758. .globl osf_getpriority
  759. .ent osf_getpriority
  760. osf_getpriority:
  761. lda $sp, -16($sp)
  762. stq $26, 0($sp)
  763. .prologue 0
  764. jsr $26, sys_getpriority
  765. ldq $26, 0($sp)
  766. blt $0, 1f
  767. /* Return value is the unbiased priority, i.e. 20 - prio.
  768. This does result in negative return values, so signal
  769. no error by writing into the R0 slot. */
  770. lda $1, 20
  771. stq $31, 16($sp)
  772. subl $1, $0, $0
  773. unop
  774. 1: lda $sp, 16($sp)
  775. ret
  776. .end osf_getpriority
  777. .align 4
  778. .globl sys_getxuid
  779. .ent sys_getxuid
  780. sys_getxuid:
  781. .prologue 0
  782. ldq $2, TI_TASK($8)
  783. ldl $0, TASK_UID($2)
  784. ldl $1, TASK_EUID($2)
  785. stq $1, 80($sp)
  786. ret
  787. .end sys_getxuid
  788. .align 4
  789. .globl sys_getxgid
  790. .ent sys_getxgid
  791. sys_getxgid:
  792. .prologue 0
  793. ldq $2, TI_TASK($8)
  794. ldl $0, TASK_GID($2)
  795. ldl $1, TASK_EGID($2)
  796. stq $1, 80($sp)
  797. ret
  798. .end sys_getxgid
  799. .align 4
  800. .globl sys_getxpid
  801. .ent sys_getxpid
  802. sys_getxpid:
  803. .prologue 0
  804. ldq $2, TI_TASK($8)
  805. /* See linux/kernel/timer.c sys_getppid for discussion
  806. about this loop. */
  807. ldq $3, TASK_REAL_PARENT($2)
  808. 1: ldl $1, TASK_TGID($3)
  809. #ifdef CONFIG_SMP
  810. mov $3, $4
  811. mb
  812. ldq $3, TASK_REAL_PARENT($2)
  813. cmpeq $3, $4, $4
  814. beq $4, 1b
  815. #endif
  816. stq $1, 80($sp)
  817. ldl $0, TASK_TGID($2)
  818. ret
  819. .end sys_getxpid
  820. .align 4
  821. .globl sys_pipe
  822. .ent sys_pipe
  823. sys_pipe:
  824. lda $sp, -16($sp)
  825. stq $26, 0($sp)
  826. .prologue 0
  827. lda $16, 8($sp)
  828. jsr $26, do_pipe
  829. ldq $26, 0($sp)
  830. bne $0, 1f
  831. /* The return values are in $0 and $20. */
  832. ldl $1, 12($sp)
  833. ldl $0, 8($sp)
  834. stq $1, 80+16($sp)
  835. 1: lda $sp, 16($sp)
  836. ret
  837. .end sys_pipe
  838. .align 4
  839. .globl sys_ptrace
  840. .ent sys_ptrace
  841. sys_ptrace:
  842. .prologue 0
  843. mov $sp, $20
  844. jmp $31, do_sys_ptrace
  845. .end sys_ptrace
  846. .align 4
  847. .globl sys_execve
  848. .ent sys_execve
  849. sys_execve:
  850. .prologue 0
  851. mov $sp, $19
  852. jmp $31, do_sys_execve
  853. .end sys_execve
  854. .align 4
  855. .globl osf_sigprocmask
  856. .ent osf_sigprocmask
  857. osf_sigprocmask:
  858. .prologue 0
  859. mov $sp, $18
  860. jmp $31, do_osf_sigprocmask
  861. .end osf_sigprocmask
  862. .align 4
  863. .globl alpha_ni_syscall
  864. .ent alpha_ni_syscall
  865. alpha_ni_syscall:
  866. .prologue 0
  867. /* Special because it also implements overflow handling via
  868. syscall number 0. And if you recall, zero is a special
  869. trigger for "not an error". Store large non-zero there. */
  870. lda $0, -ENOSYS
  871. unop
  872. stq $0, 0($sp)
  873. ret
  874. .end alpha_ni_syscall