URL
https://opencores.org/ocsvn/neorv32/neorv32/trunk
[/] [neorv32/] [trunk/] [sw/] [lib/] [source/] [neorv32_cpu.c] - Diff between revs 18 and 35
Go to most recent revision |
Show entire file |
Details |
Blame |
View Log
Rev 18 |
Rev 35 |
Line 244... |
Line 244... |
* @note This function requires the U extension to be implemented.
|
* @note This function requires the U extension to be implemented.
|
* @note Maybe you should do a fence.i after this.
|
* @note Maybe you should do a fence.i after this.
|
**************************************************************************/
|
**************************************************************************/
|
void __attribute__((naked)) neorv32_cpu_goto_user_mode(void) {
|
void __attribute__((naked)) neorv32_cpu_goto_user_mode(void) {
|
|
|
register uint32_t mask = (1<<CPU_MSTATUS_MPP_H) | (1<<CPU_MSTATUS_MPP_L);
|
// make sure to use NO registers in here! -> naked
|
asm volatile ("csrrc zero, mstatus, %[input_j]" : : [input_j] "r" (mask));
|
|
|
|
// return switching to user mode
|
asm volatile ("csrw mepc, ra \n\t" // move return address to mepc so we can return using "mret". also, we can use ra as general purpose register in here
|
asm volatile ("csrw mepc, ra");
|
"li ra, %[input_imm] \n\t" // bit mask to clear the two MPP bits
|
asm volatile ("mret");
|
"csrrc zero, mstatus, ra \n\t" // clear MPP bits -> MPP=u-mode
|
|
"mret \n\t" // return and switch to user mode
|
|
: : [input_imm] "i" ((1<<CPU_MSTATUS_MPP_H) | (1<<CPU_MSTATUS_MPP_L)));
|
}
|
}
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|
© copyright 1999-2025
OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.