entry.S 7.6 KB
Newer Older
L
Linus Torvalds 已提交
1 2
/* -*- mode: asm -*-
 *
Y
Yoshinori Sato 已提交
3
 *  linux/arch/h8300/platform/h8300h/entry.S
L
Linus Torvalds 已提交
4 5
 *
 *  Yoshinori Sato <ysato@users.sourceforge.jp>
Y
Yoshinori Sato 已提交
6
 *  David McCullough <davidm@snapgear.com>
L
Linus Torvalds 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 */

/*
 *  entry.S
 *  include exception/interrupt gateway
 *          system call entry
 */

#include <linux/sys.h>
#include <asm/unistd.h>
#include <asm/setup.h>
#include <asm/segment.h>
#include <asm/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/errno.h>

Y
Yoshinori Sato 已提交
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
#if defined(CONFIG_CPU_H8300H)
#define USERRET 8
INTERRUPTS = 64
	.h8300h
	.macro	SHLL2 reg
	shll.l	\reg
	shll.l	\reg
	.endm
	.macro	SHLR2 reg
	shlr.l	\reg
	shlr.l	\reg
	.endm
	.macro	SAVEREGS
	mov.l	er0,@-sp
	mov.l	er1,@-sp
	mov.l	er2,@-sp
	mov.l	er3,@-sp
	.endm
	.macro	RESTOREREGS
	mov.l	@sp+,er3
	mov.l	@sp+,er2
	.endm
	.macro	SAVEEXR
	.endm
	.macro	RESTOREEXR
	.endm
#endif
#if defined(CONFIG_CPU_H8S)
#define USERRET 10
#define USEREXR 8
INTERRUPTS = 128
L
Linus Torvalds 已提交
56
	.h8300s
Y
Yoshinori Sato 已提交
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
	.macro	SHLL2 reg
	shll.l	#2,\reg
	.endm
	.macro	SHLR2 reg
	shlr.l	#2,\reg
	.endm
	.macro	SAVEREGS
	stm.l	er0-er3,@-sp
	.endm
	.macro	RESTOREREGS
	ldm.l	@sp+,er2-er3
	.endm
	.macro	SAVEEXR
	mov.w	@(USEREXR:16,er0),r1
	mov.w	r1,@(LEXR-LER3:16,sp)		/* copy EXR */
	.endm
	.macro	RESTOREEXR
	mov.w	@(LEXR-LER1:16,sp),r1		/* restore EXR */
	mov.b	r1l,r1h
	mov.w	r1,@(USEREXR:16,er0)
	.endm
#endif

L
Linus Torvalds 已提交
80 81

/* CPU context save/restore macros. */
Y
Yoshinori Sato 已提交
82

L
Linus Torvalds 已提交
83 84 85 86 87 88
	.macro	SAVE_ALL
	mov.l	er0,@-sp
	stc	ccr,r0l				/* check kernel mode */
	btst	#4,r0l
	bne	5f

Y
Yoshinori Sato 已提交
89
	/* user mode */
90
	mov.l	sp,@_sw_usp
Y
Yoshinori Sato 已提交
91 92
	mov.l	@sp,er0				/* restore saved er0 */
	orc	#0x10,ccr			/* switch kernel stack */
93
	mov.l	@_sw_ksp,sp
Y
Yoshinori Sato 已提交
94 95
	sub.l	#(LRET-LORIG),sp		/* allocate LORIG - LRET */
	SAVEREGS
96
	mov.l   @_sw_usp,er0
Y
Yoshinori Sato 已提交
97 98 99
	mov.l   @(USERRET:16,er0),er1           /* copy the RET addr */
	mov.l   er1,@(LRET-LER3:16,sp)
	SAVEEXR
L
Linus Torvalds 已提交
100 101 102

	mov.l	@(LORIG-LER3:16,sp),er0
	mov.l	er0,@(LER0-LER3:16,sp)		/* copy ER0 */
