Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275/* 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/page.h>#include <asm/thread_info.h>
.macro zero_fp#ifdef CONFIG_STACKTRACE movi r8, 0#endif.endm
.macro context_tracking#ifdef CONFIG_CONTEXT_TRACKING_USER mfcr a0, epsr btsti a0, 31 bt 1f jbsr user_exit_callable ldw a0, (sp, LSAVE_A0) ldw a1, (sp, LSAVE_A1) ldw a2, (sp, LSAVE_A2) ldw a3, (sp, LSAVE_A3)#if defined(__CSKYABIV1__) ldw r6, (sp, LSAVE_A4) ldw r7, (sp, LSAVE_A5)#endif1:#endif.endm
.textENTRY(csky_pagefault) SAVE_ALL 0 zero_fp context_tracking psrset ee mov a0, sp jbsr do_page_fault jmpi ret_from_exception
ENTRY(csky_systemcall) SAVE_ALL TRAP0_SIZE zero_fp context_tracking psrset ee, ie
lrw r9, __NR_syscalls cmphs syscallid, r9 /* Check nr of syscall */ bt ret_from_exception
lrw r9, sys_call_table ixw r9, syscallid ldw syscallid, (r9) cmpnei syscallid, 0 bf ret_from_exception
mov r9, sp bmaski r10, THREAD_SHIFT andn r9, r10 ldw r10, (r9, TINFO_FLAGS) lrw r9, _TIF_SYSCALL_WORK and r10, r9 cmpnei r10, 0 bt csky_syscall_trace#if defined(__CSKYABIV2__) subi sp, 8 stw r5, (sp, 0x4) stw r4, (sp, 0x0) jsr syscallid /* Do system call */ addi sp, 8#else jsr syscallid#endif stw a0, (sp, LSAVE_A0) /* Save return value */ jmpi ret_from_exception
csky_syscall_trace: mov a0, sp /* sp = pt_regs pointer */ jbsr syscall_trace_enter cmpnei a0, 0 bt 1f /* 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 ldw r9, (sp, LSAVE_A4) stw r9, (sp, 0x0) ldw r9, (sp, LSAVE_A5) stw r9, (sp, 0x4) jsr syscallid /* Do system call */ addi sp, 8#else ldw r6, (sp, LSAVE_A4) ldw r7, (sp, LSAVE_A5) jsr syscallid /* Do system call */#endif stw a0, (sp, LSAVE_A0) /* Save return value */
1: mov a0, sp /* right now, sp --> pt_regs */ jbsr syscall_trace_exit br ret_from_exception
ENTRY(ret_from_kernel_thread) jbsr schedule_tail mov a0, r10 jsr r9 jbsr ret_from_exception
ENTRY(ret_from_fork) jbsr schedule_tail mov r9, sp bmaski r10, THREAD_SHIFT andn r9, r10 ldw r10, (r9, TINFO_FLAGS) lrw r9, _TIF_SYSCALL_WORK and r10, r9 cmpnei r10, 0 bf ret_from_exception mov a0, sp /* sp = pt_regs pointer */ jbsr syscall_trace_exit
ret_from_exception: psrclr ie ld r9, (sp, LSAVE_PSR) btsti r9, 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
ldw r10, (r9, TINFO_FLAGS) lrw r9, _TIF_WORK_MASK and r10, r9 cmpnei r10, 0 bt exit_work#ifdef CONFIG_CONTEXT_TRACKING_USER jbsr user_enter_callable#endif1:#ifdef CONFIG_PREEMPTION mov r9, sp bmaski r10, THREAD_SHIFT andn r9, r10
ldw r10, (r9, TINFO_PREEMPT) cmpnei r10, 0 bt 2f jbsr preempt_schedule_irq /* irq en/disable is done inside */2:#endif
#ifdef CONFIG_TRACE_IRQFLAGS ld r10, (sp, LSAVE_PSR) btsti r10, 6 bf 2f jbsr trace_hardirqs_on2:#endif RESTORE_ALL
exit_work: lrw r9, ret_from_exception mov lr, r9
btsti r10, TIF_NEED_RESCHED bt work_resched
psrset ie mov a0, sp mov a1, r10 jmpi do_notify_resume
work_resched: jmpi schedule
ENTRY(csky_trap) SAVE_ALL 0 zero_fp context_tracking psrset ee 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
RD_MEH a0 WR_MEH a0
/* increase epc for continue */ mfcr a0, epc addi a0, TRAP0_SIZE 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 0 zero_fp context_tracking psrset ee
#ifdef CONFIG_TRACE_IRQFLAGS jbsr trace_hardirqs_off#endif
mov a0, sp jbsr generic_handle_arch_irq
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
SAVE_SWITCH_STACK
stw sp, (a3, THREAD_KSP)
/* Set up next process to run */ lrw a3, TASK_THREAD addu a3, a1
ldw sp, (a3, THREAD_KSP) /* Set next kernel sp */
#if defined(__CSKYABIV2__) addi a3, a1, TASK_THREAD_INFO ldw tls, (a3, TINFO_TP_VALUE)#endif
RESTORE_SWITCH_STACK
rtsENDPROC(__switch_to)