entry.S 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137
  1. /* $Id: entry.S,v 1.37 2004/06/11 13:02:46 doyu Exp $
  2. *
  3. * linux/arch/sh/entry.S
  4. *
  5. * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
  6. * Copyright (C) 2003 Paul Mundt
  7. *
  8. * This file is subject to the terms and conditions of the GNU General Public
  9. * License. See the file "COPYING" in the main directory of this archive
  10. * for more details.
  11. *
  12. */
  13. #include <linux/sys.h>
  14. #include <linux/linkage.h>
  15. #include <asm/asm-offsets.h>
  16. #include <asm/thread_info.h>
  17. #include <asm/cpu/mmu_context.h>
  18. #include <asm/unistd.h>
  19. #if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE)
  20. #define sys_nfsservctl sys_ni_syscall
  21. #endif
  22. #if !defined(CONFIG_MMU)
  23. #define sys_madvise sys_ni_syscall
  24. #define sys_readahead sys_ni_syscall
  25. #define sys_mprotect sys_ni_syscall
  26. #define sys_msync sys_ni_syscall
  27. #define sys_mlock sys_ni_syscall
  28. #define sys_munlock sys_ni_syscall
  29. #define sys_mlockall sys_ni_syscall
  30. #define sys_munlockall sys_ni_syscall
  31. #define sys_mremap sys_ni_syscall
  32. #define sys_mincore sys_ni_syscall
  33. #define sys_remap_file_pages sys_ni_syscall
  34. #endif
  35. ! NOTE:
  36. ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
  37. ! to be jumped is too far, but it causes illegal slot exception.
  38. /*
  39. * entry.S contains the system-call and fault low-level handling routines.
  40. * This also contains the timer-interrupt handler, as well as all interrupts
  41. * and faults that can result in a task-switch.
  42. *
  43. * NOTE: This code handles signal-recognition, which happens every time
  44. * after a timer-interrupt and after each system call.
  45. *
  46. * NOTE: This code uses a convention that instructions in the delay slot
  47. * of a transfer-control instruction are indented by an extra space, thus:
  48. *
  49. * jmp @k0 ! control-transfer instruction
  50. * ldc k1, ssr ! delay slot
  51. *
  52. * Stack layout in 'ret_from_syscall':
  53. * ptrace needs to have all regs on the stack.
  54. * if the order here is changed, it needs to be
  55. * updated in ptrace.c and ptrace.h
  56. *
  57. * r0
  58. * ...
  59. * r15 = stack pointer
  60. * spc
  61. * pr
  62. * ssr
  63. * gbr
  64. * mach
  65. * macl
  66. * syscall #
  67. *
  68. */
  69. ENOSYS = 38
  70. EINVAL = 22
  71. #if defined(CONFIG_KGDB_NMI)
  72. NMI_VEC = 0x1c0 ! Must catch early for debounce
  73. #endif
  74. /* Offsets to the stack */
  75. OFF_R0 = 0 /* Return value. New ABI also arg4 */
  76. OFF_R1 = 4 /* New ABI: arg5 */
  77. OFF_R2 = 8 /* New ABI: arg6 */
  78. OFF_R3 = 12 /* New ABI: syscall_nr */
  79. OFF_R4 = 16 /* New ABI: arg0 */
  80. OFF_R5 = 20 /* New ABI: arg1 */
  81. OFF_R6 = 24 /* New ABI: arg2 */
  82. OFF_R7 = 28 /* New ABI: arg3 */
  83. OFF_SP = (15*4)
  84. OFF_PC = (16*4)
  85. OFF_SR = (16*4+8)
  86. OFF_TRA = (16*4+6*4)
  87. #define k0 r0
  88. #define k1 r1
  89. #define k2 r2
  90. #define k3 r3
  91. #define k4 r4
  92. #define k_ex_code r2_bank /* r2_bank1 */
  93. #define g_imask r6 /* r6_bank1 */
  94. #define k_g_imask r6_bank /* r6_bank1 */
  95. #define current r7 /* r7_bank1 */
  96. /*
  97. * Kernel mode register usage:
  98. * k0 scratch
  99. * k1 scratch
  100. * k2 scratch (Exception code)
  101. * k3 scratch (Return address)
  102. * k4 scratch
  103. * k5 reserved
  104. * k6 Global Interrupt Mask (0--15 << 4)
  105. * k7 CURRENT_THREAD_INFO (pointer to current thread info)
  106. */
  107. !
  108. ! TLB Miss / Initial Page write exception handling
  109. ! _and_
  110. ! TLB hits, but the access violate the protection.
  111. ! It can be valid access, such as stack grow and/or C-O-W.
  112. !
  113. !
  114. ! Find the pmd/pte entry and loadtlb
  115. ! If it's not found, cause address error (SEGV)
  116. !
  117. ! Although this could be written in assembly language (and it'd be faster),
  118. ! this first version depends *much* on C implementation.
  119. !
  120. #define CLI() \
  121. stc sr, r0; \
  122. or #0xf0, r0; \
  123. ldc r0, sr
  124. #define STI() \
  125. mov.l __INV_IMASK, r11; \
  126. stc sr, r10; \
  127. and r11, r10; \
  128. stc k_g_imask, r11; \
  129. or r11, r10; \
  130. ldc r10, sr
  131. #if defined(CONFIG_PREEMPT)
  132. # define preempt_stop() CLI()
  133. #else
  134. # define preempt_stop()
  135. # define resume_kernel restore_all
  136. #endif
  137. #if defined(CONFIG_MMU)
  138. .align 2
  139. ENTRY(tlb_miss_load)
  140. bra call_dpf
  141. mov #0, r5
  142. .align 2
  143. ENTRY(tlb_miss_store)
  144. bra call_dpf
  145. mov #1, r5
  146. .align 2
  147. ENTRY(initial_page_write)
  148. bra call_dpf
  149. mov #1, r5
  150. .align 2
  151. ENTRY(tlb_protection_violation_load)
  152. bra call_dpf
  153. mov #0, r5
  154. .align 2
  155. ENTRY(tlb_protection_violation_store)
  156. bra call_dpf
  157. mov #1, r5
  158. call_dpf:
  159. mov.l 1f, r0
  160. mov r5, r8
  161. mov.l @r0, r6
  162. mov r6, r9
  163. mov.l 2f, r0
  164. sts pr, r10
  165. jsr @r0
  166. mov r15, r4
  167. !
  168. tst r0, r0
  169. bf/s 0f
  170. lds r10, pr
  171. rts
  172. nop
  173. 0: STI()
  174. mov.l 3f, r0
  175. mov r9, r6
  176. mov r8, r5
  177. jmp @r0
  178. mov r15, r4
  179. .align 2
  180. 1: .long MMU_TEA
  181. 2: .long __do_page_fault
  182. 3: .long do_page_fault
  183. .align 2
  184. ENTRY(address_error_load)
  185. bra call_dae
  186. mov #0,r5 ! writeaccess = 0
  187. .align 2
  188. ENTRY(address_error_store)
  189. bra call_dae
  190. mov #1,r5 ! writeaccess = 1
  191. .align 2
  192. call_dae:
  193. mov.l 1f, r0
  194. mov.l @r0, r6 ! address
  195. mov.l 2f, r0
  196. jmp @r0
  197. mov r15, r4 ! regs
  198. .align 2
  199. 1: .long MMU_TEA
  200. 2: .long do_address_error
  201. #endif /* CONFIG_MMU */
  202. #if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
  203. ! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present.
  204. ! If both are configured, handle the debug traps (breakpoints) in SW,
  205. ! but still allow BIOS traps to FW.
  206. .align 2
  207. debug_kernel:
  208. #if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB)
  209. /* Force BIOS call to FW (debug_trap put TRA in r8) */
  210. mov r8,r0
  211. shlr2 r0
  212. cmp/eq #0x3f,r0
  213. bt debug_kernel_fw
  214. #endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */
  215. debug_enter:
  216. #if defined(CONFIG_SH_KGDB)
  217. /* Jump to kgdb, pass stacked regs as arg */
  218. debug_kernel_sw:
  219. mov.l 3f, r0
  220. jmp @r0
  221. mov r15, r4
  222. .align 2
  223. 3: .long kgdb_handle_exception
  224. #endif /* CONFIG_SH_KGDB */
  225. #if defined(CONFIG_SH_STANDARD_BIOS)
  226. /* Unwind the stack and jmp to the debug entry */
  227. debug_kernel_fw:
  228. mov.l @r15+, r0
  229. mov.l @r15+, r1
  230. mov.l @r15+, r2
  231. mov.l @r15+, r3
  232. mov.l @r15+, r4
  233. mov.l @r15+, r5
  234. mov.l @r15+, r6
  235. mov.l @r15+, r7
  236. stc sr, r8
  237. mov.l 1f, r9 ! BL =1, RB=1, IMASK=0x0F
  238. or r9, r8
  239. ldc r8, sr ! here, change the register bank
  240. mov.l @r15+, r8
  241. mov.l @r15+, r9
  242. mov.l @r15+, r10
  243. mov.l @r15+, r11
  244. mov.l @r15+, r12
  245. mov.l @r15+, r13
  246. mov.l @r15+, r14
  247. mov.l @r15+, k0
  248. ldc.l @r15+, spc
  249. lds.l @r15+, pr
  250. mov.l @r15+, k1
  251. ldc.l @r15+, gbr
  252. lds.l @r15+, mach
  253. lds.l @r15+, macl
  254. mov k0, r15
  255. !
  256. mov.l 2f, k0
  257. mov.l @k0, k0
  258. jmp @k0
  259. ldc k1, ssr
  260. .align 2
  261. 1: .long 0x300000f0
  262. 2: .long gdb_vbr_vector
  263. #endif /* CONFIG_SH_STANDARD_BIOS */
  264. #endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
  265. .align 2
  266. debug_trap:
  267. #if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
  268. mov #OFF_SR, r0
  269. mov.l @(r0,r15), r0 ! get status register
  270. shll r0
  271. shll r0 ! kernel space?
  272. bt/s debug_kernel
  273. #endif
  274. mov.l @r15, r0 ! Restore R0 value
  275. mov.l 1f, r8
  276. jmp @r8
  277. nop
  278. .align 2
  279. ENTRY(exception_error)
  280. !
  281. STI()
  282. mov.l 2f, r0
  283. jmp @r0
  284. nop
  285. !
  286. .align 2
  287. 1: .long break_point_trap_software
  288. 2: .long do_exception_error
  289. .align 2
  290. ret_from_exception:
  291. preempt_stop()
  292. ret_from_irq:
  293. !
  294. mov #OFF_SR, r0
  295. mov.l @(r0,r15), r0 ! get status register
  296. shll r0
  297. shll r0 ! kernel space?
  298. bt/s resume_kernel ! Yes, it's from kernel, go back soon
  299. GET_THREAD_INFO(r8)
  300. #ifdef CONFIG_PREEMPT
  301. bra resume_userspace
  302. nop
  303. ENTRY(resume_kernel)
  304. mov.l @(TI_PRE_COUNT,r8), r0 ! current_thread_info->preempt_count
  305. tst r0, r0
  306. bf noresched
  307. need_resched:
  308. mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
  309. tst #_TIF_NEED_RESCHED, r0 ! need_resched set?
  310. bt noresched
  311. mov #OFF_SR, r0
  312. mov.l @(r0,r15), r0 ! get status register
  313. and #0xf0, r0 ! interrupts off (exception path)?
  314. cmp/eq #0xf0, r0
  315. bt noresched
  316. mov.l 1f, r0
  317. mov.l r0, @(TI_PRE_COUNT,r8)
  318. STI()
  319. mov.l 2f, r0
  320. jsr @r0
  321. nop
  322. mov #0, r0
  323. mov.l r0, @(TI_PRE_COUNT,r8)
  324. CLI()
  325. bra need_resched
  326. nop
  327. noresched:
  328. bra restore_all
  329. nop
  330. .align 2
  331. 1: .long PREEMPT_ACTIVE
  332. 2: .long schedule
  333. #endif
  334. ENTRY(resume_userspace)
  335. ! r8: current_thread_info
  336. CLI()
  337. mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
  338. tst #_TIF_WORK_MASK, r0
  339. bt/s restore_all
  340. tst #_TIF_NEED_RESCHED, r0
  341. .align 2
  342. work_pending:
  343. ! r0: current_thread_info->flags
  344. ! r8: current_thread_info
  345. ! t: result of "tst #_TIF_NEED_RESCHED, r0"
  346. bf/s work_resched
  347. tst #_TIF_SIGPENDING, r0
  348. work_notifysig:
  349. bt/s restore_all
  350. mov r15, r4
  351. mov #0, r5
  352. mov.l 2f, r1
  353. mova restore_all, r0
  354. jmp @r1
  355. lds r0, pr
  356. work_resched:
  357. #ifndef CONFIG_PREEMPT
  358. ! gUSA handling
  359. mov.l @(OFF_SP,r15), r0 ! get user space stack pointer
  360. mov r0, r1
  361. shll r0
  362. bf/s 1f
  363. shll r0
  364. bf/s 1f
  365. mov #OFF_PC, r0
  366. ! SP >= 0xc0000000 : gUSA mark
  367. mov.l @(r0,r15), r2 ! get user space PC (program counter)
  368. mov.l @(OFF_R0,r15), r3 ! end point
  369. cmp/hs r3, r2 ! r2 >= r3?
  370. bt 1f
  371. add r3, r1 ! rewind point #2
  372. mov.l r1, @(r0,r15) ! reset PC to rewind point #2
  373. !
  374. 1:
  375. #endif
  376. mov.l 1f, r1
  377. jsr @r1 ! schedule
  378. nop
  379. CLI()
  380. !
  381. mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
  382. tst #_TIF_WORK_MASK, r0
  383. bt restore_all
  384. bra work_pending
  385. tst #_TIF_NEED_RESCHED, r0
  386. .align 2
  387. 1: .long schedule
  388. 2: .long do_signal
  389. .align 2
  390. syscall_exit_work:
  391. ! r0: current_thread_info->flags
  392. ! r8: current_thread_info
  393. tst #_TIF_SYSCALL_TRACE, r0
  394. bt/s work_pending
  395. tst #_TIF_NEED_RESCHED, r0
  396. STI()
  397. ! XXX setup arguments...
  398. mov.l 4f, r0 ! do_syscall_trace
  399. jsr @r0
  400. nop
  401. bra resume_userspace
  402. nop
  403. .align 2
  404. syscall_trace_entry:
  405. ! Yes it is traced.
  406. ! XXX setup arguments...
  407. mov.l 4f, r11 ! Call do_syscall_trace which notifies
  408. jsr @r11 ! superior (will chomp R[0-7])
  409. nop
  410. ! Reload R0-R4 from kernel stack, where the
  411. ! parent may have modified them using
  412. ! ptrace(POKEUSR). (Note that R0-R2 are
  413. ! used by the system call handler directly
  414. ! from the kernel stack anyway, so don't need
  415. ! to be reloaded here.) This allows the parent
  416. ! to rewrite system calls and args on the fly.
  417. mov.l @(OFF_R4,r15), r4 ! arg0
  418. mov.l @(OFF_R5,r15), r5
  419. mov.l @(OFF_R6,r15), r6
  420. mov.l @(OFF_R7,r15), r7 ! arg3
  421. mov.l @(OFF_R3,r15), r3 ! syscall_nr
  422. ! Arrange for do_syscall_trace to be called
  423. ! again as the system call returns.
  424. mov.l 2f, r10 ! Number of syscalls
  425. cmp/hs r10, r3
  426. bf syscall_call
  427. mov #-ENOSYS, r0
  428. bra syscall_exit
  429. mov.l r0, @(OFF_R0,r15) ! Return value
  430. /*
  431. * Syscall interface:
  432. *
  433. * Syscall #: R3
  434. * Arguments #0 to #3: R4--R7
  435. * Arguments #4 to #6: R0, R1, R2
  436. * TRA: (number of arguments + 0x10) x 4
  437. *
  438. * This code also handles delegating other traps to the BIOS/gdb stub
  439. * according to:
  440. *
  441. * Trap number
  442. * (TRA>>2) Purpose
  443. * -------- -------
  444. * 0x0-0xf old syscall ABI
  445. * 0x10-0x1f new syscall ABI
  446. * 0x20-0xff delegated through debug_trap to BIOS/gdb stub.
  447. *
  448. * Note: When we're first called, the TRA value must be shifted
  449. * right 2 bits in order to get the value that was used as the "trapa"
  450. * argument.
  451. */
  452. .align 2
  453. .globl ret_from_fork
  454. ret_from_fork:
  455. mov.l 1f, r8
  456. jsr @r8
  457. mov r0, r4
  458. bra syscall_exit
  459. nop
  460. .align 2
  461. 1: .long schedule_tail
  462. !
  463. ENTRY(system_call)
  464. mov.l 1f, r9
  465. mov.l @r9, r8 ! Read from TRA (Trap Address) Register
  466. !
  467. ! Is the trap argument >= 0x20? (TRA will be >= 0x80)
  468. mov #0x7f, r9
  469. cmp/hi r9, r8
  470. bt/s 0f
  471. mov #OFF_TRA, r9
  472. add r15, r9
  473. !
  474. mov.l r8, @r9 ! set TRA value to tra
  475. STI()
  476. ! Call the system call handler through the table.
  477. ! First check for bad syscall number
  478. mov r3, r9
  479. mov.l 2f, r8 ! Number of syscalls
  480. cmp/hs r8, r9
  481. bf/s good_system_call
  482. GET_THREAD_INFO(r8)
  483. syscall_badsys: ! Bad syscall number
  484. mov #-ENOSYS, r0
  485. bra resume_userspace
  486. mov.l r0, @(OFF_R0,r15) ! Return value
  487. !
  488. 0:
  489. bra debug_trap
  490. nop
  491. !
  492. good_system_call: ! Good syscall number
  493. mov.l @(TI_FLAGS,r8), r8
  494. mov #_TIF_SYSCALL_TRACE, r10
  495. tst r10, r8
  496. bf syscall_trace_entry
  497. !
  498. syscall_call:
  499. shll2 r9 ! x4
  500. mov.l 3f, r8 ! Load the address of sys_call_table
  501. add r8, r9
  502. mov.l @r9, r8
  503. jsr @r8 ! jump to specific syscall handler
  504. nop
  505. mov.l r0, @(OFF_R0,r15) ! save the return value
  506. !
  507. syscall_exit:
  508. CLI()
  509. !
  510. GET_THREAD_INFO(r8)
  511. mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
  512. tst #_TIF_ALLWORK_MASK, r0
  513. bf syscall_exit_work
  514. restore_all:
  515. mov.l @r15+, r0
  516. mov.l @r15+, r1
  517. mov.l @r15+, r2
  518. mov.l @r15+, r3
  519. mov.l @r15+, r4
  520. mov.l @r15+, r5
  521. mov.l @r15+, r6
  522. mov.l @r15+, r7
  523. !
  524. stc sr, r8
  525. mov.l 7f, r9
  526. or r9, r8 ! BL =1, RB=1
  527. ldc r8, sr ! here, change the register bank
  528. !
  529. mov.l @r15+, r8
  530. mov.l @r15+, r9
  531. mov.l @r15+, r10
  532. mov.l @r15+, r11
  533. mov.l @r15+, r12
  534. mov.l @r15+, r13
  535. mov.l @r15+, r14
  536. mov.l @r15+, k4 ! original stack pointer
  537. ldc.l @r15+, spc
  538. lds.l @r15+, pr
  539. mov.l @r15+, k3 ! original SR
  540. ldc.l @r15+, gbr
  541. lds.l @r15+, mach
  542. lds.l @r15+, macl
  543. add #4, r15 ! Skip syscall number
  544. !
  545. #ifdef CONFIG_SH_DSP
  546. mov.l @r15+, k0 ! DSP mode marker
  547. mov.l 5f, k1
  548. cmp/eq k0, k1 ! Do we have a DSP stack frame?
  549. bf skip_restore
  550. stc sr, k0 ! Enable CPU DSP mode
  551. or k1, k0 ! (within kernel it may be disabled)
  552. ldc k0, sr
  553. mov r2, k0 ! Backup r2
  554. ! Restore DSP registers from stack
  555. mov r15, r2
  556. movs.l @r2+, a1
  557. movs.l @r2+, a0g
  558. movs.l @r2+, a1g
  559. movs.l @r2+, m0
  560. movs.l @r2+, m1
  561. mov r2, r15
  562. lds.l @r15+, a0
  563. lds.l @r15+, x0
  564. lds.l @r15+, x1
  565. lds.l @r15+, y0
  566. lds.l @r15+, y1
  567. lds.l @r15+, dsr
  568. ldc.l @r15+, rs
  569. ldc.l @r15+, re
  570. ldc.l @r15+, mod
  571. mov k0, r2 ! Restore r2
  572. skip_restore:
  573. #endif
  574. !
  575. ! Calculate new SR value
  576. mov k3, k2 ! original SR value
  577. mov.l 9f, k1
  578. and k1, k2 ! Mask orignal SR value
  579. !
  580. mov k3, k0 ! Calculate IMASK-bits
  581. shlr2 k0
  582. and #0x3c, k0
  583. cmp/eq #0x3c, k0
  584. bt/s 6f
  585. shll2 k0
  586. mov g_imask, k0
  587. !
  588. 6: or k0, k2 ! Set the IMASK-bits
  589. ldc k2, ssr
  590. !
  591. #if defined(CONFIG_KGDB_NMI)
  592. ! Clear in_nmi
  593. mov.l 4f, k0
  594. mov #0, k1
  595. mov.b k1, @k0
  596. #endif
  597. mov.l @r15+, k2 ! restore EXPEVT
  598. mov k4, r15
  599. rte
  600. nop
  601. .align 2
  602. 1: .long TRA
  603. 2: .long NR_syscalls
  604. 3: .long sys_call_table
  605. 4: .long do_syscall_trace
  606. 5: .long 0x00001000 ! DSP
  607. 7: .long 0x30000000
  608. 9:
  609. __INV_IMASK:
  610. .long 0xffffff0f ! ~(IMASK)
  611. ! Exception Vector Base
  612. !
  613. ! Should be aligned page boundary.
  614. !
  615. .balign 4096,0,4096
  616. ENTRY(vbr_base)
  617. .long 0
  618. !
  619. .balign 256,0,256
  620. general_exception:
  621. mov.l 1f, k2
  622. mov.l 2f, k3
  623. bra handle_exception
  624. mov.l @k2, k2
  625. .align 2
  626. 1: .long EXPEVT
  627. 2: .long ret_from_exception
  628. !
  629. !
  630. .balign 1024,0,1024
  631. tlb_miss:
  632. mov.l 1f, k2
  633. mov.l 4f, k3
  634. bra handle_exception
  635. mov.l @k2, k2
  636. !
  637. .balign 512,0,512
  638. interrupt:
  639. mov.l 2f, k2
  640. mov.l 3f, k3
  641. #if defined(CONFIG_KGDB_NMI)
  642. ! Debounce (filter nested NMI)
  643. mov.l @k2, k0
  644. mov.l 5f, k1
  645. cmp/eq k1, k0
  646. bf 0f
  647. mov.l 6f, k1
  648. tas.b @k1
  649. bt 0f
  650. rte
  651. nop
  652. .align 2
  653. 5: .long NMI_VEC
  654. 6: .long in_nmi
  655. 0:
  656. #endif /* defined(CONFIG_KGDB_NMI) */
  657. bra handle_exception
  658. mov.l @k2, k2
  659. .align 2
  660. 1: .long EXPEVT
  661. 2: .long INTEVT
  662. 3: .long ret_from_irq
  663. 4: .long ret_from_exception
  664. !
  665. !
  666. .align 2
  667. handle_exception:
  668. ! Using k0, k1 for scratch registers (r0_bank1, r1_bank),
  669. ! save all registers onto stack.
  670. !
  671. stc ssr, k0 ! Is it from kernel space?
  672. shll k0 ! Check MD bit (bit30) by shifting it into...
  673. shll k0 ! ...the T bit
  674. bt/s 1f ! It's a kernel to kernel transition.
  675. mov r15, k0 ! save original stack to k0
  676. /* User space to kernel */
  677. mov #0x20, k1
  678. shll8 k1 ! k1 := 8192 (== THREAD_SIZE)
  679. add current, k1
  680. mov k1, r15 ! change to kernel stack
  681. !
  682. 1: mov #-1, k4
  683. mov.l 2f, k1
  684. !
  685. #ifdef CONFIG_SH_DSP
  686. mov.l r2, @-r15 ! Save r2, we need another reg
  687. stc sr, k4
  688. mov.l 1f, r2
  689. tst r2, k4 ! Check if in DSP mode
  690. mov.l @r15+, r2 ! Restore r2 now
  691. bt/s skip_save
  692. mov #0, k4 ! Set marker for no stack frame
  693. mov r2, k4 ! Backup r2 (in k4) for later
  694. ! Save DSP registers on stack
  695. stc.l mod, @-r15
  696. stc.l re, @-r15
  697. stc.l rs, @-r15
  698. sts.l dsr, @-r15
  699. sts.l y1, @-r15
  700. sts.l y0, @-r15
  701. sts.l x1, @-r15
  702. sts.l x0, @-r15
  703. sts.l a0, @-r15
  704. ! GAS is broken, does not generate correct "movs.l Ds,@-As" instr.
  705. ! FIXME: Make sure that this is still the case with newer toolchains,
  706. ! as we're not at all interested in supporting ancient toolchains at
  707. ! this point. -- PFM.
  708. mov r15, r2
  709. .word 0xf653 ! movs.l a1, @-r2
  710. .word 0xf6f3 ! movs.l a0g, @-r2
  711. .word 0xf6d3 ! movs.l a1g, @-r2
  712. .word 0xf6c3 ! movs.l m0, @-r2
  713. .word 0xf6e3 ! movs.l m1, @-r2
  714. mov r2, r15
  715. mov k4, r2 ! Restore r2
  716. mov.l 1f, k4 ! Force DSP stack frame
  717. skip_save:
  718. mov.l k4, @-r15 ! Push DSP mode marker onto stack
  719. #endif
  720. ! Save the user registers on the stack.
  721. mov.l k2, @-r15 ! EXPEVT
  722. mov.l k4, @-r15 ! set TRA (default: -1)
  723. !
  724. sts.l macl, @-r15
  725. sts.l mach, @-r15
  726. stc.l gbr, @-r15
  727. stc.l ssr, @-r15
  728. sts.l pr, @-r15
  729. stc.l spc, @-r15
  730. !
  731. lds k3, pr ! Set the return address to pr
  732. !
  733. mov.l k0, @-r15 ! save orignal stack
  734. mov.l r14, @-r15
  735. mov.l r13, @-r15
  736. mov.l r12, @-r15
  737. mov.l r11, @-r15
  738. mov.l r10, @-r15
  739. mov.l r9, @-r15
  740. mov.l r8, @-r15
  741. !
  742. stc sr, r8 ! Back to normal register bank, and
  743. or k1, r8 ! Block all interrupts
  744. mov.l 3f, k1
  745. and k1, r8 ! ...
  746. ldc r8, sr ! ...changed here.
  747. !
  748. mov.l r7, @-r15
  749. mov.l r6, @-r15
  750. mov.l r5, @-r15
  751. mov.l r4, @-r15
  752. mov.l r3, @-r15
  753. mov.l r2, @-r15
  754. mov.l r1, @-r15
  755. mov.l r0, @-r15
  756. ! Then, dispatch to the handler, according to the exception code.
  757. stc k_ex_code, r8
  758. shlr2 r8
  759. shlr r8
  760. mov.l 4f, r9
  761. add r8, r9
  762. mov.l @r9, r9
  763. jmp @r9
  764. nop
  765. .align 2
  766. 1: .long 0x00001000 ! DSP=1
  767. 2: .long 0x000080f0 ! FD=1, IMASK=15
  768. 3: .long 0xcfffffff ! RB=0, BL=0
  769. 4: .long exception_handling_table
  770. .align 2
  771. ENTRY(exception_none)
  772. rts
  773. nop
  774. .data
  775. ENTRY(sys_call_table)
  776. .long sys_ni_syscall /* 0 - old "setup()" system call*/
  777. .long sys_exit
  778. .long sys_fork
  779. .long sys_read
  780. .long sys_write
  781. .long sys_open /* 5 */
  782. .long sys_close
  783. .long sys_waitpid
  784. .long sys_creat
  785. .long sys_link
  786. .long sys_unlink /* 10 */
  787. .long sys_execve
  788. .long sys_chdir
  789. .long sys_time
  790. .long sys_mknod
  791. .long sys_chmod /* 15 */
  792. .long sys_lchown16
  793. .long sys_ni_syscall /* old break syscall holder */
  794. .long sys_stat
  795. .long sys_lseek
  796. .long sys_getpid /* 20 */
  797. .long sys_mount
  798. .long sys_oldumount
  799. .long sys_setuid16
  800. .long sys_getuid16
  801. .long sys_stime /* 25 */
  802. .long sys_ptrace
  803. .long sys_alarm
  804. .long sys_fstat
  805. .long sys_pause
  806. .long sys_utime /* 30 */
  807. .long sys_ni_syscall /* old stty syscall holder */
  808. .long sys_ni_syscall /* old gtty syscall holder */
  809. .long sys_access
  810. .long sys_nice
  811. .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */
  812. .long sys_sync
  813. .long sys_kill
  814. .long sys_rename
  815. .long sys_mkdir
  816. .long sys_rmdir /* 40 */
  817. .long sys_dup
  818. .long sys_pipe
  819. .long sys_times
  820. .long sys_ni_syscall /* old prof syscall holder */
  821. .long sys_brk /* 45 */
  822. .long sys_setgid16
  823. .long sys_getgid16
  824. .long sys_signal
  825. .long sys_geteuid16
  826. .long sys_getegid16 /* 50 */
  827. .long sys_acct
  828. .long sys_umount /* recycled never used phys() */
  829. .long sys_ni_syscall /* old lock syscall holder */
  830. .long sys_ioctl
  831. .long sys_fcntl /* 55 */
  832. .long sys_ni_syscall /* old mpx syscall holder */
  833. .long sys_setpgid
  834. .long sys_ni_syscall /* old ulimit syscall holder */
  835. .long sys_ni_syscall /* sys_olduname */
  836. .long sys_umask /* 60 */
  837. .long sys_chroot
  838. .long sys_ustat
  839. .long sys_dup2
  840. .long sys_getppid
  841. .long sys_getpgrp /* 65 */
  842. .long sys_setsid
  843. .long sys_sigaction
  844. .long sys_sgetmask
  845. .long sys_ssetmask
  846. .long sys_setreuid16 /* 70 */
  847. .long sys_setregid16
  848. .long sys_sigsuspend
  849. .long sys_sigpending
  850. .long sys_sethostname
  851. .long sys_setrlimit /* 75 */
  852. .long sys_old_getrlimit
  853. .long sys_getrusage
  854. .long sys_gettimeofday
  855. .long sys_settimeofday
  856. .long sys_getgroups16 /* 80 */
  857. .long sys_setgroups16
  858. .long sys_ni_syscall /* sys_oldselect */
  859. .long sys_symlink
  860. .long sys_lstat
  861. .long sys_readlink /* 85 */
  862. .long sys_uselib
  863. .long sys_swapon
  864. .long sys_reboot
  865. .long old_readdir
  866. .long old_mmap /* 90 */
  867. .long sys_munmap
  868. .long sys_truncate
  869. .long sys_ftruncate
  870. .long sys_fchmod
  871. .long sys_fchown16 /* 95 */
  872. .long sys_getpriority
  873. .long sys_setpriority
  874. .long sys_ni_syscall /* old profil syscall holder */
  875. .long sys_statfs
  876. .long sys_fstatfs /* 100 */
  877. .long sys_ni_syscall /* ioperm */
  878. .long sys_socketcall
  879. .long sys_syslog
  880. .long sys_setitimer
  881. .long sys_getitimer /* 105 */
  882. .long sys_newstat
  883. .long sys_newlstat
  884. .long sys_newfstat
  885. .long sys_uname
  886. .long sys_ni_syscall /* 110 */ /* iopl */
  887. .long sys_vhangup
  888. .long sys_ni_syscall /* idle */
  889. .long sys_ni_syscall /* vm86old */
  890. .long sys_wait4
  891. .long sys_swapoff /* 115 */
  892. .long sys_sysinfo
  893. .long sys_ipc
  894. .long sys_fsync
  895. .long sys_sigreturn
  896. .long sys_clone /* 120 */
  897. .long sys_setdomainname
  898. .long sys_newuname
  899. .long sys_ni_syscall /* sys_modify_ldt */
  900. .long sys_adjtimex
  901. .long sys_mprotect /* 125 */
  902. .long sys_sigprocmask
  903. .long sys_ni_syscall /* old "create_module" */
  904. .long sys_init_module
  905. .long sys_delete_module
  906. .long sys_ni_syscall /* 130: old "get_kernel_syms" */
  907. .long sys_quotactl
  908. .long sys_getpgid
  909. .long sys_fchdir
  910. .long sys_bdflush
  911. .long sys_sysfs /* 135 */
  912. .long sys_personality
  913. .long sys_ni_syscall /* for afs_syscall */
  914. .long sys_setfsuid16
  915. .long sys_setfsgid16
  916. .long sys_llseek /* 140 */
  917. .long sys_getdents
  918. .long sys_select
  919. .long sys_flock
  920. .long sys_msync
  921. .long sys_readv /* 145 */
  922. .long sys_writev
  923. .long sys_getsid
  924. .long sys_fdatasync
  925. .long sys_sysctl
  926. .long sys_mlock /* 150 */
  927. .long sys_munlock
  928. .long sys_mlockall
  929. .long sys_munlockall
  930. .long sys_sched_setparam
  931. .long sys_sched_getparam /* 155 */
  932. .long sys_sched_setscheduler
  933. .long sys_sched_getscheduler
  934. .long sys_sched_yield
  935. .long sys_sched_get_priority_max
  936. .long sys_sched_get_priority_min /* 160 */
  937. .long sys_sched_rr_get_interval
  938. .long sys_nanosleep
  939. .long sys_mremap
  940. .long sys_setresuid16
  941. .long sys_getresuid16 /* 165 */
  942. .long sys_ni_syscall /* vm86 */
  943. .long sys_ni_syscall /* old "query_module" */
  944. .long sys_poll
  945. .long sys_nfsservctl
  946. .long sys_setresgid16 /* 170 */
  947. .long sys_getresgid16
  948. .long sys_prctl
  949. .long sys_rt_sigreturn
  950. .long sys_rt_sigaction
  951. .long sys_rt_sigprocmask /* 175 */
  952. .long sys_rt_sigpending
  953. .long sys_rt_sigtimedwait
  954. .long sys_rt_sigqueueinfo
  955. .long sys_rt_sigsuspend
  956. .long sys_pread_wrapper /* 180 */
  957. .long sys_pwrite_wrapper
  958. .long sys_chown16
  959. .long sys_getcwd
  960. .long sys_capget
  961. .long sys_capset /* 185 */
  962. .long sys_sigaltstack
  963. .long sys_sendfile
  964. .long sys_ni_syscall /* streams1 */
  965. .long sys_ni_syscall /* streams2 */
  966. .long sys_vfork /* 190 */
  967. .long sys_getrlimit
  968. .long sys_mmap2
  969. .long sys_truncate64
  970. .long sys_ftruncate64
  971. .long sys_stat64 /* 195 */
  972. .long sys_lstat64
  973. .long sys_fstat64
  974. .long sys_lchown
  975. .long sys_getuid
  976. .long sys_getgid /* 200 */
  977. .long sys_geteuid
  978. .long sys_getegid
  979. .long sys_setreuid
  980. .long sys_setregid
  981. .long sys_getgroups /* 205 */
  982. .long sys_setgroups
  983. .long sys_fchown
  984. .long sys_setresuid
  985. .long sys_getresuid
  986. .long sys_setresgid /* 210 */
  987. .long sys_getresgid
  988. .long sys_chown
  989. .long sys_setuid
  990. .long sys_setgid
  991. .long sys_setfsuid /* 215 */
  992. .long sys_setfsgid
  993. .long sys_pivot_root
  994. .long sys_mincore
  995. .long sys_madvise
  996. .long sys_getdents64 /* 220 */
  997. .long sys_fcntl64
  998. .long sys_ni_syscall /* reserved for TUX */
  999. .long sys_ni_syscall /* Reserved for Security */
  1000. .long sys_gettid
  1001. .long sys_readahead /* 225 */
  1002. .long sys_setxattr
  1003. .long sys_lsetxattr
  1004. .long sys_fsetxattr
  1005. .long sys_getxattr
  1006. .long sys_lgetxattr /* 230 */
  1007. .long sys_fgetxattr
  1008. .long sys_listxattr
  1009. .long sys_llistxattr
  1010. .long sys_flistxattr
  1011. .long sys_removexattr /* 235 */
  1012. .long sys_lremovexattr
  1013. .long sys_fremovexattr
  1014. .long sys_tkill
  1015. .long sys_sendfile64
  1016. .long sys_futex /* 240 */
  1017. .long sys_sched_setaffinity
  1018. .long sys_sched_getaffinity
  1019. .long sys_ni_syscall
  1020. .long sys_ni_syscall
  1021. .long sys_io_setup /* 245 */
  1022. .long sys_io_destroy
  1023. .long sys_io_getevents
  1024. .long sys_io_submit
  1025. .long sys_io_cancel
  1026. .long sys_fadvise64 /* 250 */
  1027. .long sys_ni_syscall
  1028. .long sys_exit_group
  1029. .long sys_lookup_dcookie
  1030. .long sys_epoll_create
  1031. .long sys_epoll_ctl /* 255 */
  1032. .long sys_epoll_wait
  1033. .long sys_remap_file_pages
  1034. .long sys_set_tid_address
  1035. .long sys_timer_create
  1036. .long sys_timer_settime /* 260 */
  1037. .long sys_timer_gettime
  1038. .long sys_timer_getoverrun
  1039. .long sys_timer_delete
  1040. .long sys_clock_settime
  1041. .long sys_clock_gettime /* 265 */
  1042. .long sys_clock_getres
  1043. .long sys_clock_nanosleep
  1044. .long sys_statfs64
  1045. .long sys_fstatfs64
  1046. .long sys_tgkill /* 270 */
  1047. .long sys_utimes
  1048. .long sys_fadvise64_64_wrapper
  1049. .long sys_ni_syscall /* Reserved for vserver */
  1050. .long sys_ni_syscall /* Reserved for mbind */
  1051. .long sys_ni_syscall /* 275 - get_mempolicy */
  1052. .long sys_ni_syscall /* set_mempolicy */
  1053. .long sys_mq_open
  1054. .long sys_mq_unlink
  1055. .long sys_mq_timedsend
  1056. .long sys_mq_timedreceive /* 280 */
  1057. .long sys_mq_notify
  1058. .long sys_mq_getsetattr
  1059. .long sys_ni_syscall /* Reserved for kexec */
  1060. .long sys_waitid
  1061. .long sys_add_key /* 285 */
  1062. .long sys_request_key
  1063. .long sys_keyctl
  1064. .long sys_ioprio_set
  1065. .long sys_ioprio_get
  1066. .long sys_inotify_init /* 290 */
  1067. .long sys_inotify_add_watch
  1068. .long sys_inotify_rm_watch
  1069. /* End of entry.S */