android_kernel_xiaomi_sm8350/arch/m32r/kernel/entry.S

1007 lines
26 KiB
ArmAsm
Raw Normal View History

/*
* linux/arch/m32r/kernel/entry.S
*
* Copyright (c) 2001, 2002 Hirokazu Takata, Hitoshi Yamamoto, H. Kondo
* Copyright (c) 2003 Hitoshi Yamamoto
* Copyright (c) 2004 Hirokazu Takata <takata at linux-m32r.org>
*
* Taken from i386 version.
* Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
* entry.S contains the system-call and fault low-level handling routines.
* This also contains the timer-interrupt handler, as well as all interrupts
* and faults that can result in a task-switch.
*
* NOTE: This code handles signal-recognition, which happens every time
* after a timer-interrupt and after each system call.
*
* Stack layout in 'ret_from_system_call':
* ptrace needs to have all regs on the stack.
* if the order here is changed, it needs to be
[PATCH] m32r: Fix pt_regs for !COFNIG_ISA_DSP_LEVEL2 target This modification is required to fix debugging function for m32r targets with !CONFIG_ISA_DSP_LEVEL2, by unifying 'struct pt_regs' and 'struct sigcontext' size for all M32R ISA. Some m32r processor core with !CONFIG_ISA_DSP_LEVEL2 configuration has only single accumulator a0 (ex. VDEC2 core, M32102 core, etc.), the others with CONFIG_ISA_DSP_LEVEL2 has two accumulators, a0 and a1. This means there are two variations of thread context. So far, we reduced and changed stackframe size at a syscall for their context size. However, this causes a problem that a GDB for processors with CONFIG_ISA_DSP_LEVEL2 cannot be used for processors with !CONFIG_ISA_DSP_LEVEL2. From the viewpoint of GDB support, we should reduce such variation of stackframe size for simplicity. In this patch, dummy members are added to 'struct pt_regs' and 'struct sigcontext' to adjust their size for !CONFIG_ISA_DSP_LEVEL2. This modification is also a one step for a GDB update in future. Currently, on the m32r, GDB can access process's context by using ptrace functions in a simple way of register by register access. By unifying stackframe size, we have a possibility to make use of ptrace functions of not only a single register access but also block register access, PTRACE_{GETREGS,PUTREGS}. However, for this purpose, we might have to modify stackframe structure some more; for example, PSW (processor status word) register should be pre-processed before pushing to stack at a syscall, and so on. In this case, we must update carefully both kernel and GDB at a time... Signed-off-by: Hayato Fujiwara <fujiwara@linux-m32r.org> Signed-off-by: Hirokazu Takata <takata@linux-m32r.org> Cc: Kei Sakamoto <ksakamot@linux-m32r.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-04-19 01:21:20 -04:00
* updated in fork.c:copy_thread, signal.c:do_signal,
* ptrace.c and ptrace.h
*
* M32Rx/M32R2 M32R
* @(sp) - r4 ditto
* @(0x04,sp) - r5 ditto
* @(0x08,sp) - r6 ditto
* @(0x0c,sp) - *pt_regs ditto
* @(0x10,sp) - r0 ditto
* @(0x14,sp) - r1 ditto
* @(0x18,sp) - r2 ditto
* @(0x1c,sp) - r3 ditto
* @(0x20,sp) - r7 ditto
* @(0x24,sp) - r8 ditto
* @(0x28,sp) - r9 ditto
* @(0x2c,sp) - r10 ditto
* @(0x30,sp) - r11 ditto
* @(0x34,sp) - r12 ditto
* @(0x38,sp) - syscall_nr ditto
* @(0x3c,sp) - acc0h @(0x3c,sp) - acch
* @(0x40,sp) - acc0l @(0x40,sp) - accl
[PATCH] m32r: Fix pt_regs for !COFNIG_ISA_DSP_LEVEL2 target This modification is required to fix debugging function for m32r targets with !CONFIG_ISA_DSP_LEVEL2, by unifying 'struct pt_regs' and 'struct sigcontext' size for all M32R ISA. Some m32r processor core with !CONFIG_ISA_DSP_LEVEL2 configuration has only single accumulator a0 (ex. VDEC2 core, M32102 core, etc.), the others with CONFIG_ISA_DSP_LEVEL2 has two accumulators, a0 and a1. This means there are two variations of thread context. So far, we reduced and changed stackframe size at a syscall for their context size. However, this causes a problem that a GDB for processors with CONFIG_ISA_DSP_LEVEL2 cannot be used for processors with !CONFIG_ISA_DSP_LEVEL2. From the viewpoint of GDB support, we should reduce such variation of stackframe size for simplicity. In this patch, dummy members are added to 'struct pt_regs' and 'struct sigcontext' to adjust their size for !CONFIG_ISA_DSP_LEVEL2. This modification is also a one step for a GDB update in future. Currently, on the m32r, GDB can access process's context by using ptrace functions in a simple way of register by register access. By unifying stackframe size, we have a possibility to make use of ptrace functions of not only a single register access but also block register access, PTRACE_{GETREGS,PUTREGS}. However, for this purpose, we might have to modify stackframe structure some more; for example, PSW (processor status word) register should be pre-processed before pushing to stack at a syscall, and so on. In this case, we must update carefully both kernel and GDB at a time... Signed-off-by: Hayato Fujiwara <fujiwara@linux-m32r.org> Signed-off-by: Hirokazu Takata <takata@linux-m32r.org> Cc: Kei Sakamoto <ksakamot@linux-m32r.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-04-19 01:21:20 -04:00
* @(0x44,sp) - acc1h @(0x44,sp) - dummy_acc1h
* @(0x48,sp) - acc1l @(0x48,sp) - dummy_acc1l
* @(0x4c,sp) - psw ditto
* @(0x50,sp) - bpc ditto
* @(0x54,sp) - bbpsw ditto
* @(0x58,sp) - bbpc ditto
* @(0x5c,sp) - spu (cr3) ditto
* @(0x60,sp) - fp (r13) ditto
* @(0x64,sp) - lr (r14) ditto
* @(0x68,sp) - spi (cr2) ditto
* @(0x6c,sp) - orig_r0 ditto
*/
#include <linux/linkage.h>
#include <asm/irq.h>
#include <asm/unistd.h>
#include <asm/assembler.h>
#include <asm/thread_info.h>
#include <asm/errno.h>
#include <asm/segment.h>
#include <asm/smp.h>
#include <asm/page.h>
#include <asm/m32r.h>
#include <asm/mmu_context.h>
#if !defined(CONFIG_MMU)
#define sys_madvise sys_ni_syscall
#define sys_readahead sys_ni_syscall
#define sys_mprotect sys_ni_syscall
#define sys_msync sys_ni_syscall
#define sys_mlock sys_ni_syscall
#define sys_munlock sys_ni_syscall
#define sys_mlockall sys_ni_syscall
#define sys_munlockall sys_ni_syscall
#define sys_mremap sys_ni_syscall
#define sys_mincore sys_ni_syscall
#define sys_remap_file_pages sys_ni_syscall
#endif /* CONFIG_MMU */
#define R4(reg) @reg
#define R5(reg) @(0x04,reg)
#define R6(reg) @(0x08,reg)
#define PTREGS(reg) @(0x0C,reg)
#define R0(reg) @(0x10,reg)
#define R1(reg) @(0x14,reg)
#define R2(reg) @(0x18,reg)
#define R3(reg) @(0x1C,reg)
#define R7(reg) @(0x20,reg)
#define R8(reg) @(0x24,reg)
#define R9(reg) @(0x28,reg)
#define R10(reg) @(0x2C,reg)
#define R11(reg) @(0x30,reg)
#define R12(reg) @(0x34,reg)
#define SYSCALL_NR(reg) @(0x38,reg)
#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
#define ACC0H(reg) @(0x3C,reg)
#define ACC0L(reg) @(0x40,reg)
#define ACC1H(reg) @(0x44,reg)
#define ACC1L(reg) @(0x48,reg)
[PATCH] m32r: Fix pt_regs for !COFNIG_ISA_DSP_LEVEL2 target This modification is required to fix debugging function for m32r targets with !CONFIG_ISA_DSP_LEVEL2, by unifying 'struct pt_regs' and 'struct sigcontext' size for all M32R ISA. Some m32r processor core with !CONFIG_ISA_DSP_LEVEL2 configuration has only single accumulator a0 (ex. VDEC2 core, M32102 core, etc.), the others with CONFIG_ISA_DSP_LEVEL2 has two accumulators, a0 and a1. This means there are two variations of thread context. So far, we reduced and changed stackframe size at a syscall for their context size. However, this causes a problem that a GDB for processors with CONFIG_ISA_DSP_LEVEL2 cannot be used for processors with !CONFIG_ISA_DSP_LEVEL2. From the viewpoint of GDB support, we should reduce such variation of stackframe size for simplicity. In this patch, dummy members are added to 'struct pt_regs' and 'struct sigcontext' to adjust their size for !CONFIG_ISA_DSP_LEVEL2. This modification is also a one step for a GDB update in future. Currently, on the m32r, GDB can access process's context by using ptrace functions in a simple way of register by register access. By unifying stackframe size, we have a possibility to make use of ptrace functions of not only a single register access but also block register access, PTRACE_{GETREGS,PUTREGS}. However, for this purpose, we might have to modify stackframe structure some more; for example, PSW (processor status word) register should be pre-processed before pushing to stack at a syscall, and so on. In this case, we must update carefully both kernel and GDB at a time... Signed-off-by: Hayato Fujiwara <fujiwara@linux-m32r.org> Signed-off-by: Hirokazu Takata <takata@linux-m32r.org> Cc: Kei Sakamoto <ksakamot@linux-m32r.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-04-19 01:21:20 -04:00
#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
#define ACCH(reg) @(0x3C,reg)
#define ACCL(reg) @(0x40,reg)
#else
#error unknown isa configuration
#endif
#define PSW(reg) @(0x4C,reg)
#define BPC(reg) @(0x50,reg)
#define BBPSW(reg) @(0x54,reg)
#define BBPC(reg) @(0x58,reg)
#define SPU(reg) @(0x5C,reg)
#define FP(reg) @(0x60,reg) /* FP = R13 */
#define LR(reg) @(0x64,reg)
#define SP(reg) @(0x68,reg)
#define ORIG_R0(reg) @(0x6C,reg)
CF_MASK = 0x00000001
TF_MASK = 0x00000100
IF_MASK = 0x00000200
DF_MASK = 0x00000400
NT_MASK = 0x00004000
VM_MASK = 0x00020000
#ifdef CONFIG_PREEMPT
#define preempt_stop(x) CLI(x)
#else
#define preempt_stop(x)
#define resume_kernel restore_all
#endif
ENTRY(ret_from_fork)
pop r0
bl schedule_tail
GET_THREAD_INFO(r8)
bra syscall_exit
/*
* Return to user mode is not as complex as all this looks,
* but we want the default path for a system call return to
* go as quickly as possible which is why some of this is
* less clear than it otherwise should be.
*/
; userspace resumption stub bypassing syscall exit tracing
ALIGN
ret_from_exception:
preempt_stop(r4)
ret_from_intr:
ld r4, PSW(sp)
#ifdef CONFIG_ISA_M32R2
and3 r4, r4, #0x8800 ; check BSM and BPM bits
#else
and3 r4, r4, #0x8000 ; check BSM bit
#endif
beqz r4, resume_kernel
ENTRY(resume_userspace)
CLI(r4) ; make sure we don't miss an interrupt
; setting need_resched or sigpending
; between sampling and the iret
GET_THREAD_INFO(r8)
ld r9, @(TI_FLAGS, r8)
and3 r4, r9, #_TIF_WORK_MASK ; is there any work to be done on
; int/exception return?
bnez r4, work_pending
bra restore_all
#ifdef CONFIG_PREEMPT
ENTRY(resume_kernel)
GET_THREAD_INFO(r8)
ld r9, @(TI_PRE_COUNT, r8) ; non-zero preempt_count ?
bnez r9, restore_all
need_resched:
ld r9, @(TI_FLAGS, r8) ; need_resched set ?
and3 r4, r9, #_TIF_NEED_RESCHED
beqz r4, restore_all
ld r4, PSW(sp) ; interrupts off (exception path) ?
and3 r4, r4, #0x4000
beqz r4, restore_all
LDIMM (r4, PREEMPT_ACTIVE)
st r4, @(TI_PRE_COUNT, r8)
STI(r4)
bl schedule
ldi r4, #0
st r4, @(TI_PRE_COUNT, r8)
CLI(r4)
bra need_resched
#endif
; system call handler stub
ENTRY(system_call)
SWITCH_TO_KERNEL_STACK
SAVE_ALL
STI(r4) ; Enable interrupt
st sp, PTREGS(sp) ; implicit pt_regs parameter
cmpui r7, #NR_syscalls
bnc syscall_badsys
st r7, SYSCALL_NR(sp) ; syscall_nr
; system call tracing in operation
GET_THREAD_INFO(r8)
ld r9, @(TI_FLAGS, r8)
and3 r4, r9, #_TIF_SYSCALL_TRACE
bnez r4, syscall_trace_entry
syscall_call:
slli r7, #2 ; table jump for the system call
LDIMM (r4, sys_call_table)
add r7, r4
ld r7, @r7
jl r7 ; execute system call
st r0, R0(sp) ; save the return value
syscall_exit:
CLI(r4) ; make sure we don't miss an interrupt
; setting need_resched or sigpending
; between sampling and the iret
ld r9, @(TI_FLAGS, r8)
and3 r4, r9, #_TIF_ALLWORK_MASK ; current->work
bnez r4, syscall_exit_work
restore_all:
RESTORE_ALL
# perform work that needs to be done immediately before resumption
[PATCH] m32r: Fix pt_regs for !COFNIG_ISA_DSP_LEVEL2 target This modification is required to fix debugging function for m32r targets with !CONFIG_ISA_DSP_LEVEL2, by unifying 'struct pt_regs' and 'struct sigcontext' size for all M32R ISA. Some m32r processor core with !CONFIG_ISA_DSP_LEVEL2 configuration has only single accumulator a0 (ex. VDEC2 core, M32102 core, etc.), the others with CONFIG_ISA_DSP_LEVEL2 has two accumulators, a0 and a1. This means there are two variations of thread context. So far, we reduced and changed stackframe size at a syscall for their context size. However, this causes a problem that a GDB for processors with CONFIG_ISA_DSP_LEVEL2 cannot be used for processors with !CONFIG_ISA_DSP_LEVEL2. From the viewpoint of GDB support, we should reduce such variation of stackframe size for simplicity. In this patch, dummy members are added to 'struct pt_regs' and 'struct sigcontext' to adjust their size for !CONFIG_ISA_DSP_LEVEL2. This modification is also a one step for a GDB update in future. Currently, on the m32r, GDB can access process's context by using ptrace functions in a simple way of register by register access. By unifying stackframe size, we have a possibility to make use of ptrace functions of not only a single register access but also block register access, PTRACE_{GETREGS,PUTREGS}. However, for this purpose, we might have to modify stackframe structure some more; for example, PSW (processor status word) register should be pre-processed before pushing to stack at a syscall, and so on. In this case, we must update carefully both kernel and GDB at a time... Signed-off-by: Hayato Fujiwara <fujiwara@linux-m32r.org> Signed-off-by: Hirokazu Takata <takata@linux-m32r.org> Cc: Kei Sakamoto <ksakamot@linux-m32r.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-04-19 01:21:20 -04:00
# r9 : flags
ALIGN
work_pending:
and3 r4, r9, #_TIF_NEED_RESCHED
beqz r4, work_notifysig
work_resched:
bl schedule
CLI(r4) ; make sure we don't miss an interrupt
; setting need_resched or sigpending
; between sampling and the iret
ld r9, @(TI_FLAGS, r8)
and3 r4, r9, #_TIF_WORK_MASK ; is there any work to be done other
; than syscall tracing?
beqz r4, restore_all
and3 r4, r4, #_TIF_NEED_RESCHED
bnez r4, work_resched
work_notifysig: ; deal with pending signals and
; notify-resume requests
mv r0, sp ; arg1 : struct pt_regs *regs
ldi r1, #0 ; arg2 : sigset_t *oldset
mv r2, r9 ; arg3 : __u32 thread_info_flags
bl do_notify_resume
bra restore_all
; perform syscall exit tracing
ALIGN
syscall_trace_entry:
ldi r4, #-ENOSYS
st r4, R0(sp)
bl do_syscall_trace
ld r0, ORIG_R0(sp)
ld r1, R1(sp)
ld r2, R2(sp)
ld r3, R3(sp)
ld r4, R4(sp)
ld r5, R5(sp)
ld r6, R6(sp)
ld r7, SYSCALL_NR(sp)
cmpui r7, #NR_syscalls
bc syscall_call
bra syscall_exit
; perform syscall exit tracing
ALIGN
syscall_exit_work:
ld r9, @(TI_FLAGS, r8)
and3 r4, r9, #_TIF_SYSCALL_TRACE
beqz r4, work_pending
STI(r4) ; could let do_syscall_trace() call
; schedule() instead
bl do_syscall_trace
bra resume_userspace
ALIGN
syscall_fault:
SAVE_ALL
GET_THREAD_INFO(r8)
ldi r4, #-EFAULT
st r4, R0(sp)
bra resume_userspace
ALIGN
syscall_badsys:
ldi r4, #-ENOSYS
st r4, R0(sp)
bra resume_userspace
.global eit_vector
.equ ei_vec_table, eit_vector + 0x0200
/*
* EI handler routine
*/
ENTRY(ei_handler)
#if defined(CONFIG_CHIP_M32700)
SWITCH_TO_KERNEL_STACK
; WORKAROUND: force to clear SM bit and use the kernel stack (SPI).
#endif
SAVE_ALL
mv r1, sp ; arg1(regs)
#if defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_XNUX2) \
|| defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \
|| defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
; GET_ICU_STATUS;
seth r0, #shigh(M32R_ICU_ISTS_ADDR)
ld r0, @(low(M32R_ICU_ISTS_ADDR),r0)
push r0
#if defined(CONFIG_SMP)
/*
* If IRQ == 0 --> Nothing to do, Not write IMASK
* If IRQ == IPI --> Do IPI handler, Not write IMASK
* If IRQ != 0, IPI --> Do do_IRQ(), Write IMASK
*/
slli r0, #4
srli r0, #24 ; r0(irq_num<<2)
;; IRQ exist check
#if defined(CONFIG_CHIP_M32700)
/* WORKAROUND: IMASK bug M32700-TS1, TS2 chip. */
beqz r0, 3f ; if (!irq_num) goto exit
#else
beqz r0, 1f ; if (!irq_num) goto exit
#endif /* WORKAROUND */
;; IPI check
cmpi r0, #(M32R_IRQ_IPI0<<2) ; ISN < IPI0 check
bc 2f
cmpi r0, #((M32R_IRQ_IPI7+1)<<2) ; ISN > IPI7 check
bnc 2f
LDIMM (r2, ei_vec_table)
add r2, r0
ld r2, @r2
beqz r2, 1f ; if (no IPI handler) goto exit
mv r0, r1 ; arg0(regs)
jl r2
.fillinsn
1:
addi sp, #4
bra ret_to_intr
#if defined(CONFIG_CHIP_M32700)
/* WORKAROUND: IMASK bug M32700-TS1, TS2 chip. */
.fillinsn
3:
ld24 r14, #0x00070000
seth r0, #shigh(M32R_ICU_IMASK_ADDR)
st r14, @(low(M32R_ICU_IMASK_ADDR), r0)
addi sp, #4
bra ret_to_intr
#endif /* WORKAROUND */
;; do_IRQ
.fillinsn
2:
srli r0, #2
#if defined(CONFIG_PLAT_USRV)
add3 r2, r0, #-(M32R_IRQ_INT1) ; INT1# interrupt
bnez r2, 9f
; read ICU status register of PLD
seth r0, #high(PLD_ICUISTS)
or3 r0, r0, #low(PLD_ICUISTS)
lduh r0, @r0
slli r0, #21
srli r0, #27 ; ISN
addi r0, #(M32700UT_PLD_IRQ_BASE)
.fillinsn
9:
#elif defined(CONFIG_PLAT_M32700UT)
add3 r2, r0, #-(M32R_IRQ_INT1) ; INT1# interrupt
bnez r2, check_int0
; read ICU status register of PLD
seth r0, #high(PLD_ICUISTS)
or3 r0, r0, #low(PLD_ICUISTS)
lduh r0, @r0
slli r0, #21
srli r0, #27 ; ISN
addi r0, #(M32700UT_PLD_IRQ_BASE)
bra check_end
.fillinsn
check_int0:
add3 r2, r0, #-(M32R_IRQ_INT0) ; INT0# interrupt
bnez r2, check_int2
; read ICU status of LAN-board
seth r0, #high(M32700UT_LAN_ICUISTS)
or3 r0, r0, #low(M32700UT_LAN_ICUISTS)
lduh r0, @r0
slli r0, #21
srli r0, #27 ; ISN
add3 r0, r0, #(M32700UT_LAN_PLD_IRQ_BASE)
bra check_end
.fillinsn
check_int2:
add3 r2, r0, #-(M32R_IRQ_INT2) ; INT2# interrupt
bnez r2, check_end
; read ICU status of LCD-board
seth r0, #high(M32700UT_LCD_ICUISTS)
or3 r0, r0, #low(M32700UT_LCD_ICUISTS)
lduh r0, @r0
slli r0, #21
srli r0, #27 ; ISN
add3 r0, r0, #(M32700UT_LCD_PLD_IRQ_BASE)
bra check_end
.fillinsn
check_end:
#elif defined(CONFIG_PLAT_OPSPUT)
add3 r2, r0, #-(M32R_IRQ_INT1) ; INT1# interrupt
bnez r2, check_int0
; read ICU status register of PLD
seth r0, #high(PLD_ICUISTS)
or3 r0, r0, #low(PLD_ICUISTS)
lduh r0, @r0
slli r0, #21
srli r0, #27 ; ISN
addi r0, #(OPSPUT_PLD_IRQ_BASE)
bra check_end
.fillinsn
check_int0:
add3 r2, r0, #-(M32R_IRQ_INT0) ; INT0# interrupt
bnez r2, check_int2
; read ICU status of LAN-board
seth r0, #high(OPSPUT_LAN_ICUISTS)
or3 r0, r0, #low(OPSPUT_LAN_ICUISTS)
lduh r0, @r0
slli r0, #21
srli r0, #27 ; ISN
add3 r0, r0, #(OPSPUT_LAN_PLD_IRQ_BASE)
bra check_end
.fillinsn
check_int2:
add3 r2, r0, #-(M32R_IRQ_INT2) ; INT2# interrupt
bnez r2, check_end
; read ICU status of LCD-board
seth r0, #high(OPSPUT_LCD_ICUISTS)
or3 r0, r0, #low(OPSPUT_LCD_ICUISTS)
lduh r0, @r0
slli r0, #21
srli r0, #27 ; ISN
add3 r0, r0, #(OPSPUT_LCD_PLD_IRQ_BASE)
bra check_end
.fillinsn
check_end:
#endif /* CONFIG_PLAT_OPSPUT */
bl do_IRQ ; r0(irq), r1(regs)
#else /* not CONFIG_SMP */
srli r0, #22 ; r0(irq)
#if defined(CONFIG_PLAT_USRV)
add3 r2, r0, #-(M32R_IRQ_INT1) ; INT1# interrupt
bnez r2, 1f
; read ICU status register of PLD
seth r0, #high(PLD_ICUISTS)
or3 r0, r0, #low(PLD_ICUISTS)
lduh r0, @r0
slli r0, #21
srli r0, #27 ; ISN
addi r0, #(M32700UT_PLD_IRQ_BASE)
.fillinsn
1:
#elif defined(CONFIG_PLAT_M32700UT)
add3 r2, r0, #-(M32R_IRQ_INT1) ; INT1# interrupt
bnez r2, check_int0
; read ICU status register of PLD
seth r0, #high(PLD_ICUISTS)
or3 r0, r0, #low(PLD_ICUISTS)
lduh r0, @r0
slli r0, #21
srli r0, #27 ; ISN
addi r0, #(M32700UT_PLD_IRQ_BASE)
bra check_end
.fillinsn
check_int0:
add3 r2, r0, #-(M32R_IRQ_INT0) ; INT0# interrupt
bnez r2, check_int2
; read ICU status of LAN-board
seth r0, #high(M32700UT_LAN_ICUISTS)
or3 r0, r0, #low(M32700UT_LAN_ICUISTS)
lduh r0, @r0
slli r0, #21
srli r0, #27 ; ISN
add3 r0, r0, #(M32700UT_LAN_PLD_IRQ_BASE)
bra check_end
.fillinsn
check_int2:
add3 r2, r0, #-(M32R_IRQ_INT2) ; INT2# interrupt
bnez r2, check_end
; read ICU status of LCD-board
seth r0, #high(M32700UT_LCD_ICUISTS)
or3 r0, r0, #low(M32700UT_LCD_ICUISTS)
lduh r0, @r0
slli r0, #21
srli r0, #27 ; ISN
add3 r0, r0, #(M32700UT_LCD_PLD_IRQ_BASE)
bra check_end
.fillinsn
check_end:
#elif defined(CONFIG_PLAT_OPSPUT)
add3 r2, r0, #-(M32R_IRQ_INT1) ; INT1# interrupt
bnez r2, check_int0
; read ICU status register of PLD
seth r0, #high(PLD_ICUISTS)
or3 r0, r0, #low(PLD_ICUISTS)
lduh r0, @r0
slli r0, #21
srli r0, #27 ; ISN
addi r0, #(OPSPUT_PLD_IRQ_BASE)
bra check_end
.fillinsn
check_int0:
add3 r2, r0, #-(M32R_IRQ_INT0) ; INT0# interrupt
bnez r2, check_int2
; read ICU status of LAN-board
seth r0, #high(OPSPUT_LAN_ICUISTS)
or3 r0, r0, #low(OPSPUT_LAN_ICUISTS)
lduh r0, @r0
slli r0, #21
srli r0, #27 ; ISN
add3 r0, r0, #(OPSPUT_LAN_PLD_IRQ_BASE)
bra check_end
.fillinsn
check_int2:
add3 r2, r0, #-(M32R_IRQ_INT2) ; INT2# interrupt
bnez r2, check_end
; read ICU status of LCD-board
seth r0, #high(OPSPUT_LCD_ICUISTS)
or3 r0, r0, #low(OPSPUT_LCD_ICUISTS)
lduh r0, @r0
slli r0, #21
srli r0, #27 ; ISN
add3 r0, r0, #(OPSPUT_LCD_PLD_IRQ_BASE)
bra check_end
.fillinsn
check_end:
#elif defined(CONFIG_PLAT_M32104UT)
add3 r2, r0, #-(M32R_IRQ_INT1) ; INT1# interrupt
bnez r2, check_end
; read ICU status register of PLD
seth r0, #high(PLD_ICUISTS)
or3 r0, r0, #low(PLD_ICUISTS)
lduh r0, @r0
slli r0, #21
srli r0, #27 ; ISN
addi r0, #(M32104UT_PLD_IRQ_BASE)
bra check_end
.fillinsn
check_end:
#endif /* CONFIG_PLAT_M32104UT */
bl do_IRQ
#endif /* CONFIG_SMP */
pop r14
seth r0, #shigh(M32R_ICU_IMASK_ADDR)
st r14, @(low(M32R_ICU_IMASK_ADDR),r0)
#else
#error no chip configuration
#endif
ret_to_intr:
bra ret_from_intr
/*
* Default EIT handler
*/
ALIGN
int_msg:
.asciz "Unknown interrupt\n"
.byte 0
ENTRY(default_eit_handler)
push r0
mvfc r0, psw
push r1
push r2
push r3
push r0
LDIMM (r0, __KERNEL_DS)
mv r0, r1
mv r0, r2
LDIMM (r0, int_msg)
bl printk
pop r0
pop r3
pop r2
pop r1
mvtc r0, psw
pop r0
infinit:
bra infinit
#ifdef CONFIG_MMU
/*
* Access Exception handler
*/
ENTRY(ace_handler)
SWITCH_TO_KERNEL_STACK
SAVE_ALL
seth r2, #shigh(MMU_REG_BASE) /* Check status register */
ld r4, @(low(MESTS_offset),r2)
st r4, @(low(MESTS_offset),r2)
srl3 r1, r4, #4
#ifdef CONFIG_CHIP_M32700
and3 r1, r1, #0x0000ffff
; WORKAROUND: ignore TME bit for the M32700(TS1).
#endif /* CONFIG_CHIP_M32700 */
beqz r1, inst
oprand:
ld r2, @(low(MDEVA_offset),r2) ; set address
srli r2, #12
slli r2, #12
srli r1, #1
bra 1f
inst:
and3 r1, r4, #2
srli r1, #1
or3 r1, r1, #8
mvfc r2, bpc ; set address
.fillinsn
1:
mvfc r3, psw
mv r0, sp
and3 r3, r3, 0x800
srli r3, #9
or r1, r3
/*
* do_page_fault():
* r0 : struct pt_regs *regs
* r1 : unsigned long error-code
* r2 : unsigned long address
* error-code:
* +------+------+------+------+
* | bit3 | bit2 | bit1 | bit0 |
* +------+------+------+------+
* bit 3 == 0:means data, 1:means instruction
* bit 2 == 0:means kernel, 1:means user-mode
* bit 1 == 0:means read, 1:means write
* bit 0 == 0:means no page found 1:means protection fault
*
*/
bl do_page_fault
bra ret_from_intr
#endif /* CONFIG_MMU */
ENTRY(alignment_check)
/* void alignment_check(int error_code) */
SWITCH_TO_KERNEL_STACK
SAVE_ALL
ldi r1, #0x30 ; error_code
mv r0, sp ; pt_regs
bl do_alignment_check
error_code:
bra ret_from_exception
ENTRY(rie_handler)
/* void rie_handler(int error_code) */
SWITCH_TO_KERNEL_STACK
SAVE_ALL
ldi r1, #0x20 ; error_code
mv r0, sp ; pt_regs
bl do_rie_handler
bra error_code
ENTRY(pie_handler)
/* void pie_handler(int error_code) */
SWITCH_TO_KERNEL_STACK
SAVE_ALL
ldi r1, #0 ; error_code ; FIXME
mv r0, sp ; pt_regs
bl do_pie_handler
bra error_code
ENTRY(debug_trap)
.global withdraw_debug_trap
/* void debug_trap(void) */
SWITCH_TO_KERNEL_STACK
SAVE_ALL
mv r0, sp ; pt_regs
bl withdraw_debug_trap
ldi r1, #0 ; error_code
mv r0, sp ; pt_regs
bl do_debug_trap
bra error_code
ENTRY(ill_trap)
/* void ill_trap(void) */
SWITCH_TO_KERNEL_STACK
SAVE_ALL
ldi r1, #0 ; error_code ; FIXME
mv r0, sp ; pt_regs
bl do_ill_trap
bra error_code
/* Cache flushing handler */
ENTRY(cache_flushing_handler)
.global _flush_cache_all
/* void _flush_cache_all(void); */
SWITCH_TO_KERNEL_STACK
push r0
push r1
push r2
push r3
push r4
push r5
push r6
push r7
push lr
bl _flush_cache_all
pop lr
pop r7
pop r6
pop r5
pop r4
pop r3
pop r2
pop r1
pop r0
rte
.data
ENTRY(sys_call_table)
.long sys_restart_syscall /* 0 - old "setup()" system call*/
.long sys_exit
.long sys_fork
.long sys_read
.long sys_write
.long sys_open /* 5 */
.long sys_close
.long sys_waitpid
.long sys_creat
.long sys_link
.long sys_unlink /* 10 */
.long sys_execve
.long sys_chdir
.long sys_time
.long sys_mknod
.long sys_chmod /* 15 */
.long sys_ni_syscall /* lchown16 syscall holder */
.long sys_ni_syscall /* old break syscall holder */
.long sys_ni_syscall /* old stat syscall holder */
.long sys_lseek
.long sys_getpid /* 20 */
.long sys_mount
.long sys_oldumount
.long sys_ni_syscall /* setuid16 syscall holder */
.long sys_ni_syscall /* getuid16 syscall holder */
.long sys_stime /* 25 */
.long sys_ptrace
.long sys_alarm
.long sys_ni_syscall /* old fstat syscall holder */
.long sys_pause
.long sys_utime /* 30 */
.long sys_ni_syscall /* old stty syscall holder */
.long sys_cachectl /* for M32R */ /* old gtty syscall holder */
.long sys_access
.long sys_ni_syscall /* nice syscall holder */
.long sys_ni_syscall /* 35 - old ftime syscall holder */
.long sys_sync
.long sys_kill
.long sys_rename
.long sys_mkdir
.long sys_rmdir /* 40 */
.long sys_dup
.long sys_pipe
.long sys_times
.long sys_ni_syscall /* old prof syscall holder */
.long sys_brk /* 45 */
.long sys_ni_syscall /* setgid16 syscall holder */
.long sys_getgid /* will be unused */
.long sys_ni_syscall /* signal syscall holder */
.long sys_ni_syscall /* geteuid16 syscall holder */
.long sys_ni_syscall /* 50 - getegid16 syscall holder */
.long sys_acct
.long sys_umount /* recycled never used phys() */
.long sys_ni_syscall /* old lock syscall holder */
.long sys_ioctl
.long sys_fcntl /* 55 - will be unused */
.long sys_ni_syscall /* mpx syscall holder */
.long sys_setpgid
.long sys_ni_syscall /* old ulimit syscall holder */
.long sys_ni_syscall /* sys_olduname */
.long sys_umask /* 60 */
.long sys_chroot
.long sys_ustat
.long sys_dup2
.long sys_getppid
.long sys_getpgrp /* 65 */
.long sys_setsid
.long sys_ni_syscall /* sigaction syscall holder */
.long sys_ni_syscall /* sgetmask syscall holder */
.long sys_ni_syscall /* ssetmask syscall holder */
.long sys_ni_syscall /* 70 - setreuid16 syscall holder */
.long sys_ni_syscall /* setregid16 syscall holder */
.long sys_ni_syscall /* sigsuspend syscall holder */
.long sys_ni_syscall /* sigpending syscall holder */
.long sys_sethostname
.long sys_setrlimit /* 75 */
.long sys_getrlimit/*will be unused*/
.long sys_getrusage
.long sys_gettimeofday
.long sys_settimeofday
.long sys_ni_syscall /* 80 - getgroups16 syscall holder */
.long sys_ni_syscall /* setgroups16 syscall holder */
.long sys_ni_syscall /* sys_oldselect */
.long sys_symlink
.long sys_ni_syscall /* old lstat syscall holder */
.long sys_readlink /* 85 */
.long sys_uselib
.long sys_swapon
.long sys_reboot
.long sys_ni_syscall /* readdir syscall holder */
.long sys_ni_syscall /* 90 - old_mmap syscall holder */
.long sys_munmap
.long sys_truncate
.long sys_ftruncate
.long sys_fchmod
.long sys_ni_syscall /* 95 - fchwon16 syscall holder */
.long sys_getpriority
.long sys_setpriority
.long sys_ni_syscall /* old profil syscall holder */
.long sys_statfs
.long sys_fstatfs /* 100 */
.long sys_ni_syscall /* ioperm syscall holder */
.long sys_socketcall
.long sys_syslog
.long sys_setitimer
.long sys_getitimer /* 105 */
.long sys_newstat
.long sys_newlstat
.long sys_newfstat
.long sys_ni_syscall /* old uname syscall holder */
.long sys_ni_syscall /* 110 - iopl syscall holder */
.long sys_vhangup
.long sys_ni_syscall /* idle syscall holder */
.long sys_ni_syscall /* vm86old syscall holder */
.long sys_wait4
.long sys_swapoff /* 115 */
.long sys_sysinfo
.long sys_ipc
.long sys_fsync
.long sys_ni_syscall /* sigreturn syscall holder */
.long sys_clone /* 120 */
.long sys_setdomainname
.long sys_newuname
.long sys_ni_syscall /* modify_ldt syscall holder */
.long sys_adjtimex
.long sys_mprotect /* 125 */
.long sys_ni_syscall /* sigprocmask syscall holder */
.long sys_ni_syscall /* create_module syscall holder */
.long sys_init_module
.long sys_delete_module
.long sys_ni_syscall /* 130 - get_kernel_syms */
.long sys_quotactl
.long sys_getpgid
.long sys_fchdir
.long sys_bdflush
.long sys_sysfs /* 135 */
.long sys_personality
.long sys_ni_syscall /* afs_syscall syscall holder */
.long sys_ni_syscall /* setfsuid16 syscall holder */
.long sys_ni_syscall /* setfsgid16 syscall holder */
.long sys_llseek /* 140 */
.long sys_getdents
.long sys_select
.long sys_flock
.long sys_msync
.long sys_readv /* 145 */
.long sys_writev
.long sys_getsid
.long sys_fdatasync
.long sys_sysctl
.long sys_mlock /* 150 */
.long sys_munlock
.long sys_mlockall
.long sys_munlockall
.long sys_sched_setparam
.long sys_sched_getparam /* 155 */
.long sys_sched_setscheduler
.long sys_sched_getscheduler
.long sys_sched_yield
.long sys_sched_get_priority_max
.long sys_sched_get_priority_min /* 160 */
.long sys_sched_rr_get_interval
.long sys_nanosleep
.long sys_mremap
.long sys_ni_syscall /* setresuid16 syscall holder */
.long sys_ni_syscall /* 165 - getresuid16 syscall holder */
.long sys_tas /* vm86 syscall holder */
.long sys_ni_syscall /* query_module syscall holder */
.long sys_poll
.long sys_nfsservctl
.long sys_setresgid /* 170 */
.long sys_getresgid
.long sys_prctl
.long sys_rt_sigreturn
.long sys_rt_sigaction
.long sys_rt_sigprocmask /* 175 */
.long sys_rt_sigpending
.long sys_rt_sigtimedwait
.long sys_rt_sigqueueinfo
.long sys_rt_sigsuspend
.long sys_pread64 /* 180 */
.long sys_pwrite64
.long sys_ni_syscall /* chown16 syscall holder */
.long sys_getcwd
.long sys_capget
.long sys_capset /* 185 */
.long sys_sigaltstack
.long sys_sendfile
.long sys_ni_syscall /* streams1 */
.long sys_ni_syscall /* streams2 */
.long sys_vfork /* 190 */
.long sys_getrlimit
.long sys_mmap2
.long sys_truncate64
.long sys_ftruncate64
.long sys_stat64 /* 195 */
.long sys_lstat64
.long sys_fstat64
.long sys_lchown
.long sys_getuid
.long sys_getgid /* 200 */
.long sys_geteuid
.long sys_getegid
.long sys_setreuid
.long sys_setregid
.long sys_getgroups /* 205 */
.long sys_setgroups
.long sys_fchown
.long sys_setresuid
.long sys_getresuid
.long sys_setresgid /* 210 */
.long sys_getresgid
.long sys_chown
.long sys_setuid
.long sys_setgid
.long sys_setfsuid /* 215 */
.long sys_setfsgid
.long sys_pivot_root
.long sys_mincore
.long sys_madvise
.long sys_getdents64 /* 220 */
.long sys_fcntl64
.long sys_ni_syscall /* reserved for TUX */
.long sys_ni_syscall /* Reserved for Security */
.long sys_gettid
.long sys_readahead /* 225 */
.long sys_setxattr
.long sys_lsetxattr
.long sys_fsetxattr
.long sys_getxattr
.long sys_lgetxattr /* 230 */
.long sys_fgetxattr
.long sys_listxattr
.long sys_llistxattr
.long sys_flistxattr
.long sys_removexattr /* 235 */
.long sys_lremovexattr
.long sys_fremovexattr
.long sys_tkill
.long sys_sendfile64
.long sys_futex /* 240 */
.long sys_sched_setaffinity
.long sys_sched_getaffinity
.long sys_ni_syscall /* reserved for "set_thread_area" system call */
.long sys_ni_syscall /* reserved for "get_thread_area" system call */
.long sys_io_setup /* 245 */
.long sys_io_destroy
.long sys_io_getevents
.long sys_io_submit
.long sys_io_cancel
.long sys_fadvise64 /* 250 */
.long sys_ni_syscall
.long sys_exit_group
.long sys_lookup_dcookie
.long sys_epoll_create
.long sys_epoll_ctl /* 255 */
.long sys_epoll_wait
.long sys_remap_file_pages
.long sys_set_tid_address
.long sys_timer_create
.long sys_timer_settime /* 260 */
.long sys_timer_gettime
.long sys_timer_getoverrun
.long sys_timer_delete
.long sys_clock_settime
.long sys_clock_gettime /* 265 */
.long sys_clock_getres
.long sys_clock_nanosleep
.long sys_statfs64
.long sys_fstatfs64
.long sys_tgkill /* 270 */
.long sys_utimes
.long sys_fadvise64_64
.long sys_ni_syscall /* Reserved for sys_vserver */
.long sys_ni_syscall /* Reserved for sys_mbind */
.long sys_ni_syscall /* Reserved for sys_get_mempolicy */
.long sys_ni_syscall /* Reserved for sys_set_mempolicy */
.long sys_mq_open
.long sys_mq_unlink
.long sys_mq_timedsend
.long sys_mq_timedreceive /* 280 */
.long sys_mq_notify
.long sys_mq_getsetattr
.long sys_ni_syscall /* reserved for kexec */
.long sys_waitid
syscall_table_size=(.-sys_call_table)