csky: Exception handling and mm-fault
This patch adds exception handling code, cpuinfo and mm-fault code. Signed-off-by: Guo Ren <ren_guo@c-sky.com> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
79
arch/csky/kernel/cpu-probe.c
Normal file
79
arch/csky/kernel/cpu-probe.c
Normal file
@@ -0,0 +1,79 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/memblock.h>
|
||||
|
||||
#include <abi/reg_ops.h>
|
||||
|
||||
static void percpu_print(void *arg)
|
||||
{
|
||||
struct seq_file *m = (struct seq_file *)arg;
|
||||
unsigned int cur, next, i;
|
||||
|
||||
seq_printf(m, "processor : %d\n", smp_processor_id());
|
||||
seq_printf(m, "C-SKY CPU model : %s\n", CSKYCPU_DEF_NAME);
|
||||
|
||||
/* read processor id, max is 100 */
|
||||
cur = mfcr("cr13");
|
||||
for (i = 0; i < 100; i++) {
|
||||
seq_printf(m, "product info[%d] : 0x%08x\n", i, cur);
|
||||
|
||||
next = mfcr("cr13");
|
||||
|
||||
/* some CPU only has one id reg */
|
||||
if (cur == next)
|
||||
break;
|
||||
|
||||
cur = next;
|
||||
|
||||
/* cpid index is 31-28, reset */
|
||||
if (!(next >> 28)) {
|
||||
while ((mfcr("cr13") >> 28) != i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* CPU feature regs, setup by bootloader or gdbinit */
|
||||
seq_printf(m, "hint (CPU funcs): 0x%08x\n", mfcr_hint());
|
||||
seq_printf(m, "ccr (L1C & MMU): 0x%08x\n", mfcr("cr18"));
|
||||
seq_printf(m, "ccr2 (L2C) : 0x%08x\n", mfcr_ccr2());
|
||||
seq_printf(m, "\n");
|
||||
}
|
||||
|
||||
static int c_show(struct seq_file *m, void *v)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
for_each_online_cpu(cpu)
|
||||
smp_call_function_single(cpu, percpu_print, m, true);
|
||||
|
||||
#ifdef CSKY_ARCH_VERSION
|
||||
seq_printf(m, "arch-version : %s\n", CSKY_ARCH_VERSION);
|
||||
seq_printf(m, "\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *c_start(struct seq_file *m, loff_t *pos)
|
||||
{
|
||||
return *pos < 1 ? (void *)1 : NULL;
|
||||
}
|
||||
|
||||
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
|
||||
{
|
||||
++*pos;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void c_stop(struct seq_file *m, void *v) {}
|
||||
|
||||
const struct seq_operations cpuinfo_op = {
|
||||
.start = c_start,
|
||||
.next = c_next,
|
||||
.stop = c_stop,
|
||||
.show = c_show,
|
||||
};
|
396
arch/csky/kernel/entry.S
Normal file
396
arch/csky/kernel/entry.S
Normal file
@@ -0,0 +1,396 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <abi/entry.h>
|
||||
#include <abi/pgtable-bits.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <linux/threads.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/thread_info.h>
|
||||
|
||||
#define PTE_INDX_MSK 0xffc
|
||||
#define PTE_INDX_SHIFT 10
|
||||
#define _PGDIR_SHIFT 22
|
||||
|
||||
.macro tlbop_begin name, val0, val1, val2
|
||||
ENTRY(csky_\name)
|
||||
mtcr a3, ss2
|
||||
mtcr r6, ss3
|
||||
mtcr a2, ss4
|
||||
|
||||
RD_PGDR r6
|
||||
RD_MEH a3
|
||||
#ifdef CONFIG_CPU_HAS_TLBI
|
||||
tlbi.vaas a3
|
||||
sync.is
|
||||
|
||||
btsti a3, 31
|
||||
bf 1f
|
||||
RD_PGDR_K r6
|
||||
1:
|
||||
#else
|
||||
bgeni a2, 31
|
||||
WR_MCIR a2
|
||||
bgeni a2, 25
|
||||
WR_MCIR a2
|
||||
#endif
|
||||
bclri r6, 0
|
||||
lrw a2, PHYS_OFFSET
|
||||
subu r6, a2
|
||||
bseti r6, 31
|
||||
|
||||
mov a2, a3
|
||||
lsri a2, _PGDIR_SHIFT
|
||||
lsli a2, 2
|
||||
addu r6, a2
|
||||
ldw r6, (r6)
|
||||
|
||||
lrw a2, PHYS_OFFSET
|
||||
subu r6, a2
|
||||
bseti r6, 31
|
||||
|
||||
lsri a3, PTE_INDX_SHIFT
|
||||
lrw a2, PTE_INDX_MSK
|
||||
and a3, a2
|
||||
addu r6, a3
|
||||
ldw a3, (r6)
|
||||
|
||||
movi a2, (_PAGE_PRESENT | \val0)
|
||||
and a3, a2
|
||||
cmpne a3, a2
|
||||
bt \name
|
||||
|
||||
/* First read/write the page, just update the flags */
|
||||
ldw a3, (r6)
|
||||
bgeni a2, PAGE_VALID_BIT
|
||||
bseti a2, PAGE_ACCESSED_BIT
|
||||
bseti a2, \val1
|
||||
bseti a2, \val2
|
||||
or a3, a2
|
||||
stw a3, (r6)
|
||||
|
||||
/* Some cpu tlb-hardrefill bypass the cache */
|
||||
#ifdef CONFIG_CPU_NEED_TLBSYNC
|
||||
movi a2, 0x22
|
||||
bseti a2, 6
|
||||
mtcr r6, cr22
|
||||
mtcr a2, cr17
|
||||
sync
|
||||
#endif
|
||||
|
||||
mfcr a3, ss2
|
||||
mfcr r6, ss3
|
||||
mfcr a2, ss4
|
||||
rte
|
||||
\name:
|
||||
mfcr a3, ss2
|
||||
mfcr r6, ss3
|
||||
mfcr a2, ss4
|
||||
SAVE_ALL EPC_KEEP
|
||||
.endm
|
||||
.macro tlbop_end is_write
|
||||
RD_MEH a2
|
||||
psrset ee, ie
|
||||
mov a0, sp
|
||||
movi a1, \is_write
|
||||
jbsr do_page_fault
|
||||
movi r11_sig, 0 /* r11 = 0, Not a syscall. */
|
||||
jmpi ret_from_exception
|
||||
.endm
|
||||
|
||||
.text
|
||||
|
||||
tlbop_begin tlbinvalidl, _PAGE_READ, PAGE_VALID_BIT, PAGE_ACCESSED_BIT
|
||||
tlbop_end 0
|
||||
|
||||
tlbop_begin tlbinvalids, _PAGE_WRITE, PAGE_DIRTY_BIT, PAGE_MODIFIED_BIT
|
||||
tlbop_end 1
|
||||
|
||||
tlbop_begin tlbmodified, _PAGE_WRITE, PAGE_DIRTY_BIT, PAGE_MODIFIED_BIT
|
||||
#ifndef CONFIG_CPU_HAS_LDSTEX
|
||||
jbsr csky_cmpxchg_fixup
|
||||
#endif
|
||||
tlbop_end 1
|
||||
|
||||
ENTRY(csky_systemcall)
|
||||
SAVE_ALL EPC_INCREASE
|
||||
|
||||
psrset ee, ie
|
||||
|
||||
/* Stack frame for syscall, origin call set_esp0 */
|
||||
mov r12, sp
|
||||
|
||||
bmaski r11, 13
|
||||
andn r12, r11
|
||||
bgeni r11, 9
|
||||
addi r11, 32
|
||||
addu r12, r11
|
||||
st sp, (r12, 0)
|
||||
|
||||
lrw r11, __NR_syscalls
|
||||
cmphs syscallid, r11 /* Check nr of syscall */
|
||||
bt ret_from_exception
|
||||
|
||||
lrw r13, sys_call_table
|
||||
ixw r13, syscallid
|
||||
ldw r11, (r13)
|
||||
cmpnei r11, 0
|
||||
bf ret_from_exception
|
||||
|
||||
mov r9, sp
|
||||
bmaski r10, THREAD_SHIFT
|
||||
andn r9, r10
|
||||
ldw r8, (r9, TINFO_FLAGS)
|
||||
btsti r8, TIF_SYSCALL_TRACE
|
||||
bt 1f
|
||||
#if defined(__CSKYABIV2__)
|
||||
subi sp, 8
|
||||
stw r5, (sp, 0x4)
|
||||
stw r4, (sp, 0x0)
|
||||
jsr r11 /* Do system call */
|
||||
addi sp, 8
|
||||
#else
|
||||
jsr r11
|
||||
#endif
|
||||
stw a0, (sp, LSAVE_A0) /* Save return value */
|
||||
jmpi ret_from_exception
|
||||
|
||||
1:
|
||||
movi a0, 0 /* enter system call */
|
||||
mov a1, sp /* sp = pt_regs pointer */
|
||||
jbsr syscall_trace
|
||||
/* Prepare args before do system call */
|
||||
ldw a0, (sp, LSAVE_A0)
|
||||
ldw a1, (sp, LSAVE_A1)
|
||||
ldw a2, (sp, LSAVE_A2)
|
||||
ldw a3, (sp, LSAVE_A3)
|
||||
#if defined(__CSKYABIV2__)
|
||||
subi sp, 8
|
||||
stw r5, (sp, 0x4)
|
||||
stw r4, (sp, 0x0)
|
||||
#else
|
||||
ldw r6, (sp, LSAVE_A4)
|
||||
ldw r7, (sp, LSAVE_A5)
|
||||
#endif
|
||||
jsr r11 /* Do system call */
|
||||
#if defined(__CSKYABIV2__)
|
||||
addi sp, 8
|
||||
#endif
|
||||
stw a0, (sp, LSAVE_A0) /* Save return value */
|
||||
|
||||
movi a0, 1 /* leave system call */
|
||||
mov a1, sp /* sp = pt_regs pointer */
|
||||
jbsr syscall_trace
|
||||
|
||||
syscall_exit_work:
|
||||
ld syscallid, (sp, LSAVE_PSR)
|
||||
btsti syscallid, 31
|
||||
bt 2f
|
||||
|
||||
jmpi resume_userspace
|
||||
|
||||
2: RESTORE_ALL
|
||||
|
||||
ENTRY(ret_from_kernel_thread)
|
||||
jbsr schedule_tail
|
||||
mov a0, r8
|
||||
jsr r9
|
||||
jbsr ret_from_exception
|
||||
|
||||
ENTRY(ret_from_fork)
|
||||
jbsr schedule_tail
|
||||
mov r9, sp
|
||||
bmaski r10, THREAD_SHIFT
|
||||
andn r9, r10
|
||||
ldw r8, (r9, TINFO_FLAGS)
|
||||
movi r11_sig, 1
|
||||
btsti r8, TIF_SYSCALL_TRACE
|
||||
bf 3f
|
||||
movi a0, 1
|
||||
mov a1, sp /* sp = pt_regs pointer */
|
||||
jbsr syscall_trace
|
||||
3:
|
||||
jbsr ret_from_exception
|
||||
|
||||
ret_from_exception:
|
||||
ld syscallid, (sp, LSAVE_PSR)
|
||||
btsti syscallid, 31
|
||||
bt 1f
|
||||
|
||||
/*
|
||||
* Load address of current->thread_info, Then get address of task_struct
|
||||
* Get task_needreshed in task_struct
|
||||
*/
|
||||
mov r9, sp
|
||||
bmaski r10, THREAD_SHIFT
|
||||
andn r9, r10
|
||||
|
||||
resume_userspace:
|
||||
ldw r8, (r9, TINFO_FLAGS)
|
||||
andi r8, (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED)
|
||||
cmpnei r8, 0
|
||||
bt exit_work
|
||||
1: RESTORE_ALL
|
||||
|
||||
exit_work:
|
||||
mov a0, sp /* Stack address is arg[0] */
|
||||
jbsr set_esp0 /* Call C level */
|
||||
btsti r8, TIF_NEED_RESCHED
|
||||
bt work_resched
|
||||
/* If thread_info->flag is empty, RESTORE_ALL */
|
||||
cmpnei r8, 0
|
||||
bf 1b
|
||||
mov a1, sp
|
||||
mov a0, r8
|
||||
mov a2, r11_sig /* syscall? */
|
||||
btsti r8, TIF_SIGPENDING /* delivering a signal? */
|
||||
/* prevent further restarts(set r11 = 0) */
|
||||
clrt r11_sig
|
||||
jbsr do_notify_resume /* do signals */
|
||||
br resume_userspace
|
||||
|
||||
work_resched:
|
||||
lrw syscallid, ret_from_exception
|
||||
mov r15, syscallid /* Return address in link */
|
||||
jmpi schedule
|
||||
|
||||
ENTRY(sys_rt_sigreturn)
|
||||
movi r11_sig, 0
|
||||
jmpi do_rt_sigreturn
|
||||
|
||||
ENTRY(csky_trap)
|
||||
SAVE_ALL EPC_KEEP
|
||||
psrset ee
|
||||
movi r11_sig, 0 /* r11 = 0, Not a syscall. */
|
||||
mov a0, sp /* Push Stack pointer arg */
|
||||
jbsr trap_c /* Call C-level trap handler */
|
||||
jmpi ret_from_exception
|
||||
|
||||
/*
|
||||
* Prototype from libc for abiv1:
|
||||
* register unsigned int __result asm("a0");
|
||||
* asm( "trap 3" :"=r"(__result)::);
|
||||
*/
|
||||
ENTRY(csky_get_tls)
|
||||
USPTOKSP
|
||||
|
||||
/* increase epc for continue */
|
||||
mfcr a0, epc
|
||||
INCTRAP a0
|
||||
mtcr a0, epc
|
||||
|
||||
/* get current task thread_info with kernel 8K stack */
|
||||
bmaski a0, THREAD_SHIFT
|
||||
not a0
|
||||
subi sp, 1
|
||||
and a0, sp
|
||||
addi sp, 1
|
||||
|
||||
/* get tls */
|
||||
ldw a0, (a0, TINFO_TP_VALUE)
|
||||
|
||||
KSPTOUSP
|
||||
rte
|
||||
|
||||
ENTRY(csky_irq)
|
||||
SAVE_ALL EPC_KEEP
|
||||
psrset ee
|
||||
movi r11_sig, 0 /* r11 = 0, Not a syscall. */
|
||||
|
||||
#ifdef CONFIG_PREEMPT
|
||||
mov r9, sp /* Get current stack pointer */
|
||||
bmaski r10, THREAD_SHIFT
|
||||
andn r9, r10 /* Get thread_info */
|
||||
|
||||
/*
|
||||
* Get task_struct->stack.preempt_count for current,
|
||||
* and increase 1.
|
||||
*/
|
||||
ldw r8, (r9, TINFO_PREEMPT)
|
||||
addi r8, 1
|
||||
stw r8, (r9, TINFO_PREEMPT)
|
||||
#endif
|
||||
|
||||
mov a0, sp
|
||||
jbsr csky_do_IRQ
|
||||
|
||||
#ifdef CONFIG_PREEMPT
|
||||
subi r8, 1
|
||||
stw r8, (r9, TINFO_PREEMPT)
|
||||
cmpnei r8, 0
|
||||
bt 2f
|
||||
ldw r8, (r9, TINFO_FLAGS)
|
||||
btsti r8, TIF_NEED_RESCHED
|
||||
bf 2f
|
||||
1:
|
||||
jbsr preempt_schedule_irq /* irq en/disable is done inside */
|
||||
ldw r7, (r9, TINFO_FLAGS) /* get new tasks TI_FLAGS */
|
||||
btsti r7, TIF_NEED_RESCHED
|
||||
bt 1b /* go again */
|
||||
#endif
|
||||
2:
|
||||
jmpi ret_from_exception
|
||||
|
||||
/*
|
||||
* a0 = prev task_struct *
|
||||
* a1 = next task_struct *
|
||||
* a0 = return next
|
||||
*/
|
||||
ENTRY(__switch_to)
|
||||
lrw a3, TASK_THREAD
|
||||
addu a3, a0
|
||||
|
||||
mfcr a2, psr /* Save PSR value */
|
||||
stw a2, (a3, THREAD_SR) /* Save PSR in task struct */
|
||||
bclri a2, 6 /* Disable interrupts */
|
||||
mtcr a2, psr
|
||||
|
||||
SAVE_SWITCH_STACK
|
||||
|
||||
stw sp, (a3, THREAD_KSP)
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_HILO
|
||||
lrw r10, THREAD_DSPHI
|
||||
add r10, a3
|
||||
mfhi r6
|
||||
mflo r7
|
||||
stw r6, (r10, 0) /* THREAD_DSPHI */
|
||||
stw r7, (r10, 4) /* THREAD_DSPLO */
|
||||
mfcr r6, cr14
|
||||
stw r6, (r10, 8) /* THREAD_DSPCSR */
|
||||
#endif
|
||||
|
||||
/* Set up next process to run */
|
||||
lrw a3, TASK_THREAD
|
||||
addu a3, a1
|
||||
|
||||
ldw sp, (a3, THREAD_KSP) /* Set next kernel sp */
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_HILO
|
||||
lrw r10, THREAD_DSPHI
|
||||
add r10, a3
|
||||
ldw r6, (r10, 8) /* THREAD_DSPCSR */
|
||||
mtcr r6, cr14
|
||||
ldw r6, (r10, 0) /* THREAD_DSPHI */
|
||||
ldw r7, (r10, 4) /* THREAD_DSPLO */
|
||||
mthi r6
|
||||
mtlo r7
|
||||
#endif
|
||||
|
||||
ldw a2, (a3, THREAD_SR) /* Set next PSR */
|
||||
mtcr a2, psr
|
||||
|
||||
#if defined(__CSKYABIV2__)
|
||||
addi r7, a1, TASK_THREAD_INFO
|
||||
ldw tls, (r7, TINFO_TP_VALUE)
|
||||
#endif
|
||||
|
||||
RESTORE_SWITCH_STACK
|
||||
|
||||
rts
|
||||
ENDPROC(__switch_to)
|
169
arch/csky/kernel/traps.c
Normal file
169
arch/csky/kernel/traps.c
Normal file
@@ -0,0 +1,169 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/user.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/siginfo.h>
|
||||
|
||||
#include <asm/mmu_context.h>
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_FPU
|
||||
#include <abi/fpu.h>
|
||||
#endif
|
||||
|
||||
/* Defined in entry.S */
|
||||
asmlinkage void csky_trap(void);
|
||||
|
||||
asmlinkage void csky_systemcall(void);
|
||||
asmlinkage void csky_cmpxchg(void);
|
||||
asmlinkage void csky_get_tls(void);
|
||||
asmlinkage void csky_irq(void);
|
||||
|
||||
asmlinkage void csky_tlbinvalidl(void);
|
||||
asmlinkage void csky_tlbinvalids(void);
|
||||
asmlinkage void csky_tlbmodified(void);
|
||||
|
||||
/* Defined in head.S */
|
||||
asmlinkage void _start_smp_secondary(void);
|
||||
|
||||
void __init pre_trap_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
mtcr("vbr", vec_base);
|
||||
|
||||
for (i = 1; i < 128; i++)
|
||||
VEC_INIT(i, csky_trap);
|
||||
}
|
||||
|
||||
void __init trap_init(void)
|
||||
{
|
||||
VEC_INIT(VEC_AUTOVEC, csky_irq);
|
||||
|
||||
/* setup trap0 trap2 trap3 */
|
||||
VEC_INIT(VEC_TRAP0, csky_systemcall);
|
||||
VEC_INIT(VEC_TRAP2, csky_cmpxchg);
|
||||
VEC_INIT(VEC_TRAP3, csky_get_tls);
|
||||
|
||||
/* setup MMU TLB exception */
|
||||
VEC_INIT(VEC_TLBINVALIDL, csky_tlbinvalidl);
|
||||
VEC_INIT(VEC_TLBINVALIDS, csky_tlbinvalids);
|
||||
VEC_INIT(VEC_TLBMODIFIED, csky_tlbmodified);
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_FPU
|
||||
init_fpu();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
mtcr("cr<28, 0>", virt_to_phys(vec_base));
|
||||
|
||||
VEC_INIT(VEC_RESET, (void *)virt_to_phys(_start_smp_secondary));
|
||||
#endif
|
||||
}
|
||||
|
||||
void die_if_kernel(char *str, struct pt_regs *regs, int nr)
|
||||
{
|
||||
if (user_mode(regs))
|
||||
return;
|
||||
|
||||
console_verbose();
|
||||
pr_err("%s: %08x\n", str, nr);
|
||||
show_regs(regs);
|
||||
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||
do_exit(SIGSEGV);
|
||||
}
|
||||
|
||||
void buserr(struct pt_regs *regs)
|
||||
{
|
||||
#ifdef CONFIG_CPU_CK810
|
||||
static unsigned long prev_pc;
|
||||
|
||||
if ((regs->pc == prev_pc) && prev_pc != 0) {
|
||||
prev_pc = 0;
|
||||
} else {
|
||||
prev_pc = regs->pc;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
die_if_kernel("Kernel mode BUS error", regs, 0);
|
||||
|
||||
pr_err("User mode Bus Error\n");
|
||||
show_regs(regs);
|
||||
|
||||
current->thread.esp0 = (unsigned long) regs;
|
||||
force_sig_fault(SIGSEGV, 0, (void __user *)regs->pc, current);
|
||||
}
|
||||
|
||||
#define USR_BKPT 0x1464
|
||||
asmlinkage void trap_c(struct pt_regs *regs)
|
||||
{
|
||||
int sig;
|
||||
unsigned long vector;
|
||||
siginfo_t info;
|
||||
|
||||
vector = (mfcr("psr") >> 16) & 0xff;
|
||||
|
||||
switch (vector) {
|
||||
case VEC_ZERODIV:
|
||||
sig = SIGFPE;
|
||||
break;
|
||||
/* ptrace */
|
||||
case VEC_TRACE:
|
||||
info.si_code = TRAP_TRACE;
|
||||
sig = SIGTRAP;
|
||||
break;
|
||||
case VEC_ILLEGAL:
|
||||
#ifndef CONFIG_CPU_NO_USER_BKPT
|
||||
if (*(uint16_t *)instruction_pointer(regs) != USR_BKPT)
|
||||
#endif
|
||||
{
|
||||
sig = SIGILL;
|
||||
break;
|
||||
}
|
||||
/* gdbserver breakpoint */
|
||||
case VEC_TRAP1:
|
||||
/* jtagserver breakpoint */
|
||||
case VEC_BREAKPOINT:
|
||||
info.si_code = TRAP_BRKPT;
|
||||
sig = SIGTRAP;
|
||||
break;
|
||||
case VEC_ACCESS:
|
||||
return buserr(regs);
|
||||
#ifdef CONFIG_CPU_NEED_SOFTALIGN
|
||||
case VEC_ALIGN:
|
||||
return csky_alignment(regs);
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_HAS_FPU
|
||||
case VEC_FPE:
|
||||
return fpu_fpe(regs);
|
||||
case VEC_PRIV:
|
||||
if (fpu_libc_helper(regs))
|
||||
return;
|
||||
#endif
|
||||
default:
|
||||
sig = SIGSEGV;
|
||||
break;
|
||||
}
|
||||
send_sig(sig, current, 0);
|
||||
}
|
||||
|
||||
asmlinkage void set_esp0(unsigned long ssp)
|
||||
{
|
||||
current->thread.esp0 = ssp;
|
||||
}
|
Reference in New Issue
Block a user