Y
Yoshinori Sato 已提交
103 104
	mov.w	e1,r1				/* e1 highbyte = ccr */
	and	#0xef,r1h			/* mask mode? flag */
L
Linus Torvalds 已提交
105 106
	bra	6f
5:
Y
Yoshinori Sato 已提交
107 108 109
	/* kernel mode */
	mov.l	@sp,er0				/* restore saved er0 */
	subs	#2,sp				/* set dummy ccr */
Y
Yoshinori Sato 已提交
110
	SAVEREGS
L
Linus Torvalds 已提交
111
	mov.w	@(LRET-LER3:16,sp),r1		/* copy old ccr */
Y
Yoshinori Sato 已提交
112
6:
L
Linus Torvalds 已提交
113 114
	mov.b	r1h,r1l
	mov.b	#0,r1h
Y
Yoshinori Sato 已提交
115
	mov.w	r1,@(LCCR-LER3:16,sp)		/* set ccr */
L
Linus Torvalds 已提交
116 117 118
	mov.l	er6,@-sp			/* syscall arg #6 */
	mov.l	er5,@-sp			/* syscall arg #5 */
	mov.l	er4,@-sp			/* syscall arg #4 */
Y
Yoshinori Sato 已提交
119
	.endm					/* r1 = ccr */
L
Linus Torvalds 已提交
120 121 122 123 124

	.macro	RESTORE_ALL
	mov.l	@sp+,er4
	mov.l	@sp+,er5
	mov.l	@sp+,er6
Y
Yoshinori Sato 已提交
125
	RESTOREREGS
L
Linus Torvalds 已提交
126 127 128 129 130
	mov.w	@(LCCR-LER1:16,sp),r0		/* check kernel mode */
	btst	#4,r0l
	bne	7f

	orc	#0x80,ccr
131
	mov.l	@_sw_usp,er0
L
Linus Torvalds 已提交
132 133
	mov.l	@(LER0-LER1:16,sp),er1		/* restore ER0 */
	mov.l	er1,@er0
Y
Yoshinori Sato 已提交
134
	RESTOREEXR
L
Linus Torvalds 已提交
135 136 137 138 139
	mov.w	@(LCCR-LER1:16,sp),r1		/* restore the RET addr */
	mov.b	r1l,r1h
	mov.b	@(LRET+1-LER1:16,sp),r1l
	mov.w	r1,e1
	mov.w	@(LRET+2-LER1:16,sp),r1
Y
Yoshinori Sato 已提交
140
	mov.l	er1,@(USERRET:16,er0)
L
Linus Torvalds 已提交
141 142

	mov.l	@sp+,er1
Y
Yoshinori Sato 已提交
143
	add.l	#(LRET-LER1),sp			/* remove LORIG - LRET */
144
	mov.l	sp,@_sw_ksp
Y
Yoshinori Sato 已提交
145
	andc	#0xef,ccr			/* switch to user mode */
L
Linus Torvalds 已提交
146 147 148 149 150 151 152 153 154 155 156
	mov.l	er0,sp
	bra	8f
7:
	mov.l	@sp+,er1
	adds	#4,sp
	adds	#2,sp
8:
	mov.l	@sp+,er0
	adds	#4,sp				/* remove the sw created LVEC */
	rte
	.endm
Y
Yoshinori Sato 已提交
157

158 159 160 161 162 163 164 165 166 167
.globl _system_call
.globl _ret_from_exception
.globl _ret_from_fork
.globl _ret_from_kernel_thread
.globl _ret_from_interrupt
.globl _interrupt_redirect_table
.globl _sw_ksp,_sw_usp
.globl _resume
.globl _interrupt_entry
.globl _trace_break
Y
Yoshinori Sato 已提交
168

L
Linus Torvalds 已提交
169 170
#if defined(CONFIG_ROMKERNEL)
	.section .int_redirect,"ax"
171
_interrupt_redirect_table:
Y
Yoshinori Sato 已提交
172
#if defined(CONFIG_CPU_H8300H)
L
Linus Torvalds 已提交
173 174 175
	.rept	7
	.long	0
	.endr
