pussuw edited a comment on pull request #5782:
URL: https://github.com/apache/incubator-nuttx/pull/5782#issuecomment-1076670069
Thank you for your comments. Here are a few considerations to your questions.
>How about we trigger software interrupt(SSIP) instead ECALL?
This mechanism could maybe be used, but is not necessary, as the asm
functions provided here do the same. Also, the SW interrupt is typically used
for inter-processor communication (IPI) and I would like to keep that option
open for a true SMP.
> Can we fake CPU by modifying CSR_STATUS to match the ECALL condition and
ghen jump to exception_common directly?
Not really, in my opinion this gets extremely complicated.
1. Sharing the IRQ stack will break this
2. I don't know how the mcause/scause registers will behave in this case.
Are these even writable (need to check tomorrow, I don't think so).
3. Finally, the CURRENT_REGS behavior. CURRENT_REGS != NULL is tested in
many places to guess whether the SW is in IRQ or not
I would keep the interrupt handling separate, it is quite mature code and I
would rather not modify it lightly.
> It's different from the active context switch, the passive context
switch(e.g. the block thread wake up by an interrupt handler) since the
interrupt handle already run in S-mode:
> The exception entry pointer already save the current thread context for us
so we can restore the unblock thread context directly without trap to M-mode
Absolutely true, and this is what is done in this implementation also
>My understanding is different from yours: user task need issue syscall here
otherwise how the thread can raise the privilege to S-mode?
This is also true. The user thread must use syscall to raise privilege to
S-mode / kernel mode. But a context switch syscall is never sent by the
application directly from **user mode**. This happens only when the user task
is already executing kernel code in privileged mode. How the task got there can
happen e.g. via sem_wait() or some other synchronization mechanism / timer
interrupt / other interrupt etc. In any case, at this point the user task is
already in **privileged mode**, and thus any sys_call() (including
SYS_switch_context) will be executed from privileged mode. If that uses ecall,
then the privilege will raise from S->M which is not what we want.
This is the only place where SYS_switch_context exists. The macro takes in
tcb->xcp.regs from task that is to be preempted as arg1, and the task to be
activated as arg2. Only the kernel can do this, as only the kernel knows the
tcb:s. The same goes for the other context handling SYS_xxx numbers. These have
been replaced by the asm functions, because e.g. in the below case sys_call2
would execute ecall.
```
#define riscv_switchcontext(saveregs, restoreregs) \
sys_call2(SYS_switch_context, (uintptr_t)saveregs, (uintptr_t)restoreregs)
```
> No, all syscalls(either reserved or normal) are for user space(U-mode) to
initiate the designed functionality to kernel space.
Also true. But with the old implementation the user task can / is already in
kernel space, when e.g. sys_call(SYS_context_switch) is executed. If sys_call
executes ecall instruction, again we raise privilege from S->M (or M->M in the
case of the flat build). This is the case for many (not all, like I said, sorry
about that) reserved syscalls.
>The suggestion look reasonable, sys_call0-6 is directly called by user
space code, libc/machine is a better place. But, we can do the change for all
arch in a new patch.
I agree, a new patch is better for this. This patch is already very big. And
I still have the CONFIG_BUILD_KERNEL code to give for review (it's also done) :)
On a last note, I think I chose the naming of "ksys_call()" quite poorly.
Actually, the function is just a trampoline to execute the asm function
riscv_syscall_dispatch. A trampoline is required to store the original return
address, so the "ksys_call()" return procedure will know where it came from
originally (like with ecall you know from EPC, but emulated with SW!)
>Ok, it just has the S-mode timer interrupt pending bit(STIP), so we have:
> Let M-mode simulate the software timer and access the functionality
through ECALL and trigger the interrupt by STIP
> Use the external hardware time instead
>To support cpuid and timer, S-mode has to talk with M-mode. How do you
reduce the coupling since we can't assume M-mode is also running NuttX? Do you
plan reuse OpenSBI interface?
I don't plan to use OpenSBI. The coupling should/could be handled somehow
differently. However, if NuttX is running on a hart, no other OS can run on the
same hart, so using my "miniSBI" is perfectly safe, **for that hart**.
Obviously tampering with other harts this will fail horribly...
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]