Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Porting RISC-V processor with CLIC interrupt system #279

Closed
fanghuaqi opened this issue Oct 24, 2020 · 3 comments
Closed

Porting RISC-V processor with CLIC interrupt system #279

fanghuaqi opened this issue Oct 24, 2020 · 3 comments

Comments

@fanghuaqi
Copy link

Hi there, I am working on porting RISC-V processor with clic interrupt system, not the clint + plic version.

For clic spec, please check https://github.com/riscv/riscv-fast-interrupt/blob/master/clic.adoc

I tried to use a lowest priority interrupt(Machine software interrupt) to do context switch, but I found that if I trigger this interrupt in task context, it will not be handled due to interrupt is disabled globally, but if I enable irq, the kernel will work incorrectly, could you give me some hints on it?

You can find my porting code in https://github.com/nuclei-community/lk/tree/dev_nuclei/arch/riscv

Thanks
Huaqi

@fanghuaqi
Copy link
Author

Hi there, I updated the code with more details, in the portable code of arch_context_switch function, I use software interrupt function to trigger thread switch, in interrupt context switch it is ok, since the interrupt will be reenabled, but if I do it in task switch, the interrupt is disabled before arch_context_switch, so I just use spin_unlock to remove lock and use arch_enable_ints to re-enable interrupt? Is it ok?

void arch_context_switch(thread_t *oldthread, thread_t *newthread) {
    DEBUG_ASSERT(arch_ints_disabled());
    if (oldthread->stack_size > 0) {
        if (newthread->stack_size == 0) { // switch back to idle task, manually create a stack for it
            newthread->stack = initial_stack;
            newthread->stack_size = sizeof(initial_stack);
            newthread->entry= idle_thread_routine;
            arch_thread_initialize(newthread);
        }

        rt_interrupt_from_thread = &(oldthread->arch.cs_frame);
        rt_interrupt_to_thread = &(newthread->arch.cs_frame);
        riscv_trigger_preempt(); // trigger a software interrupt to do task context switch
        if (rt_thread_switch_interrupt_flag == 0) { // task switch in task context
            spin_unlock(&thread_lock); // remove lock, otherwise the thread might spin in lock 
            arch_enable_ints();   // enable interrupt for software interrupt come
        }
    } else { // First task started, switch from idle
        arch_context_start((unsigned long)&(newthread->arch.cs_frame));
        // never return
    }
}

Or is there any porting requirements for this arch_context_switch function?

Thanks
Huaqi

@fanghuaqi
Copy link
Author

@fanghuaqi
Copy link
Author

See PR #281

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant