Skip to content

Instantly share code, notes, and snippets.

@knknkn1162
Created October 20, 2019 11:08
Show Gist options
  • Save knknkn1162/5c547113940b3afebb39cedb03c294f7 to your computer and use it in GitHub Desktop.
Save knknkn1162/5c547113940b3afebb39cedb03c294f7 to your computer and use it in GitHub Desktop.
// 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