entry.S 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952
  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_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, $16
  371. br $1, do_switch_stack
  372. mov $sp, $17
  373. mov $5, $18
  374. jsr $26, do_notify_resume
  375. bsr $1, undo_switch_stack
  376. br restore_all
  377. .end work_pending
  378. /*
  379. * PTRACE syscall handler
  380. */
  381. .align 4
  382. .ent strace
  383. strace:
  384. /* set up signal stack, call syscall_trace */
  385. bsr $1, do_switch_stack
  386. jsr $26, syscall_trace
  387. bsr $1, undo_switch_stack
  388. /* get the system call number and the arguments back.. */
  389. ldq $0, 0($sp)
  390. ldq $16, SP_OFF+24($sp)
  391. ldq $17, SP_OFF+32($sp)
  392. ldq $18, SP_OFF+40($sp)
  393. ldq $19, 72($sp)
  394. ldq $20, 80($sp)
  395. ldq $21, 88($sp)
  396. /* get the system call pointer.. */
  397. lda $1, NR_SYSCALLS($31)
  398. lda $2, sys_call_table
  399. lda $27, alpha_ni_syscall
  400. cmpult $0, $1, $1
  401. s8addq $0, $2, $2
  402. beq $1, 1f
  403. ldq $27, 0($2)
  404. 1: jsr $26, ($27), sys_gettimeofday
  405. ldgp $gp, 0($26)
  406. /* check return.. */
  407. blt $0, $strace_error /* the call failed */
  408. stq $31, 72($sp) /* a3=0 => no error */
  409. $strace_success:
  410. stq $0, 0($sp) /* save return value */
  411. bsr $1, do_switch_stack
  412. jsr $26, syscall_trace
  413. bsr $1, undo_switch_stack
  414. br $31, ret_from_sys_call
  415. .align 3
  416. $strace_error:
  417. ldq $19, 0($sp) /* old syscall nr (zero if success) */
  418. beq $19, $strace_success
  419. ldq $20, 72($sp) /* .. and this a3 */
  420. subq $31, $0, $0 /* with error in v0 */
  421. addq $31, 1, $1 /* set a3 for errno return */
  422. stq $0, 0($sp)
  423. stq $1, 72($sp) /* a3 for return */
  424. bsr $1, do_switch_stack
  425. mov $19, $9 /* save old syscall number */
  426. mov $20, $10 /* save old a3 */
  427. jsr $26, syscall_trace
  428. mov $9, $19
  429. mov $10, $20
  430. bsr $1, undo_switch_stack
  431. mov $31, $26 /* tell "ret_from_sys_call" we can restart */
  432. br ret_from_sys_call
  433. .end strace
  434. /*
  435. * Save and restore the switch stack -- aka the balance of the user context.
  436. */
  437. .align 4
  438. .ent do_switch_stack
  439. do_switch_stack:
  440. lda $sp, -SWITCH_STACK_SIZE($sp)
  441. stq $9, 0($sp)
  442. stq $10, 8($sp)
  443. stq $11, 16($sp)
  444. stq $12, 24($sp)
  445. stq $13, 32($sp)
  446. stq $14, 40($sp)
  447. stq $15, 48($sp)
  448. stq $26, 56($sp)
  449. stt $f0, 64($sp)
  450. stt $f1, 72($sp)
  451. stt $f2, 80($sp)
  452. stt $f3, 88($sp)
  453. stt $f4, 96($sp)
  454. stt $f5, 104($sp)
  455. stt $f6, 112($sp)
  456. stt $f7, 120($sp)
  457. stt $f8, 128($sp)
  458. stt $f9, 136($sp)
  459. stt $f10, 144($sp)
  460. stt $f11, 152($sp)
  461. stt $f12, 160($sp)
  462. stt $f13, 168($sp)
  463. stt $f14, 176($sp)
  464. stt $f15, 184($sp)
  465. stt $f16, 192($sp)
  466. stt $f17, 200($sp)
  467. stt $f18, 208($sp)
  468. stt $f19, 216($sp)
  469. stt $f20, 224($sp)
  470. stt $f21, 232($sp)
  471. stt $f22, 240($sp)
  472. stt $f23, 248($sp)
  473. stt $f24, 256($sp)
  474. stt $f25, 264($sp)
  475. stt $f26, 272($sp)
  476. stt $f27, 280($sp)
  477. mf_fpcr $f0 # get fpcr
  478. stt $f28, 288($sp)
  479. stt $f29, 296($sp)
  480. stt $f30, 304($sp)
  481. stt $f0, 312($sp) # save fpcr in slot of $f31
  482. ldt $f0, 64($sp) # dont let "do_switch_stack" change fp state.
  483. ret $31, ($1), 1
  484. .end do_switch_stack
  485. .align 4
  486. .ent undo_switch_stack
  487. undo_switch_stack:
  488. ldq $9, 0($sp)
  489. ldq $10, 8($sp)
  490. ldq $11, 16($sp)
  491. ldq $12, 24($sp)
  492. ldq $13, 32($sp)
  493. ldq $14, 40($sp)
  494. ldq $15, 48($sp)
  495. ldq $26, 56($sp)
  496. ldt $f30, 312($sp) # get saved fpcr
  497. ldt $f0, 64($sp)
  498. ldt $f1, 72($sp)
  499. ldt $f2, 80($sp)
  500. ldt $f3, 88($sp)
  501. mt_fpcr $f30 # install saved fpcr
  502. ldt $f4, 96($sp)
  503. ldt $f5, 104($sp)
  504. ldt $f6, 112($sp)
  505. ldt $f7, 120($sp)
  506. ldt $f8, 128($sp)
  507. ldt $f9, 136($sp)
  508. ldt $f10, 144($sp)
  509. ldt $f11, 152($sp)
  510. ldt $f12, 160($sp)
  511. ldt $f13, 168($sp)
  512. ldt $f14, 176($sp)
  513. ldt $f15, 184($sp)
  514. ldt $f16, 192($sp)
  515. ldt $f17, 200($sp)
  516. ldt $f18, 208($sp)
  517. ldt $f19, 216($sp)
  518. ldt $f20, 224($sp)
  519. ldt $f21, 232($sp)
  520. ldt $f22, 240($sp)
  521. ldt $f23, 248($sp)
  522. ldt $f24, 256($sp)
  523. ldt $f25, 264($sp)
  524. ldt $f26, 272($sp)
  525. ldt $f27, 280($sp)
  526. ldt $f28, 288($sp)
  527. ldt $f29, 296($sp)
  528. ldt $f30, 304($sp)
  529. lda $sp, SWITCH_STACK_SIZE($sp)
  530. ret $31, ($1), 1
  531. .end undo_switch_stack
  532. /*
  533. * The meat of the context switch code.
  534. */
  535. .align 4
  536. .globl alpha_switch_to
  537. .ent alpha_switch_to
  538. alpha_switch_to:
  539. .prologue 0
  540. bsr $1, do_switch_stack
  541. call_pal PAL_swpctx
  542. lda $8, 0x3fff
  543. bsr $1, undo_switch_stack
  544. bic $sp, $8, $8
  545. mov $17, $0
  546. ret
  547. .end alpha_switch_to
  548. /*
  549. * New processes begin life here.
  550. */
  551. .globl ret_from_fork
  552. .align 4
  553. .ent ret_from_fork
  554. ret_from_fork:
  555. lda $26, ret_from_sys_call
  556. mov $17, $16
  557. jmp $31, schedule_tail
  558. .end ret_from_fork
  559. /*
  560. * kernel_thread(fn, arg, clone_flags)
  561. */
  562. .align 4
  563. .globl kernel_thread
  564. .ent kernel_thread
  565. kernel_thread:
  566. /* We can be called from a module. */
  567. ldgp $gp, 0($27)
  568. .prologue 1
  569. subq $sp, SP_OFF+6*8, $sp
  570. br $1, 2f /* load start address */
  571. /* We've now "returned" from a fake system call. */
  572. unop
  573. blt $0, 1f /* error? */
  574. ldi $1, 0x3fff
  575. beq $20, 1f /* parent or child? */
  576. bic $sp, $1, $8 /* in child. */
  577. jsr $26, ($27)
  578. ldgp $gp, 0($26)
  579. mov $0, $16
  580. mov $31, $26
  581. jmp $31, sys_exit
  582. 1: ret /* in parent. */
  583. .align 4
  584. 2: /* Fake a system call stack frame, as we can't do system calls
  585. from kernel space. Note that we store FN and ARG as they
  586. need to be set up in the child for the call. Also store $8
  587. and $26 for use in the parent. */
  588. stq $31, SP_OFF($sp) /* ps */
  589. stq $1, SP_OFF+8($sp) /* pc */
  590. stq $gp, SP_OFF+16($sp) /* gp */
  591. stq $16, 136($sp) /* $27; FN for child */
  592. stq $17, SP_OFF+24($sp) /* $16; ARG for child */
  593. stq $8, 64($sp) /* $8 */
  594. stq $26, 128($sp) /* $26 */
  595. /* Avoid the HAE being gratuitously wrong, to avoid restoring it. */
  596. ldq $2, alpha_mv+HAE_CACHE
  597. stq $2, 152($sp) /* HAE */
  598. /* Shuffle FLAGS to the front; add CLONE_VM. */
  599. ldi $1, CLONE_VM|CLONE_UNTRACED
  600. or $18, $1, $16
  601. bsr $26, sys_clone
  602. /* We don't actually care for a3 success widgetry in the kernel.
  603. Not for positive errno values. */
  604. stq $0, 0($sp) /* $0 */
  605. br restore_all
  606. .end kernel_thread
  607. /*
  608. * kernel_execve(path, argv, envp)
  609. */
  610. .align 4
  611. .globl kernel_execve
  612. .ent kernel_execve
  613. kernel_execve:
  614. /* We can be called from a module. */
  615. ldgp $gp, 0($27)
  616. lda $sp, -(32+SIZEOF_PT_REGS+8)($sp)
  617. .frame $sp, 32+SIZEOF_PT_REGS+8, $26, 0
  618. stq $26, 0($sp)
  619. stq $16, 8($sp)
  620. stq $17, 16($sp)
  621. stq $18, 24($sp)
  622. .prologue 1
  623. lda $16, 32($sp)
  624. lda $17, 0
  625. lda $18, SIZEOF_PT_REGS
  626. bsr $26, memset !samegp
  627. /* Avoid the HAE being gratuitously wrong, which would cause us
  628. to do the whole turn off interrupts thing and restore it. */
  629. ldq $2, alpha_mv+HAE_CACHE
  630. stq $2, 152+32($sp)
  631. ldq $16, 8($sp)
  632. ldq $17, 16($sp)
  633. ldq $18, 24($sp)
  634. lda $19, 32($sp)
  635. bsr $26, do_execve !samegp
  636. ldq $26, 0($sp)
  637. bne $0, 1f /* error! */
  638. /* Move the temporary pt_regs struct from its current location
  639. to the top of the kernel stack frame. See copy_thread for
  640. details for a normal process. */
  641. lda $16, 0x4000 - SIZEOF_PT_REGS($8)
  642. lda $17, 32($sp)
  643. lda $18, SIZEOF_PT_REGS
  644. bsr $26, memmove !samegp
  645. /* Take that over as our new stack frame and visit userland! */
  646. lda $sp, 0x4000 - SIZEOF_PT_REGS($8)
  647. br $31, ret_from_sys_call
  648. 1: lda $sp, 32+SIZEOF_PT_REGS+8($sp)
  649. ret
  650. .end kernel_execve
  651. /*
  652. * Special system calls. Most of these are special in that they either
  653. * have to play switch_stack games or in some way use the pt_regs struct.
  654. */
  655. .align 4
  656. .globl sys_fork
  657. .ent sys_fork
  658. sys_fork:
  659. .prologue 0
  660. mov $sp, $21
  661. bsr $1, do_switch_stack
  662. bis $31, SIGCHLD, $16
  663. mov $31, $17
  664. mov $31, $18
  665. mov $31, $19
  666. mov $31, $20
  667. jsr $26, alpha_clone
  668. bsr $1, undo_switch_stack
  669. ret
  670. .end sys_fork
  671. .align 4
  672. .globl sys_clone
  673. .ent sys_clone
  674. sys_clone:
  675. .prologue 0
  676. mov $sp, $21
  677. bsr $1, do_switch_stack
  678. /* $16, $17, $18, $19, $20 come from the user. */
  679. jsr $26, alpha_clone
  680. bsr $1, undo_switch_stack
  681. ret
  682. .end sys_clone
  683. .align 4
  684. .globl sys_vfork
  685. .ent sys_vfork
  686. sys_vfork:
  687. .prologue 0
  688. mov $sp, $16
  689. bsr $1, do_switch_stack
  690. jsr $26, alpha_vfork
  691. bsr $1, undo_switch_stack
  692. ret
  693. .end sys_vfork
  694. .align 4
  695. .globl sys_sigreturn
  696. .ent sys_sigreturn
  697. sys_sigreturn:
  698. .prologue 0
  699. mov $sp, $17
  700. lda $18, -SWITCH_STACK_SIZE($sp)
  701. lda $sp, -SWITCH_STACK_SIZE($sp)
  702. jsr $26, do_sigreturn
  703. br $1, undo_switch_stack
  704. br ret_from_sys_call
  705. .end sys_sigreturn
  706. .align 4
  707. .globl sys_rt_sigreturn
  708. .ent sys_rt_sigreturn
  709. sys_rt_sigreturn:
  710. .prologue 0
  711. mov $sp, $17
  712. lda $18, -SWITCH_STACK_SIZE($sp)
  713. lda $sp, -SWITCH_STACK_SIZE($sp)
  714. jsr $26, do_rt_sigreturn
  715. br $1, undo_switch_stack
  716. br ret_from_sys_call
  717. .end sys_rt_sigreturn
  718. .align 4
  719. .globl sys_sigsuspend
  720. .ent sys_sigsuspend
  721. sys_sigsuspend:
  722. .prologue 0
  723. mov $sp, $17
  724. br $1, do_switch_stack
  725. mov $sp, $18
  726. subq $sp, 16, $sp
  727. stq $26, 0($sp)
  728. jsr $26, do_sigsuspend
  729. ldq $26, 0($sp)
  730. lda $sp, SWITCH_STACK_SIZE+16($sp)
  731. ret
  732. .end sys_sigsuspend
  733. .align 4
  734. .globl sys_rt_sigsuspend
  735. .ent sys_rt_sigsuspend
  736. sys_rt_sigsuspend:
  737. .prologue 0
  738. mov $sp, $18
  739. br $1, do_switch_stack
  740. mov $sp, $19
  741. subq $sp, 16, $sp
  742. stq $26, 0($sp)
  743. jsr $26, do_rt_sigsuspend
  744. ldq $26, 0($sp)
  745. lda $sp, SWITCH_STACK_SIZE+16($sp)
  746. ret
  747. .end sys_rt_sigsuspend
  748. .align 4
  749. .globl sys_sethae
  750. .ent sys_sethae
  751. sys_sethae:
  752. .prologue 0
  753. stq $16, 152($sp)
  754. ret
  755. .end sys_sethae
  756. .align 4
  757. .globl osf_getpriority
  758. .ent osf_getpriority
  759. osf_getpriority:
  760. lda $sp, -16($sp)
  761. stq $26, 0($sp)
  762. .prologue 0
  763. jsr $26, sys_getpriority
  764. ldq $26, 0($sp)
  765. blt $0, 1f
  766. /* Return value is the unbiased priority, i.e. 20 - prio.
  767. This does result in negative return values, so signal
  768. no error by writing into the R0 slot. */
  769. lda $1, 20
  770. stq $31, 16($sp)
  771. subl $1, $0, $0
  772. unop
  773. 1: lda $sp, 16($sp)
  774. ret
  775. .end osf_getpriority
  776. .align 4
  777. .globl sys_getxuid
  778. .ent sys_getxuid
  779. sys_getxuid:
  780. .prologue 0
  781. ldq $2, TI_TASK($8)
  782. ldq $3, TASK_CRED($2)
  783. ldl $0, CRED_UID($3)
  784. ldl $1, CRED_EUID($3)
  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. ldq $3, TASK_CRED($2)
  795. ldl $0, CRED_GID($3)
  796. ldl $1, CRED_EGID($3)
  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_alpha_pipe
  825. .ent sys_alpha_pipe
  826. sys_alpha_pipe:
  827. lda $sp, -16($sp)
  828. stq $26, 0($sp)
  829. .prologue 0
  830. mov $31, $17
  831. lda $16, 8($sp)
  832. jsr $26, do_pipe_flags
  833. ldq $26, 0($sp)
  834. bne $0, 1f
  835. /* The return values are in $0 and $20. */
  836. ldl $1, 12($sp)
  837. ldl $0, 8($sp)
  838. stq $1, 80+16($sp)
  839. 1: lda $sp, 16($sp)
  840. ret
  841. .end sys_alpha_pipe
  842. .align 4
  843. .globl sys_execve
  844. .ent sys_execve
  845. sys_execve:
  846. .prologue 0
  847. mov $sp, $19
  848. jmp $31, do_sys_execve
  849. .end sys_execve
  850. .align 4
  851. .globl osf_sigprocmask
  852. .ent osf_sigprocmask
  853. osf_sigprocmask:
  854. .prologue 0
  855. mov $sp, $18
  856. jmp $31, sys_osf_sigprocmask
  857. .end osf_sigprocmask
  858. .align 4
  859. .globl alpha_ni_syscall
  860. .ent alpha_ni_syscall
  861. alpha_ni_syscall:
  862. .prologue 0
  863. /* Special because it also implements overflow handling via
  864. syscall number 0. And if you recall, zero is a special
  865. trigger for "not an error". Store large non-zero there. */
  866. lda $0, -ENOSYS
  867. unop
  868. stq $0, 0($sp)
  869. ret
  870. .end alpha_ni_syscall