Y
Yoshinori Sato 已提交
176 177 178 179 180
#endif
#if defined(CONFIG_CPU_H8S)
	.rept	5
	.long	0
	.endr
181
	jmp	@_trace_break
Y
Yoshinori Sato 已提交
182 183 184
	.long	0
#endif

185 186
	jsr	@_interrupt_entry		/* NMI */
	jmp	@_system_call			/* TRAPA #0 (System call) */
L
Linus Torvalds 已提交
187 188
	.long	0
	.long	0
189
	jmp	@_trace_break			/* TRAPA #3 (breakpoint) */
L
Linus Torvalds 已提交
190
	.rept	INTERRUPTS-12
191
	jsr	@_interrupt_entry
L
Linus Torvalds 已提交
192 193 194
	.endr
#endif
#if defined(CONFIG_RAMKERNEL)
195
.globl _interrupt_redirect_table
L
Linus Torvalds 已提交
196
	.section .bss
197
_interrupt_redirect_table:
L
Linus Torvalds 已提交
198 199
	.space	4
#endif
Y
Yoshinori Sato 已提交
200

L
Linus Torvalds 已提交
201 202
	.section .text
	.align	2
203
_interrupt_entry:
L
Linus Torvalds 已提交
204
	SAVE_ALL
Y
Yoshinori Sato 已提交
205 206 207
	mov.l	sp,er0
	add.l	#LVEC,er0
	btst	#4,r1l
L
Linus Torvalds 已提交
208
	bne	1f
Y
Yoshinori Sato 已提交
209
	/* user LVEC */
210
	mov.l	@_sw_usp,er0
Y
Yoshinori Sato 已提交
211
	adds	#4,er0
L
Linus Torvalds 已提交
212
1:
Y
Yoshinori Sato 已提交
213
	mov.l	@er0,er0			/* LVEC address */
L
Linus Torvalds 已提交
214
#if defined(CONFIG_ROMKERNEL)
215
	sub.l	#_interrupt_redirect_table,er0
L
Linus Torvalds 已提交
216 217
#endif
#if defined(CONFIG_RAMKERNEL)
218
	mov.l	@_interrupt_redirect_table,er1
L
Linus Torvalds 已提交
219 220
	sub.l	er1,er0
#endif
Y
Yoshinori Sato 已提交
221
	SHLR2	er0
L
Linus Torvalds 已提交
222 223 224
	dec.l	#1,er0
	mov.l	sp,er1
	subs	#4,er1				/* adjust ret_pc */
225 226
	jsr	@_do_IRQ
	jmp	@_ret_from_interrupt
L
Linus Torvalds 已提交
227

228
_system_call:
L
Linus Torvalds 已提交
229 230
	subs	#4,sp				/* dummy LVEC */
	SAVE_ALL
Y
Yoshinori Sato 已提交
231
	andc	#0x7f,ccr
L
Linus Torvalds 已提交
232 233 234 235
	mov.l	er0,er4

	/* save top of frame */
	mov.l	sp,er0
236
	jsr	@_set_esp0
L
Linus Torvalds 已提交
237 238
	mov.l	sp,er2
	and.w	#0xe000,r2
