entry.S 19 KB

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