entry.S 24 KB

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