Y
Yoshinori Sato 已提交
239
	mov.b	@((TI_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
L
Linus Torvalds 已提交
240
	btst	#(TIF_SYSCALL_TRACE & 7),r2l
Y
Yoshinori Sato 已提交
241
	beq	1f
242
	jsr	@_do_syscall_trace
Y
Yoshinori Sato 已提交
243 244 245 246
1:
	cmp.l	#NR_syscalls,er4
	bcc	badsys
	SHLL2	er4
247
	mov.l	#_sys_call_table,er0
Y
Yoshinori Sato 已提交
248 249
	add.l	er4,er0
	mov.l	@er0,er4
250
	beq	_ret_from_exception:16
L
Linus Torvalds 已提交
251 252 253 254
	mov.l	@(LER1:16,sp),er0
	mov.l	@(LER2:16,sp),er1
	mov.l	@(LER3:16,sp),er2
	jsr	@er4
Y
Yoshinori Sato 已提交
255 256 257 258 259 260
	mov.l	er0,@(LER0:16,sp)		/* save the return value */
	mov.l	sp,er2
	and.w	#0xe000,r2
	mov.b	@((TI_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
	btst	#(TIF_SYSCALL_TRACE & 7),r2l
	beq	2f
261
	jsr	@_do_syscall_trace
Y
Yoshinori Sato 已提交
262
2:
L
Linus Torvalds 已提交
263
#if defined(CONFIG_SYSCALL_PRINT)
264
	jsr	@_syscall_print
L
Linus Torvalds 已提交
265
#endif
Y
Yoshinori Sato 已提交
266 267
	orc	#0x80,ccr
	bra	resume_userspace
L
Linus Torvalds 已提交
268

Y
Yoshinori Sato 已提交
269 270 271 272
badsys:
	mov.l	#-ENOSYS,er0
	mov.l	er0,@(LER0:16,sp)
	bra	resume_userspace
L
Linus Torvalds 已提交
273

Y
Yoshinori Sato 已提交
274 275 276
#if !defined(CONFIG_PREEMPT)
#define resume_kernel restore_all
#endif
L
Linus Torvalds 已提交
277

278
_ret_from_exception:
L
Linus Torvalds 已提交
279 280 281
#if defined(CONFIG_PREEMPT)
	orc	#0x80,ccr
#endif
282
_ret_from_interrupt:
L
Linus Torvalds 已提交
283
	mov.b	@(LCCR+1:16,sp),r0l
Y
Yoshinori Sato 已提交
284 285 286
	btst	#4,r0l
	bne	resume_kernel:8		/* return from kernel */
resume_userspace:
L
Linus Torvalds 已提交
287 288
	andc	#0x7f,ccr
	mov.l	sp,er4
Y
Yoshinori Sato 已提交
289
	and.w	#0xe000,r4		/* er4 <- current thread info */
L
Linus Torvalds 已提交
290 291
	mov.l	@(TI_FLAGS:16,er4),er1
	and.l	#_TIF_WORK_MASK,er1
Y
Yoshinori Sato 已提交
292 293
	beq	restore_all:8
work_pending:
L
Linus Torvalds 已提交
294
	btst	#TIF_NEED_RESCHED,r1l
Y
Yoshinori Sato 已提交
295 296
	bne	work_resched:8
	/* work notifysig */
L
Linus Torvalds 已提交
297
	mov.l	sp,er0
Y
Yoshinori Sato 已提交
298
	subs	#4,er0			/* er0: pt_regs */
299
	jsr	@_do_notify_resume
Y
Yoshinori Sato 已提交
300 301 302
	bra	restore_all:8
work_resched:
	mov.l	sp,er0
303 304
	jsr	@_set_esp0
	jsr	@_schedule
Y
Yoshinori Sato 已提交
305 306 307 308
	bra	resume_userspace:8
restore_all:
	RESTORE_ALL			/* Does RTE */

L
Linus Torvalds 已提交
309
#if defined(CONFIG_PREEMPT)
Y
Yoshinori Sato 已提交
310 311 312 313 314 315 316 317 318 319 320
resume_kernel:
	mov.l	@(TI_PRE_COUNT:16,er4),er0
	bne	restore_all:8
need_resched:
	mov.l	@(TI_FLAGS:16,er4),er0
	btst	#TIF_NEED_RESCHED,r0l
	beq	restore_all:8
	mov.b	@(LCCR+1:16,sp),r0l	/* Interrupt Enabled? */
	bmi	restore_all:8
	mov.l	#PREEMPT_ACTIVE,er0
	mov.l	er0,@(TI_PRE_COUNT:16,er4)
L
Linus Torvalds 已提交
321
	andc	#0x7f,ccr
Y
Yoshinori Sato 已提交
322
	mov.l	sp,er0
323 324
	jsr	@_set_esp0
	jsr	@_schedule
L
Linus Torvalds 已提交
325
	orc	#0x80,ccr
Y
Yoshinori Sato 已提交
326
	bra	need_resched:8
L
Linus Torvalds 已提交
327
#endif
Y
Yoshinori Sato 已提交
328

329
_ret_from_fork:
Y
Yoshinori Sato 已提交
330
	mov.l	er2,er0
331 332
	jsr	@_schedule_tail
	jmp	@_ret_from_exception
L
Linus Torvalds 已提交
333

334
_ret_from_kernel_thread:
A
Al Viro 已提交
335
	mov.l	er2,er0
336
	jsr	@_schedule_tail
A
Al Viro 已提交
337 338 339
	mov.l	@(LER4:16,sp),er0
	mov.l	@(LER5:16,sp),er1
	jsr	@er1
340
	jmp	@_ret_from_exception
A
Al Viro 已提交
341

342
_resume:
L
Linus Torvalds 已提交
343
	/*
Y
Yoshinori Sato 已提交
344 345 346 347 348
	 * Beware - when entering resume, offset of tss is in d1,
	 * prev (the current task) is in a0, next (the new task)
	 * is in a1 and d2.b is non-zero if the mm structure is
	 * shared between the tasks, so don't change these
	 * registers until their contents are no longer needed.
L
Linus Torvalds 已提交
349 350 351 352 353 354 355 356 357
	 */

	/* save sr */
	sub.w	r3,r3
	stc	ccr,r3l
	mov.w	r3,@(THREAD_CCR+2:16,er0)

	/* disable interrupts */
	orc	#0x80,ccr
358
	mov.l	@_sw_usp,er3
L
Linus Torvalds 已提交
359 360
	mov.l	er3,@(THREAD_USP:16,er0)
	mov.l	sp,@(THREAD_KSP:16,er0)
Y
Yoshinori Sato 已提交
361

L
Linus Torvalds 已提交
362 363 364 365
	/* Skip address space switching if they are the same. */
	/* FIXME: what did we hack out of here, this does nothing! */

	mov.l	@(THREAD_USP:16,er1),er0
366
	mov.l	er0,@_sw_usp
L
Linus Torvalds 已提交
367
	mov.l	@(THREAD_KSP:16,er1),sp
Y
Yoshinori Sato 已提交
368

L
Linus Torvalds 已提交
369 370 371 372 373 374
	/* restore status register */
	mov.w	@(THREAD_CCR+2:16,er1),r3

	ldc	r3l,ccr
	rts

375
_trace_break:
Y
Yoshinori Sato 已提交
376
	subs	#4,sp
L
Linus Torvalds 已提交
377 378 379
	SAVE_ALL
	sub.l	er1,er1
	dec.l	#1,er1
Y
Yoshinori Sato 已提交
380
	mov.l	er1,@(LORIG,sp)
L
Linus Torvalds 已提交
381
	mov.l	sp,er0
382 383
	jsr	@_set_esp0
	mov.l	@_sw_usp,er0
L
Linus Torvalds 已提交
384
	mov.l	@er0,er1
Y
Yoshinori Sato 已提交
385 386 387
	mov.w	@(-2:16,er1),r2
	cmp.w	#0x5730,r2
	beq	1f
L
Linus Torvalds 已提交
388
	subs	#2,er1
Y
Yoshinori Sato 已提交
389 390
	mov.l	er1,@er0
1:
L
Linus Torvalds 已提交
391 392
	and.w	#0xff,e1
	mov.l	er1,er0
393 394
	jsr	@_trace_trap
	jmp	@_ret_from_exception
L
Linus Torvalds 已提交
395 396

	.section	.bss
397
_sw_ksp:
Y
Yoshinori Sato 已提交
398
	.space	4
399
_sw_usp:
Y
Yoshinori Sato 已提交
400 401 402
	.space	4

	.end