Skip to content

Commit

Permalink
core: riscv: Improve thread user mode record
Browse files Browse the repository at this point in the history
The following steps descript the program flow of kernel context during
entering and exiting user mode:

1. thread_enter_user_mode(): prepare user mode context
2. __thread_enter_user_mode(): allocate thread_user_mode_rec from kernel
   stack, and save kernel RA and callee-saved registers into
   thread_user_mode_rec. Save kernel SP into thread context.
   Enter user mode context.

If there is a user ecall which wants to return to kernel mode:
  3. ecall_from_user(): Already set kernel SP, GP, and TP.
  4. setup_unwind_user_mode(): prepare to return to kernel mode.
If there is a user abort which should return to kernel mode:
  3. abort_from_user(): Already set kernel SP, GP, and TP.
  4. handle_user_mode_panic(): prepare to return to kernel mode.

5. XRET to kernel mode with kernel SP, GP, and TP.
6. thread_unwind_user_mode(): Restore kernel RA and callee-saved
   registers from thread_user_mode_rec.

Thus, it's unnecessary to save kernel SP and GP into
thread_user_mode_rec, since they have already set by trap handler and
it's unnecessary to set them again in thread_unwind_user_mode().

Also, rename THREAD_USER_MODE_REC_XX to their register names.

Signed-off-by: Alvin Chang <alvinga@andestech.com>
  • Loading branch information
gagachang committed Aug 18, 2024
1 parent 04cf678 commit 4930cbb
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 27 deletions.
8 changes: 4 additions & 4 deletions core/arch/riscv/include/kernel/thread_private_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ struct thread_user_mode_rec {
unsigned long pad;
/*
* x[] is used to save registers for user/kernel context-switching
* 0-3: ra-tp
* 4-6: s0-s1
* 6-15: s2-s11
* 0: ra
* 1-2: s0-s1
* 3-12: s2-s11
*/
unsigned long x[16];
unsigned long x[13];
};

extern long thread_user_kcode_offset;
Expand Down
10 changes: 4 additions & 6 deletions core/arch/riscv/kernel/asm-defines.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,12 @@ DEFINES
/* struct thread_user_mode_rec */
DEFINE(THREAD_USER_MODE_REC_CTX_REGS_PTR,
offsetof(struct thread_user_mode_rec, ctx_regs_ptr));
DEFINE(THREAD_USER_MODE_REC_X1,
DEFINE(THREAD_USER_MODE_REC_RA,
offsetof(struct thread_user_mode_rec, x[0]));
DEFINE(THREAD_USER_MODE_REC_X4,
DEFINE(THREAD_USER_MODE_REC_S0,
offsetof(struct thread_user_mode_rec, x[1]));
DEFINE(THREAD_USER_MODE_REC_S2,
offsetof(struct thread_user_mode_rec, x[3]));
DEFINE(THREAD_USER_MODE_REC_X8,
offsetof(struct thread_user_mode_rec, x[4]));
DEFINE(THREAD_USER_MODE_REC_X18,
offsetof(struct thread_user_mode_rec, x[6]));
DEFINE(THREAD_USER_MODE_REC_SIZE, sizeof(struct thread_user_mode_rec));

/* struct thread_abort_regs */
Expand Down
26 changes: 9 additions & 17 deletions core/arch/riscv/kernel/thread_rv.S
Original file line number Diff line number Diff line change
Expand Up @@ -537,30 +537,22 @@ END_FUNC trap_from_user

/*
* void thread_unwind_user_mode(uint32_t ret, uint32_t exit_status0,
* uint32_t exit_status1);
* uint32_t exit_status1);
* See description in thread.h
*/
FUNC thread_unwind_user_mode , :

/* Store the exit status */
load_xregs sp, THREAD_USER_MODE_REC_CTX_REGS_PTR, REG_A3, REG_A5
sw a1, (a4)
sw a2, (a5)

/* Save user callee regs */
/* Save user callee-saved regs */
store_xregs a3, THREAD_CTX_REG_S0, REG_S0, REG_S1
store_xregs a3, THREAD_CTX_REG_S2, REG_S2, REG_S11
store_xregs a3, THREAD_CTX_REG_SP, REG_SP, REG_TP

/* Restore kernel callee regs */
mv a1, sp

load_xregs a1, THREAD_USER_MODE_REC_X1, REG_RA, REG_GP
load_xregs a1, THREAD_USER_MODE_REC_X8, REG_S0, REG_S1
load_xregs a1, THREAD_USER_MODE_REC_X18, REG_S2, REG_S11

/* Restore kernel ra(thread_enter_user_mode()) & callee-saved regs */
load_xregs sp, THREAD_USER_MODE_REC_RA, REG_RA
load_xregs sp, THREAD_USER_MODE_REC_S0, REG_S0, REG_S1
load_xregs sp, THREAD_USER_MODE_REC_S2, REG_S2, REG_S11
add sp, sp, THREAD_USER_MODE_REC_SIZE

/* Return from the call of thread_enter_user_mode() */
ret
END_FUNC thread_unwind_user_mode
Expand All @@ -579,9 +571,9 @@ FUNC __thread_enter_user_mode , :
*/
addi sp, sp, -THREAD_USER_MODE_REC_SIZE
store_xregs sp, THREAD_USER_MODE_REC_CTX_REGS_PTR, REG_A0, REG_A2
store_xregs sp, THREAD_USER_MODE_REC_X1, REG_RA, REG_GP
store_xregs sp, THREAD_USER_MODE_REC_X8, REG_S0, REG_S1
store_xregs sp, THREAD_USER_MODE_REC_X18, REG_S2, REG_S11
store_xregs sp, THREAD_USER_MODE_REC_RA, REG_RA
store_xregs sp, THREAD_USER_MODE_REC_S0, REG_S0, REG_S1
store_xregs sp, THREAD_USER_MODE_REC_S2, REG_S2, REG_S11

/*
* Save the kernel stack pointer in the thread context
Expand Down

0 comments on commit 4930cbb

Please sign in to comment.