Failed to fetch fork details. Try again later.
-
HappyEric authorede59a3c1b
Forked from
404小队 / OSKernel2021-404
Source project has a limited visibility.
#include <asm.h>
#include <csr.h>
.macro SAVE_CONTEXT
.local _restore_kernel_tpsp
.local _save_context
.local _from_kernel
# csrrw tp, CSR_SSCRATCH, tp
# bnez tp, _save_context
# _restore_kernel_tpsp:
# csrr tp, CSR_SSCRATCH
# sd sp, PCB_KERNEL_SP(tp)
_save_context:
/* HappyEric uses tp as current_running */
/*
* If coming from userspace, tp is greater or equal to 0
* If coming from kernel, tp is less than 0xffffffff00000000
*/
bltz tp, _from_kernel
csrw CSR_SSCRATCH, tp
ld tp, current_running
sd sp, PCB_USER_SP(tp) /* user sp is real */
ld sp, PCB_KERNEL_SP(tp)
csrr tp, CSR_SSCRATCH
_from_kernel:
addi sp, sp, -(OFFSET_SIZE)
/* TODO: save all general purpose registers here! */
sd zero, OFFSET_REG_ZERO(sp)
sd ra, OFFSET_REG_RA(sp)
sd gp, OFFSET_REG_GP(sp)
/* push tp */
sd tp, OFFSET_REG_TP(sp)
ld tp, current_running
sd sp, PCB_KERNEL_SP(tp) /* very important */
sd t0, OFFSET_REG_T0(sp)
sd t1, OFFSET_REG_T1(sp)
sd t2, OFFSET_REG_T2(sp)
sd s0, OFFSET_REG_S0(sp)
sd s1, OFFSET_REG_S1(sp)
sd a0, OFFSET_REG_A0(sp)
sd a1, OFFSET_REG_A1(sp)
sd a2, OFFSET_REG_A2(sp)
sd a3, OFFSET_REG_A3(sp)
sd a4, OFFSET_REG_A4(sp)
sd a5, OFFSET_REG_A5(sp)
sd a6, OFFSET_REG_A6(sp)
sd a7, OFFSET_REG_A7(sp)
sd s2, OFFSET_REG_S2(sp)
sd s3, OFFSET_REG_S3(sp)
sd s4, OFFSET_REG_S4(sp)
sd s5, OFFSET_REG_S5(sp)
sd s6, OFFSET_REG_S6(sp)
sd s7, OFFSET_REG_S7(sp)
sd s8, OFFSET_REG_S8(sp)
sd s9, OFFSET_REG_S9(sp)
sd s10, OFFSET_REG_S10(sp)
sd s11, OFFSET_REG_S11(sp)
sd t3, OFFSET_REG_T3(sp)
sd t4, OFFSET_REG_T4(sp)
sd t5, OFFSET_REG_T5(sp)
sd t6, OFFSET_REG_T6(sp)
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
/*
* 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
/* TODO: save sstatus, sepc, stval, scause and sscratch on kernel stack */
csrr s0, CSR_SSTATUS
sd s0, OFFSET_REG_SSTATUS(sp)
csrr s0, CSR_SEPC
sd s0, OFFSET_REG_SEPC(sp)
csrr s0, CSR_STVAL
sd s0, OFFSET_REG_SBADADDR(sp)
csrr s0, CSR_SCAUSE
sd s0, OFFSET_REG_SCAUSE(sp)
csrr s0, CSR_SATP
sd s0, OFFSET_REG_SATP(sp)
.endm
.macro RESTORE_CONTEXT
.local _back_to_kernel
/* TODO: Restore all registers and sepc,sstatus */
ld zero, OFFSET_REG_ZERO(sp)
ld ra, OFFSET_REG_RA(sp)
ld gp, OFFSET_REG_GP(sp)
ld tp, OFFSET_REG_TP(sp)
ld t0, OFFSET_REG_T0(sp)
ld t1, OFFSET_REG_T1(sp)
ld t2, OFFSET_REG_T2(sp)
ld s1, OFFSET_REG_S1(sp)
ld a0, OFFSET_REG_A0(sp)
ld a1, OFFSET_REG_A1(sp)
ld a2, OFFSET_REG_A2(sp)
ld a3, OFFSET_REG_A3(sp)
ld a4, OFFSET_REG_A4(sp)
ld a5, OFFSET_REG_A5(sp)
ld a6, OFFSET_REG_A6(sp)
ld a7, OFFSET_REG_A7(sp)
ld s2, OFFSET_REG_S2(sp)
ld s3, OFFSET_REG_S3(sp)
ld s4, OFFSET_REG_S4(sp)
ld s5, OFFSET_REG_S5(sp)
ld s6, OFFSET_REG_S6(sp)
ld s7, OFFSET_REG_S7(sp)
ld s8, OFFSET_REG_S8(sp)
ld s9, OFFSET_REG_S9(sp)
ld s10, OFFSET_REG_S10(sp)
ld s11, OFFSET_REG_S11(sp)
ld t3, OFFSET_REG_T3(sp)
ld t4, OFFSET_REG_T4(sp)
ld t5, OFFSET_REG_T5(sp)
ld t6, OFFSET_REG_T6(sp)
ld s0, OFFSET_REG_SSTATUS(sp)
csrw CSR_SSTATUS, s0
ld s0, OFFSET_REG_SEPC(sp)
csrw CSR_SEPC, s0
ld s0, OFFSET_REG_SATP(sp)
fence
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
fence.i
sfence.vma
fence
fence.i
csrw CSR_SATP, s0
fence
fence.i
sfence.vma
fence
fence.i
ld s0, OFFSET_REG_S0(sp)
addi sp, sp, OFFSET_SIZE
bltz tp, _back_to_kernel
csrw CSR_SSCRATCH, tp
ld tp, current_running
sd sp, PCB_KERNEL_SP(tp)
ld sp, PCB_USER_SP(tp)
csrr tp, CSR_SSCRATCH
_back_to_kernel:
.endm
ENTRY(enable_preempt)
ld t1, current_running
ld t0, PCB_PREEMPT_COUNT(t1)
beq t0, zero, do_enable
addi t0, t0, -1
sd t0, PCB_PREEMPT_COUNT(t1)
beq t0, zero, do_enable
jr ra
do_enable:
not t0, x0
csrs CSR_SIE, t0
jr ra
ENDPROC(enable_preempt)
ENTRY(disable_preempt)
csrw CSR_SIE, zero
ld t1, current_running
ld t0, PCB_PREEMPT_COUNT(t1)
addi t0, t0, 1
sd t0, PCB_PREEMPT_COUNT(t1)
jr ra
ENDPROC(disable_preempt)
ENTRY(enable_interrupt)
li t0, SR_SIE
csrs CSR_SSTATUS, t0
jr ra
ENDPROC(enable_interrupt)
ENTRY(disable_interrupt)
li t0, SR_SIE
csrc CSR_SSTATUS, t0
jr ra
ENDPROC(disable_interrupt)
// the address of previous pcb in a0
// the address of next pcb in a1
ENTRY(switch_to)
beqz a0, switch_to_restore
addi tp, a0, 0
// save all callee save registers on kernel stack
addi sp, sp, -(SWITCH_TO_SIZE)
sd ra, SWITCH_TO_RA(sp)
sd s0, SWITCH_TO_S0(sp)
sd s1, SWITCH_TO_S1(sp)
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
sd s2, SWITCH_TO_S2(sp)
sd s3, SWITCH_TO_S3(sp)
sd s4, SWITCH_TO_S4(sp)
sd s5, SWITCH_TO_S5(sp)
sd s6, SWITCH_TO_S6(sp)
sd s7, SWITCH_TO_S7(sp)
sd s8, SWITCH_TO_S8(sp)
sd s9, SWITCH_TO_S9(sp)
sd s10, SWITCH_TO_S10(sp)
sd s11, SWITCH_TO_S11(sp)
csrr s11, CSR_SATP
sd s11, SWITCH_TO_SATP(sp)
sd sp, PCB_KERNEL_SP(tp)
switch_to_restore:
// restore next
addi tp, a1, 0
ld sp, PCB_KERNEL_SP(tp)
ld s0, SWITCH_TO_SATP(sp)
fence
fence.i
sfence.vma
fence
fence.i
csrw CSR_SATP, s0
fence
fence.i
sfence.vma
fence
fence.i
ld s0, SWITCH_TO_S0(sp)
ld s1, SWITCH_TO_S1(sp)
ld s2, SWITCH_TO_S2(sp)
ld s3, SWITCH_TO_S3(sp)
ld s4, SWITCH_TO_S4(sp)
ld s5, SWITCH_TO_S5(sp)
ld s6, SWITCH_TO_S6(sp)
ld s7, SWITCH_TO_S7(sp)
ld s8, SWITCH_TO_S8(sp)
ld s9, SWITCH_TO_S9(sp)
ld s10, SWITCH_TO_S10(sp)
ld s11, SWITCH_TO_S11(sp)
ld ra, SWITCH_TO_RA(sp)
addi sp, sp, SWITCH_TO_SIZE
jr ra
ENDPROC(switch_to)
ENTRY(ret_from_exception)
sd sp, PCB_KERNEL_SP(tp)
call handle_signal
ld sp, PCB_KERNEL_SP(tp)
RESTORE_CONTEXT
sret
ENDPROC(ret_from_exception)
ENTRY(exception_handler_entry)
.align 4
SAVE_CONTEXT
/* Load the global pointer */
.option push
.option norelax
la gp, __global_pointer$
.option pop
281282283284285286287288289290291292293294295296297298299300301302303304305306307
csrw CSR_SSCRATCH, x0
/* TODO: load ret_from_exception into $ra
* so that we can return to ret_from_exception
* when interrupt_help complete.
*/
la ra, ret_from_exception
/* TODO: call interrupt_helper
* note: dont forget to pass parameters for it.
*/
ld a0, PCB_KERNEL_SP(tp)
csrr a1, CSR_STVAL
csrr a2, CSR_SCAUSE
mv a3, tp
la t0, interrupt_helper
jr t0
ENDPROC(exception_handler_entry)
ENTRY(do_sret)
csrw CSR_SEPC, ra
sret
ENDPROC(do_sret)