Created
October 20, 2019 11:08
-
-
Save knknkn1162/5c547113940b3afebb39cedb03c294f7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// lib/sbi/sbi_hart.c | |
// sbi_hart_switch_mode(hartid, scratch->next_arg1, scratch->next_addr, scratch->next_mode, false); | |
void __attribute__((noreturn)) | |
sbi_hart_switch_mode(unsigned long arg0, unsigned long arg1, | |
unsigned long next_addr, unsigned long next_mode, | |
bool next_virt) | |
{ | |
unsigned long val; | |
switch (next_mode) { // scratch->next_mode | |
case PRV_M: | |
break; | |
case PRV_S: // here! | |
if (!misa_extension('S')) | |
sbi_hart_hang(); | |
break; | |
case PRV_U: | |
if (!misa_extension('U')) | |
sbi_hart_hang(); | |
break; | |
default: | |
sbi_hart_hang(); | |
} | |
val = csr_read(CSR_MSTATUS); | |
val = INSERT_FIELD(val, MSTATUS_MPP, next_mode); | |
val = INSERT_FIELD(val, MSTATUS_MPIE, 0); | |
csr_write(CSR_MSTATUS, val); | |
csr_write(CSR_MEPC, next_addr); | |
if (next_mode == PRV_S) { // here! | |
csr_write(CSR_STVEC, next_addr); | |
csr_write(CSR_SSCRATCH, 0); | |
csr_write(CSR_SIE, 0); | |
csr_write(CSR_SATP, 0); | |
} else if (next_mode == PRV_U) { | |
csr_write(CSR_UTVEC, next_addr); | |
csr_write(CSR_USCRATCH, 0); | |
csr_write(CSR_UIE, 0); | |
} | |
register unsigned long a0 asm("a0") = arg0; | |
register unsigned long a1 asm("a1") = arg1; | |
__asm__ __volatile__("mret" : : "r"(a0), "r"(a1)); | |
__builtin_unreachable(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment