version 1.13, 2020/10/31 15:18:09 |
version 1.14, 2020/11/04 06:56:56 |
|
|
|
|
#ifdef _LP64 |
#ifdef _LP64 |
li t0, SR_U64|SR_S64 |
li t0, SR_U64|SR_S64 |
li t1, SR_IM|SR_VM|SR_EI |
li t1, SR_IM|SR_SIE |
csrs sstatus, t0 |
csrs sstatus, t0 |
#else |
#else |
li t1, SR_IM|SR_VM|SR_U64|SR_S64|R_EI |
li t1, SR_IM|SR_U64|SR_S64|SR_EI |
#endif |
#endif |
csrc sstatus, t1 |
csrc sstatus, t1 |
|
|
|
|
bgtz a6, .Lfill // loop if more |
bgtz a6, .Lfill // loop if more |
#endif |
#endif |
|
|
csrw sptbr, s1 // set the page table base |
|
li t0, SR_VM |
|
csrs sstatus, t0 // Enable VM |
|
|
|
// We should have a VM so let's start using our real addresses |
// We should have a VM so let's start using our real addresses |
lui t0, %hi(.Lmmu_on) // load hi part of absolute address |
lui t0, %hi(.Lmmu_on) // load hi part of absolute address |
jr t0, %lo(.Lmmu_on) // jump to absolute address |
jr t0, %lo(.Lmmu_on) // jump to absolute address |
Line 185 ENTRY_NP(cpu_switchto) |
|
Line 181 ENTRY_NP(cpu_switchto) |
|
|
|
REG_S sp, L_MD_KTF(a0) // record trapframe pointer |
REG_S sp, L_MD_KTF(a0) // record trapframe pointer |
|
|
csrrci t0, sstatus, SR_EI // # disable interrupts |
csrrci t0, sstatus, SR_SIE // # disable interrupts |
|
|
mv tp, a1 // # put the new lwp in thread pointer |
mv tp, a1 // # put the new lwp in thread pointer |
|
|
Line 274 ENTRY_NP(cpu_fast_switchto) |
|
Line 270 ENTRY_NP(cpu_fast_switchto) |
|
mv s0, tp // remember curlwp |
mv s0, tp // remember curlwp |
mv s1, sp // remember kernel stack |
mv s1, sp // remember kernel stack |
|
|
#if 0 |
csrrci t0, sstatus, SR_SIE // disable interrupts |
csrrci t0, sstatus, SR_EI // disable interrupts |
|
#endif |
|
PTR_L t1, L_CPU(tp) // get curcpu() |
PTR_L t1, L_CPU(tp) // get curcpu() |
|
|
PTR_S sp, L_MD_KTF(tp) // save trapframe ptr in oldlwp |
PTR_S sp, L_MD_KTF(tp) // save trapframe ptr in oldlwp |
mv tp, a0 // set thread pointer to newlwp |
mv tp, a0 // set thread pointer to newlwp |
PTR_S tp, CI_CURLWP(t1) // update curlwp |
PTR_S tp, CI_CURLWP(t1) // update curlwp |
PTR_L sp, L_MD_KTF(tp) // switch to its stack |
PTR_L sp, L_MD_KTF(tp) // switch to its stack |
#if 0 |
|
csrw sstatus, t0 // reenable interrupts |
csrw sstatus, t0 // reenable interrupts |
#endif |
|
call _C_LABEL(softint_dispatch) |
call _C_LABEL(softint_dispatch) |
#if 0 |
csrrci t0, sstatus, SR_SIE // disable interrupts |
csrrci t0, sstatus, SR_EI // disable interrupts |
|
#endif |
|
PTR_L t1, L_CPU(tp) // get curcpu() again |
PTR_L t1, L_CPU(tp) // get curcpu() again |
mv tp, s0 // return to pinned lwp |
mv tp, s0 // return to pinned lwp |
PTR_S tp, CI_CURLWP(t1) // restore curlwp |
PTR_S tp, CI_CURLWP(t1) // restore curlwp |
#if 0 |
|
csrw sstatus, t0 // reeanble interrupts |
csrw sstatus, t0 // reeanble interrupts |
#endif |
|
mv sp, s1 // restore stack pointer |
mv sp, s1 // restore stack pointer |
|
|
REG_L ra, (TF_RA + CALLFRAME_RA)(sp) // get return address |
REG_L ra, (TF_RA + CALLFRAME_RA)(sp) // get return address |
Line 378 ENTRY_NP(cpu_exception_handler) |
|
Line 366 ENTRY_NP(cpu_exception_handler) |
|
|
|
bltz a3, intr_handler // MSB is set if interrupt |
bltz a3, intr_handler // MSB is set if interrupt |
|
|
// badaddr is only relavent for non-interrupts |
// stval is only relavent for non-interrupts |
csrr a4, sbadaddr // get badaddr |
csrr a4, stval // get stval |
REG_S a4, TF_BADADDR(sp) |
REG_S a4, TF_TVAL(sp) |
|
|
beqz t1, trap_user // this was a user trap |
beqz t1, trap_user // this was a user trap |
// This was a kernel exception |
// This was a kernel exception |
Line 390 exception_kernexit: |
|
Line 378 exception_kernexit: |
|
// trap or interrupt). Simply return the volatile registers and the |
// trap or interrupt). Simply return the volatile registers and the |
// exception PC and status, load the saved SP from the trapframe, and |
// exception PC and status, load the saved SP from the trapframe, and |
// return from the exception |
// return from the exception |
csrrci zero, sstatus, SR_EI // disable interrupts |
csrrci zero, sstatus, SR_SIE // disable interrupts |
|
|
REG_L ra, TF_RA(sp) // restore return address |
REG_L ra, TF_RA(sp) // restore return address |
REG_L gp, TF_GP(sp) // restore gp |
REG_L gp, TF_GP(sp) // restore gp |
|
|
REG_S s10, TF_S10(sp) // only save from userland |
REG_S s10, TF_S10(sp) // only save from userland |
REG_S s11, TF_S11(sp) // only save from userland |
REG_S s11, TF_S11(sp) // only save from userland |
|
|
csrsi sstatus, SR_EI // reenable interrupts |
csrsi sstatus, SR_SIE // reenable interrupts |
|
|
li t0, CAUSE_SYSCALL // let's see if this was a syscall |
li t0, CAUSE_SYSCALL // let's see if this was a syscall |
beq a3, t0, trap_syscall // yes it was |
beq a3, t0, trap_syscall // yes it was |
|
|
_C_LABEL(exception_userexit): |
_C_LABEL(exception_userexit): |
INT_L t0, L_MD_ASTPENDING(tp) // ast pending? |
INT_L t0, L_MD_ASTPENDING(tp) // ast pending? |
bnez t0, trap_doast // yes, handle it. |
bnez t0, trap_doast // yes, handle it. |
csrrci zero, sstatus, SR_EI // disable interrupts |
csrrci zero, sstatus, SR_SIE // disable interrupts |
csrw sscratch, tp // show we are coming from userland |
csrw sscratch, tp // show we are coming from userland |
REG_L tp, TF_TP(sp) // only restore from userland |
REG_L tp, TF_TP(sp) // only restore from userland |
REG_L s0, TF_S0(sp) // only restore from userland |
REG_L s0, TF_S0(sp) // only restore from userland |