Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
0003 
0004 #include <linux/linkage.h>
0005 #include <abi/entry.h>
0006 #include <abi/pgtable-bits.h>
0007 #include <asm/errno.h>
0008 #include <asm/setup.h>
0009 #include <asm/unistd.h>
0010 #include <asm/asm-offsets.h>
0011 #include <linux/threads.h>
0012 #include <asm/page.h>
0013 #include <asm/thread_info.h>
0014 
0015 .macro  zero_fp
0016 #ifdef CONFIG_STACKTRACE
0017     movi    r8, 0
0018 #endif
0019 .endm
0020 
0021 .macro  context_tracking
0022 #ifdef CONFIG_CONTEXT_TRACKING_USER
0023     mfcr    a0, epsr
0024     btsti   a0, 31
0025     bt  1f
0026     jbsr    user_exit_callable
0027     ldw a0, (sp, LSAVE_A0)
0028     ldw a1, (sp, LSAVE_A1)
0029     ldw a2, (sp, LSAVE_A2)
0030     ldw a3, (sp, LSAVE_A3)
0031 #if defined(__CSKYABIV1__)
0032     ldw r6, (sp, LSAVE_A4)
0033     ldw r7, (sp, LSAVE_A5)
0034 #endif
0035 1:
0036 #endif
0037 .endm
0038 
0039 .text
0040 ENTRY(csky_pagefault)
0041     SAVE_ALL 0
0042     zero_fp
0043     context_tracking
0044     psrset  ee
0045     mov     a0, sp
0046     jbsr    do_page_fault
0047     jmpi    ret_from_exception
0048 
0049 ENTRY(csky_systemcall)
0050     SAVE_ALL TRAP0_SIZE
0051     zero_fp
0052     context_tracking
0053     psrset  ee, ie
0054 
0055     lrw     r9, __NR_syscalls
0056     cmphs   syscallid, r9       /* Check nr of syscall */
0057     bt      1f
0058 
0059     lrw     r9, sys_call_table
0060     ixw     r9, syscallid
0061     ldw     syscallid, (r9)
0062     cmpnei  syscallid, 0
0063     bf      ret_from_exception
0064 
0065     mov     r9, sp
0066     bmaski  r10, THREAD_SHIFT
0067     andn    r9, r10
0068     ldw     r10, (r9, TINFO_FLAGS)
0069     lrw r9, _TIF_SYSCALL_WORK
0070     and r10, r9
0071     cmpnei  r10, 0
0072     bt      csky_syscall_trace
0073 #if defined(__CSKYABIV2__)
0074     subi    sp, 8
0075     stw     r5, (sp, 0x4)
0076     stw     r4, (sp, 0x0)
0077     jsr     syscallid                      /* Do system call */
0078     addi    sp, 8
0079 #else
0080     jsr     syscallid
0081 #endif
0082     stw     a0, (sp, LSAVE_A0)      /* Save return value */
0083 1:
0084 #ifdef CONFIG_DEBUG_RSEQ
0085     mov a0, sp
0086     jbsr    rseq_syscall
0087 #endif
0088     jmpi    ret_from_exception
0089 
0090 csky_syscall_trace:
0091     mov a0, sp                  /* sp = pt_regs pointer */
0092     jbsr    syscall_trace_enter
0093     cmpnei  a0, 0
0094     bt  1f
0095     /* Prepare args before do system call */
0096     ldw a0, (sp, LSAVE_A0)
0097     ldw a1, (sp, LSAVE_A1)
0098     ldw a2, (sp, LSAVE_A2)
0099     ldw a3, (sp, LSAVE_A3)
0100 #if defined(__CSKYABIV2__)
0101     subi    sp, 8
0102     ldw r9, (sp, LSAVE_A4)
0103     stw r9, (sp, 0x0)
0104     ldw r9, (sp, LSAVE_A5)
0105     stw r9, (sp, 0x4)
0106     jsr syscallid                     /* Do system call */
0107     addi    sp, 8
0108 #else
0109     ldw r6, (sp, LSAVE_A4)
0110     ldw r7, (sp, LSAVE_A5)
0111     jsr syscallid                     /* Do system call */
0112 #endif
0113     stw a0, (sp, LSAVE_A0)  /* Save return value */
0114 
0115 1:
0116 #ifdef CONFIG_DEBUG_RSEQ
0117     mov a0, sp
0118     jbsr    rseq_syscall
0119 #endif
0120     mov     a0, sp                  /* right now, sp --> pt_regs */
0121     jbsr    syscall_trace_exit
0122     br  ret_from_exception
0123 
0124 ENTRY(ret_from_kernel_thread)
0125     jbsr    schedule_tail
0126     mov a0, r10
0127     jsr r9
0128     jbsr    ret_from_exception
0129 
0130 ENTRY(ret_from_fork)
0131     jbsr    schedule_tail
0132     mov r9, sp
0133     bmaski  r10, THREAD_SHIFT
0134     andn    r9, r10
0135     ldw r10, (r9, TINFO_FLAGS)
0136     lrw r9, _TIF_SYSCALL_WORK
0137     and r10, r9
0138     cmpnei  r10, 0
0139     bf  ret_from_exception
0140     mov a0, sp          /* sp = pt_regs pointer */
0141     jbsr    syscall_trace_exit
0142 
0143 ret_from_exception:
0144     psrclr  ie
0145     ld  r9, (sp, LSAVE_PSR)
0146     btsti   r9, 31
0147 
0148     bt  1f
0149     /*
0150      * Load address of current->thread_info, Then get address of task_struct
0151      * Get task_needreshed in task_struct
0152      */
0153     mov r9, sp
0154     bmaski  r10, THREAD_SHIFT
0155     andn    r9, r10
0156 
0157     ldw r10, (r9, TINFO_FLAGS)
0158     lrw r9, _TIF_WORK_MASK
0159     and r10, r9
0160     cmpnei  r10, 0
0161     bt  exit_work
0162 #ifdef CONFIG_CONTEXT_TRACKING_USER
0163     jbsr    user_enter_callable
0164 #endif
0165 1:
0166 #ifdef CONFIG_PREEMPTION
0167     mov r9, sp
0168     bmaski  r10, THREAD_SHIFT
0169     andn    r9, r10
0170 
0171     ldw r10, (r9, TINFO_PREEMPT)
0172     cmpnei  r10, 0
0173     bt  2f
0174     jbsr    preempt_schedule_irq    /* irq en/disable is done inside */
0175 2:
0176 #endif
0177 
0178 #ifdef CONFIG_TRACE_IRQFLAGS
0179     ld  r10, (sp, LSAVE_PSR)
0180     btsti   r10, 6
0181     bf  2f
0182     jbsr    trace_hardirqs_on
0183 2:
0184 #endif
0185     RESTORE_ALL
0186 
0187 exit_work:
0188     lrw r9, ret_from_exception
0189     mov lr, r9
0190 
0191     btsti   r10, TIF_NEED_RESCHED
0192     bt  work_resched
0193 
0194     psrset  ie
0195     mov a0, sp
0196     mov a1, r10
0197     jmpi    do_notify_resume
0198 
0199 work_resched:
0200     jmpi    schedule
0201 
0202 ENTRY(csky_trap)
0203     SAVE_ALL 0
0204     zero_fp
0205     context_tracking
0206     psrset  ee
0207     mov a0, sp                 /* Push Stack pointer arg */
0208     jbsr    trap_c                 /* Call C-level trap handler */
0209     jmpi    ret_from_exception
0210 
0211 /*
0212  * Prototype from libc for abiv1:
0213  * register unsigned int __result asm("a0");
0214  * asm( "trap 3" :"=r"(__result)::);
0215  */
0216 ENTRY(csky_get_tls)
0217     USPTOKSP
0218 
0219     RD_MEH  a0
0220     WR_MEH  a0
0221 
0222     /* increase epc for continue */
0223     mfcr    a0, epc
0224     addi    a0, TRAP0_SIZE
0225     mtcr    a0, epc
0226 
0227     /* get current task thread_info with kernel 8K stack */
0228     bmaski  a0, THREAD_SHIFT
0229     not a0
0230     subi    sp, 1
0231     and a0, sp
0232     addi    sp, 1
0233 
0234     /* get tls */
0235     ldw a0, (a0, TINFO_TP_VALUE)
0236 
0237     KSPTOUSP
0238     rte
0239 
0240 ENTRY(csky_irq)
0241     SAVE_ALL 0
0242     zero_fp
0243     context_tracking
0244     psrset  ee
0245 
0246 #ifdef CONFIG_TRACE_IRQFLAGS
0247     jbsr    trace_hardirqs_off
0248 #endif
0249 
0250 
0251     mov a0, sp
0252     jbsr    generic_handle_arch_irq
0253 
0254     jmpi    ret_from_exception
0255 
0256 /*
0257  * a0 =  prev task_struct *
0258  * a1 =  next task_struct *
0259  * a0 =  return next
0260  */
0261 ENTRY(__switch_to)
0262     lrw a3, TASK_THREAD
0263     addu    a3, a0
0264 
0265     SAVE_SWITCH_STACK
0266 
0267     stw sp, (a3, THREAD_KSP)
0268 
0269     /* Set up next process to run */
0270     lrw a3, TASK_THREAD
0271     addu    a3, a1
0272 
0273     ldw sp, (a3, THREAD_KSP)    /* Set next kernel sp */
0274 
0275 #if  defined(__CSKYABIV2__)
0276     addi    a3, a1, TASK_THREAD_INFO
0277     ldw tls, (a3, TINFO_TP_VALUE)
0278 #endif
0279 
0280     RESTORE_SWITCH_STACK
0281 
0282     rts
0283 ENDPROC(__switch_to)