entry.S 25 KB

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