271 lines
5.5 KiB
ArmAsm
271 lines
5.5 KiB
ArmAsm
/*
|
|
* Copyright (c) 2020 AIIT XUOS Lab
|
|
* XiUOS is licensed under Mulan PSL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
* You may obtain a copy of Mulan PSL v2 at:
|
|
* http://license.coscl.org.cn/MulanPSL2
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PSL v2 for more details.
|
|
*/
|
|
/**
|
|
* @file trampoline.S
|
|
* @brief trap in and out code
|
|
* @version 1.0
|
|
* @author AIIT XUOS Lab
|
|
* @date 2024-04-22
|
|
*/
|
|
|
|
/*************************************************
|
|
File name: trampoline.S
|
|
Description: trap in and out code
|
|
Others:
|
|
History:
|
|
1. Date: 2024-04-22
|
|
Author: AIIT XUOS Lab
|
|
Modification:
|
|
1. first version
|
|
*************************************************/
|
|
|
|
#include "memlayout.h"
|
|
#include "core.h"
|
|
#include "asm/csr.h"
|
|
#include "asm/asm-offsets.h"
|
|
|
|
|
|
.align 4
|
|
.global handle_exception
|
|
handle_exception:
|
|
csrrw tp, CSR_SCRATCH, tp
|
|
bnez tp, _save_context
|
|
|
|
_restore_kernel_tpsp:
|
|
csrr tp, CSR_SCRATCH
|
|
REG_S sp, TASK_TI_KERNEL_SP(tp)
|
|
|
|
_save_context:
|
|
REG_S sp, TASK_TI_USER_SP(tp)
|
|
REG_L sp, TASK_TI_KERNEL_SP(tp)
|
|
addi sp, sp, -(PT_SIZE_ON_STACK)
|
|
REG_S x1, PT_RA(sp)
|
|
REG_S x3, PT_GP(sp)
|
|
REG_S x5, PT_T0(sp)
|
|
REG_S x6, PT_T1(sp)
|
|
REG_S x7, PT_T2(sp)
|
|
REG_S x8, PT_S0(sp)
|
|
REG_S x9, PT_S1(sp)
|
|
REG_S x10, PT_A0(sp)
|
|
REG_S x11, PT_A1(sp)
|
|
REG_S x12, PT_A2(sp)
|
|
REG_S x13, PT_A3(sp)
|
|
REG_S x14, PT_A4(sp)
|
|
REG_S x15, PT_A5(sp)
|
|
REG_S x16, PT_A6(sp)
|
|
REG_S x17, PT_A7(sp)
|
|
REG_S x18, PT_S2(sp)
|
|
REG_S x19, PT_S3(sp)
|
|
REG_S x20, PT_S4(sp)
|
|
REG_S x21, PT_S5(sp)
|
|
REG_S x22, PT_S6(sp)
|
|
REG_S x23, PT_S7(sp)
|
|
REG_S x24, PT_S8(sp)
|
|
REG_S x25, PT_S9(sp)
|
|
REG_S x26, PT_S10(sp)
|
|
REG_S x27, PT_S11(sp)
|
|
REG_S x28, PT_T3(sp)
|
|
REG_S x29, PT_T4(sp)
|
|
REG_S x30, PT_T5(sp)
|
|
REG_S x31, PT_T6(sp)
|
|
|
|
/*
|
|
* Disable user-mode memory access as it should only be set in the
|
|
* actual user copy routines.
|
|
*
|
|
* Disable the FPU to detect illegal usage of floating point in kernel
|
|
* space.
|
|
*/
|
|
li t0, SR_SUM | SR_FS
|
|
|
|
REG_L s0, TASK_TI_USER_SP(tp)
|
|
csrrc s1, CSR_STATUS, t0
|
|
csrr s2, CSR_EPC
|
|
csrr s3, CSR_TVAL
|
|
csrr s4, CSR_CAUSE
|
|
csrr s5, CSR_SCRATCH
|
|
REG_S s0, PT_SP(sp)
|
|
REG_S s1, PT_STATUS(sp)
|
|
REG_S s2, PT_EPC(sp)
|
|
REG_S s3, PT_BADADDR(sp)
|
|
REG_S s4, PT_CAUSE(sp)
|
|
REG_S s5, PT_TP(sp)
|
|
|
|
/*
|
|
* Set the scratch register to 0, so that if a recursive exception
|
|
* occurs, the exception vector knows it came from the kernel
|
|
*/
|
|
csrw CSR_SCRATCH, x0
|
|
|
|
/* Load the global pointer */
|
|
.option push
|
|
.option norelax
|
|
la gp, __global_pointer$
|
|
.option pop
|
|
|
|
/*
|
|
* MSB of cause differentiates between
|
|
* interrupts and exceptions
|
|
*/
|
|
bge s4, zero, 1f
|
|
|
|
la ra, ret_from_exception
|
|
|
|
/* Handle interrupts */
|
|
move a0, sp /* pt_regs */
|
|
//la a1, handle_arch_irq
|
|
la a1, intr_irq_dispatch
|
|
REG_L a1, (a1)
|
|
jr a1
|
|
|
|
1:
|
|
/*
|
|
* Exceptions run with interrupts enabled or disabled depending on the
|
|
* state of SR_PIE in m/sstatus.
|
|
*/
|
|
andi t0, s1, SR_PIE
|
|
beqz t0, 1f
|
|
/* kprobes, entered via ebreak, must have interrupts disabled. */
|
|
li t0, EXC_BREAKPOINT
|
|
beq s4, t0, 1f
|
|
|
|
csrs CSR_STATUS, SR_IE
|
|
|
|
1:
|
|
la ra, ret_from_exception
|
|
/* Handle syscalls */
|
|
li t0, EXC_SYSCALL
|
|
beq s4, t0, handle_syscall
|
|
|
|
mv a0, sp
|
|
mv a1, s4
|
|
tail do_exception
|
|
|
|
handle_syscall:
|
|
/* save the initial A0 value (needed in signal handlers) */
|
|
REG_S a0, PT_ORIG_A0(sp)
|
|
/*
|
|
* Advance SEPC to avoid executing the original
|
|
* scall instruction on sret
|
|
*/
|
|
addi s2, s2, 0x4
|
|
REG_S s2, PT_EPC(sp)
|
|
|
|
/* Trace syscalls, but only if requested by the user. */
|
|
j handle_syscall_trace_enter
|
|
|
|
ret
|
|
|
|
|
|
/* Slow paths for ptrace. */
|
|
handle_syscall_trace_enter:
|
|
csrr s0, satp
|
|
la a0, riscv_kernel_satp
|
|
ld a0, 0(a0)
|
|
csrw satp, a0
|
|
sfence.vma
|
|
|
|
move a0, sp
|
|
//call do_syscall_trace_enter
|
|
call syscall_arch_handler
|
|
move t0, a0
|
|
REG_L a0, PT_A0(sp)
|
|
REG_L a1, PT_A1(sp)
|
|
REG_L a2, PT_A2(sp)
|
|
REG_L a3, PT_A3(sp)
|
|
REG_L a4, PT_A4(sp)
|
|
REG_L a5, PT_A5(sp)
|
|
REG_L a6, PT_A6(sp)
|
|
REG_L a7, PT_A7(sp)
|
|
//bnez t0, ret_from_syscall_rejected
|
|
//j check_syscall_nr
|
|
handle_syscall_trace_exit:
|
|
move a0, sp
|
|
//call do_syscall_trace_exit
|
|
|
|
csrw satp, s0
|
|
sfence.vma
|
|
|
|
j ret_from_exception
|
|
|
|
|
|
ret_from_exception:
|
|
REG_L s0, PT_STATUS(sp)
|
|
csrc CSR_STATUS, SR_IE
|
|
|
|
andi s0, s0, SR_SPP
|
|
bnez s0, resume_kernel
|
|
|
|
resume_userspace:
|
|
/* Save unwound kernel stack pointer in thread_info */
|
|
addi s0, sp, PT_SIZE_ON_STACK
|
|
REG_S s0, TASK_TI_KERNEL_SP(tp)
|
|
|
|
/*
|
|
* Save TP into the scratch register , so we can find the kernel data
|
|
* structures again.
|
|
*/
|
|
csrw CSR_SCRATCH, tp
|
|
|
|
restore_all:
|
|
REG_L a0, PT_STATUS(sp)
|
|
|
|
REG_L a2, PT_EPC(sp)
|
|
REG_SC x0, a2, PT_EPC(sp)
|
|
|
|
csrw CSR_STATUS, a0
|
|
csrw CSR_EPC, a2
|
|
|
|
REG_L x1, PT_RA(sp)
|
|
REG_L x3, PT_GP(sp)
|
|
REG_L x4, PT_TP(sp)
|
|
REG_L x5, PT_T0(sp)
|
|
REG_L x6, PT_T1(sp)
|
|
REG_L x7, PT_T2(sp)
|
|
REG_L x8, PT_S0(sp)
|
|
REG_L x9, PT_S1(sp)
|
|
REG_L x10, PT_A0(sp)
|
|
REG_L x11, PT_A1(sp)
|
|
REG_L x12, PT_A2(sp)
|
|
REG_L x13, PT_A3(sp)
|
|
REG_L x14, PT_A4(sp)
|
|
REG_L x15, PT_A5(sp)
|
|
REG_L x16, PT_A6(sp)
|
|
REG_L x17, PT_A7(sp)
|
|
REG_L x18, PT_S2(sp)
|
|
REG_L x19, PT_S3(sp)
|
|
REG_L x20, PT_S4(sp)
|
|
REG_L x21, PT_S5(sp)
|
|
REG_L x22, PT_S6(sp)
|
|
REG_L x23, PT_S7(sp)
|
|
REG_L x24, PT_S8(sp)
|
|
REG_L x25, PT_S9(sp)
|
|
REG_L x26, PT_S10(sp)
|
|
REG_L x27, PT_S11(sp)
|
|
REG_L x28, PT_T3(sp)
|
|
REG_L x29, PT_T4(sp)
|
|
REG_L x30, PT_T5(sp)
|
|
REG_L x31, PT_T6(sp)
|
|
|
|
REG_L x2, PT_SP(sp)
|
|
|
|
sret
|
|
|
|
resume_kernel:
|
|
j restore_all
|
|
|
|
|
|
.global task_prepare_enter
|
|
task_prepare_enter:
|
|
call xizi_leave_kernel
|
|
j ret_from_exception
|