entry.S 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /* -*- mode: asm -*-
  2. *
  3. * linux/arch/h8300/platform/h8s/entry.S
  4. *
  5. * Yoshinori Sato <ysato@users.sourceforge.jp>
  6. *
  7. * fairly heavy changes to fix syscall args and signal processing
  8. * by David McCullough <davidm@snapgear.com>
  9. */
  10. /*
  11. * entry.S
  12. * include exception/interrupt gateway
  13. * system call entry
  14. */
  15. #include <linux/sys.h>
  16. #include <linux/config.h>
  17. #include <asm/unistd.h>
  18. #include <asm/setup.h>
  19. #include <asm/segment.h>
  20. #include <asm/linkage.h>
  21. #include <asm/asm-offsets.h>
  22. #include <asm/thread_info.h>
  23. #include <asm/errno.h>
  24. .h8300s
  25. /* CPU context save/restore macros. */
  26. .macro SAVE_ALL
  27. mov.l er0,@-sp
  28. stc ccr,r0l /* check kernel mode */
  29. orc #0x10,ccr
  30. btst #4,r0l
  31. bne 5f
  32. mov.l sp,@SYMBOL_NAME(sw_usp) /* user mode */
  33. mov.l @sp,er0
  34. mov.l @SYMBOL_NAME(sw_ksp),sp
  35. sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */
  36. stm.l er0-er3,@-sp
  37. mov.l @SYMBOL_NAME(sw_usp),er0
  38. mov.l @(10:16,er0),er1 /* copy the RET addr */
  39. mov.l er1,@(LRET-LER3:16,sp)
  40. mov.w @(8:16,er0),r1
  41. mov.w r1,@(LEXR-LER3:16,sp) /* copy EXR */
  42. mov.w e1,r1 /* e1 highbyte = ccr */
  43. and #0xef,r1h /* mask mode? flag */
  44. sub.w r0,r0
  45. mov.b r1h,r0l
  46. mov.w r0,@(LCCR-LER3:16,sp) /* copy ccr */
  47. mov.l @(LORIG-LER3:16,sp),er0
  48. mov.l er0,@(LER0-LER3:16,sp) /* copy ER0 */
  49. bra 6f
  50. 5:
  51. mov.l @sp,er0 /* kernel mode */
  52. subs #2,sp /* dummy ccr */
  53. stm.l er0-er3,@-sp
  54. mov.w @(LRET-LER3:16,sp),r1 /* copy old ccr */
  55. mov.b r1h,r1l
  56. mov.b #0,r1h
  57. mov.w r1,@(LCCR-LER3:16,sp)
  58. 6:
  59. mov.l er6,@-sp /* syscall arg #6 */
  60. mov.l er5,@-sp /* syscall arg #5 */
  61. mov.l er4,@-sp /* syscall arg #4 */
  62. .endm
  63. .macro RESTORE_ALL
  64. mov.l @sp+,er4
  65. mov.l @sp+,er5
  66. mov.l @sp+,er6
  67. ldm.l @sp+,er2-er3
  68. mov.w @(LCCR-LER1:16,sp),r0 /* check kernel mode */
  69. btst #4,r0l
  70. bne 7f
  71. orc #0x80,ccr
  72. mov.l @SYMBOL_NAME(sw_usp),er0
  73. mov.l @(LER0-LER1:16,sp),er1 /* restore ER0 */
  74. mov.l er1,@er0
  75. mov.w @(LEXR-LER1:16,sp),r1 /* restore EXR */
  76. mov.b r1l,r1h
  77. mov.w r1,@(8:16,er0)
  78. mov.w @(LCCR-LER1:16,sp),r1 /* restore the RET addr */
  79. mov.b r1l,r1h
  80. mov.b @(LRET+1-LER1:16,sp),r1l
  81. mov.w r1,e1
  82. mov.w @(LRET+2-LER1:16,sp),r1
  83. mov.l er1,@(10:16,er0)
  84. mov.l @sp+,er1
  85. add.l #(LRET-LER1),sp /* remove LORIG - LRET */
  86. mov.l sp,@SYMBOL_NAME(sw_ksp)
  87. mov.l er0,sp
  88. bra 8f
  89. 7:
  90. mov.l @sp+,er1
  91. adds #4,sp
  92. adds #2,sp
  93. 8:
  94. mov.l @sp+,er0
  95. adds #4,sp /* remove the sw created LVEC */
  96. rte
  97. .endm
  98. .globl SYMBOL_NAME(system_call)
  99. .globl SYMBOL_NAME(ret_from_exception)
  100. .globl SYMBOL_NAME(ret_from_fork)
  101. .globl SYMBOL_NAME(ret_from_interrupt)
  102. .globl SYMBOL_NAME(interrupt_redirect_table)
  103. .globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
  104. .globl SYMBOL_NAME(resume)
  105. .globl SYMBOL_NAME(trace_break)
  106. .globl SYMBOL_NAME(interrupt_entry)
  107. INTERRUPTS = 128
  108. #if defined(CONFIG_ROMKERNEL)
  109. .section .int_redirect,"ax"
  110. SYMBOL_NAME_LABEL(interrupt_redirect_table)
  111. .rept 7
  112. .long 0
  113. .endr
  114. jsr @SYMBOL_NAME(interrupt_entry) /* NMI */
  115. jmp @SYMBOL_NAME(system_call) /* TRAPA #0 (System call) */
  116. .long 0
  117. .long 0
  118. jmp @SYMBOL_NAME(trace_break) /* TRAPA #3 (breakpoint) */
  119. .rept INTERRUPTS-12
  120. jsr @SYMBOL_NAME(interrupt_entry)
  121. .endr
  122. #endif
  123. #if defined(CONFIG_RAMKERNEL)
  124. .globl SYMBOL_NAME(interrupt_redirect_table)
  125. .section .bss
  126. SYMBOL_NAME_LABEL(interrupt_redirect_table)
  127. .space 4
  128. #endif
  129. .section .text
  130. .align 2
  131. SYMBOL_NAME_LABEL(interrupt_entry)
  132. SAVE_ALL
  133. mov.w @(LCCR,sp),r0
  134. btst #4,r0l
  135. bne 1f
  136. mov.l @SYMBOL_NAME(sw_usp),er0
  137. mov.l @(4:16,er0),er0
  138. bra 2f
  139. 1:
  140. mov.l @(LVEC:16,sp),er0
  141. 2:
  142. #if defined(CONFIG_ROMKERNEL)
  143. sub.l #SYMBOL_NAME(interrupt_redirect_table),er0
  144. #endif
  145. #if defined(CONFIG_RAMKERNEL)
  146. mov.l @SYMBOL_NAME(interrupt_redirect_table),er1
  147. sub.l er1,er0
  148. #endif
  149. shlr.l #2,er0
  150. dec.l #1,er0
  151. mov.l sp,er1
  152. subs #4,er1 /* adjust ret_pc */
  153. jsr @SYMBOL_NAME(process_int)
  154. mov.l @SYMBOL_NAME(irq_stat)+CPUSTAT_SOFTIRQ_PENDING,er0
  155. beq 1f
  156. jsr @SYMBOL_NAME(do_softirq)
  157. 1:
  158. jmp @SYMBOL_NAME(ret_from_exception)
  159. SYMBOL_NAME_LABEL(system_call)
  160. subs #4,sp /* dummy LVEC */
  161. SAVE_ALL
  162. mov.w @(LCCR:16,sp),r1
  163. bset #4,r1l
  164. ldc r1l,ccr /* restore ccr */
  165. mov.l er0,er4
  166. mov.l #-ENOSYS,er0
  167. mov.l er0,@(LER0:16,sp)
  168. /* save top of frame */
  169. mov.l sp,er0
  170. jsr @SYMBOL_NAME(set_esp0)
  171. cmp.l #NR_syscalls,er4
  172. bcc SYMBOL_NAME(ret_from_exception):16
  173. shll.l #2,er4
  174. mov.l #SYMBOL_NAME(sys_call_table),er0
  175. add.l er4,er0
  176. mov.l @er0,er0
  177. mov.l er0,er4
  178. beq SYMBOL_NAME(ret_from_exception):16
  179. mov.l sp,er2
  180. and.w #0xe000,r2
  181. mov.b @((TASK_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
  182. btst #(TIF_SYSCALL_TRACE & 7),r2l
  183. mov.l @(LER1:16,sp),er0
  184. mov.l @(LER2:16,sp),er1
  185. mov.l @(LER3:16,sp),er2
  186. jsr @er4
  187. mov.l er0,@(LER0:16,sp) /* save the return value */
  188. #if defined(CONFIG_SYSCALL_PRINT)
  189. jsr @SYMBOL_NAME(syscall_print)
  190. #endif
  191. bra SYMBOL_NAME(ret_from_exception):8
  192. 1:
  193. jsr SYMBOL_NAME(syscall_trace)
  194. mov.l @(LER1:16,sp),er0
  195. mov.l @(LER2:16,sp),er1
  196. mov.l @(LER3:16,sp),er2
  197. jsr @er4
  198. mov.l er0,@(LER0:16,sp) /* save the return value */
  199. jsr @SYMBOL_NAME(syscall_trace)
  200. bra SYMBOL_NAME(ret_from_exception):8
  201. SYMBOL_NAME_LABEL(ret_from_fork)
  202. mov.l er2,er0
  203. jsr @SYMBOL_NAME(schedule_tail)
  204. bra SYMBOL_NAME(ret_from_exception):8
  205. SYMBOL_NAME_LABEL(reschedule)
  206. /* save top of frame */
  207. mov.l sp,er0
  208. jsr @SYMBOL_NAME(set_esp0)
  209. jsr @SYMBOL_NAME(schedule)
  210. SYMBOL_NAME_LABEL(ret_from_exception)
  211. #if defined(CONFIG_PREEMPT)
  212. orc #0x80,ccr
  213. #endif
  214. SYMBOL_NAME_LABEL(ret_from_interrupt)
  215. mov.b @(LCCR+1:16,sp),r0l
  216. btst #4,r0l /* check if returning to kernel */
  217. bne done:8 /* if so, skip resched, signals */
  218. andc #0x7f,ccr
  219. mov.l sp,er4
  220. and.w #0xe000,r4
  221. mov.l @(TI_FLAGS:16,er4),er1
  222. and.l #_TIF_WORK_MASK,er1
  223. beq done:8
  224. 1:
  225. mov.l @(TI_FLAGS:16,er4),er1
  226. btst #TIF_NEED_RESCHED,r1l
  227. bne SYMBOL_NAME(reschedule):16
  228. mov.l sp,er0
  229. subs #4,er0 /* adjust retpc */
  230. mov.l er2,er1
  231. jsr @SYMBOL_NAME(do_signal)
  232. #if defined(CONFIG_PREEMPT)
  233. bra done:8 /* userspace thoru */
  234. 3:
  235. btst #4,r0l
  236. beq done:8 /* userspace thoru */
  237. 4:
  238. mov.l @(TI_PRE_COUNT:16,er4),er1
  239. bne done:8
  240. mov.l @(TI_FLAGS:16,er4),er1
  241. btst #TIF_NEED_RESCHED,r1l
  242. beq done:8
  243. mov.b r0l,r0l
  244. bpl done:8 /* interrupt off (exception path?) */
  245. mov.l #PREEMPT_ACTIVE,er1
  246. mov.l er1,@(TI_PRE_COUNT:16,er4)
  247. andc #0x7f,ccr
  248. jsr @SYMBOL_NAME(schedule)
  249. sub.l er1,er1
  250. mov.l er1,@(TI_PRE_COUNT:16,er4)
  251. orc #0x80,ccr
  252. bra 4b:8
  253. #endif
  254. done:
  255. RESTORE_ALL /* Does RTE */
  256. SYMBOL_NAME_LABEL(resume)
  257. /*
  258. * er0 = prev
  259. * er1 = next
  260. * return last in er2
  261. */
  262. /* save sr */
  263. sub.w r3,r3
  264. stc ccr,r3l
  265. stc exr,r3h
  266. mov.w r3,@(THREAD_CCR+2:16,er0)
  267. /* disable interrupts */
  268. orc #0x80,ccr
  269. mov.l @SYMBOL_NAME(sw_usp),er3
  270. mov.l er3,@(THREAD_USP:16,er0)
  271. mov.l sp,@(THREAD_KSP:16,er0)
  272. /* Skip address space switching if they are the same. */
  273. /* FIXME: what did we hack out of here, this does nothing! */
  274. mov.l @(THREAD_USP:16,er1),er0
  275. mov.l er0,@SYMBOL_NAME(sw_usp)
  276. mov.l @(THREAD_KSP:16,er1),sp
  277. /* restore status register */
  278. mov.w @(THREAD_CCR+2:16,er1),r3
  279. ldc r3l,ccr
  280. ldc r3h,exr
  281. rts
  282. SYMBOL_NAME_LABEL(trace_break)
  283. subs #4,sp /* dummy LVEC */
  284. SAVE_ALL
  285. sub.l er1,er1
  286. dec.l #1,er1
  287. mov.l er1,@(LORIG,sp)
  288. mov.l sp,er0
  289. jsr @SYMBOL_NAME(set_esp0)
  290. mov.l @SYMBOL_NAME(sw_usp),er0
  291. mov.l @er0,er1
  292. subs #2,er1
  293. mov.l er1,@er0
  294. and.w #0xff,e1
  295. mov.l er1,er0
  296. jsr @SYMBOL_NAME(trace_trap)
  297. jmp @SYMBOL_NAME(ret_from_exception)
  298. .section .bss
  299. SYMBOL_NAME_LABEL(sw_ksp)
  300. .space 4
  301. SYMBOL_NAME_LABEL(sw_usp)
  302. .space 4