1
0
Fork 0
alistair23-linux/arch/csky/kernel/entry.S

346 lines
6.4 KiB
ArmAsm
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

/* 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 zero_fp
#ifdef CONFIG_STACKTRACE
movi r8, 0
#endif
.endm
.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, va_pa_offset
ld.w a2, (a2, 0)
subu r6, a2
bseti r6, 31
mov a2, a3
lsri a2, _PGDIR_SHIFT
lsli a2, 2
addu r6, a2
ldw r6, (r6)
lrw a2, va_pa_offset
ld.w a2, (a2, 0)
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 0
.endm
.macro tlbop_end is_write
zero_fp
RD_MEH a2
psrset ee, ie
mov a0, sp
movi a1, \is_write
jbsr do_page_fault
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 TRAP0_SIZE
zero_fp
psrset ee, ie
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 r12, (r9, TINFO_FLAGS)
ANDI_R3 r12, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT)
cmpnei r12, 0
bt csky_syscall_trace
#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
csky_syscall_trace:
mov a0, sp /* sp = pt_regs pointer */
jbsr syscall_trace_enter
/* 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)
#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 */
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 r12, (r9, TINFO_FLAGS)
ANDI_R3 r12, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT)
cmpnei r12, 0
bf ret_from_exception
mov a0, sp /* sp = pt_regs pointer */
jbsr syscall_trace_exit
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
ldw r12, (r9, TINFO_FLAGS)
andi r12, (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED)
cmpnei r12, 0
bt exit_work
1:
RESTORE_ALL
exit_work:
lrw syscallid, ret_from_exception
mov lr, syscallid
btsti r12, TIF_NEED_RESCHED
bt work_resched
mov a0, sp
mov a1, r12
jmpi do_notify_resume
work_resched:
jmpi schedule
ENTRY(csky_trap)
SAVE_ALL 0
zero_fp
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
/* 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
psrset ee
#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 r12, (r9, TINFO_PREEMPT)
addi r12, 1
stw r12, (r9, TINFO_PREEMPT)
#endif
mov a0, sp
jbsr csky_do_IRQ
#ifdef CONFIG_PREEMPT
subi r12, 1
stw r12, (r9, TINFO_PREEMPT)
cmpnei r12, 0
bt 2f
ldw r12, (r9, TINFO_FLAGS)
btsti r12, TIF_NEED_RESCHED
bf 2f
jbsr preempt_schedule_irq /* irq en/disable is done inside */
#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 */
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 */
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)