diff --git a/arch/risc-v/include/rv32im/irq.h b/arch/risc-v/include/rv32im/irq.h index 888d160f41..35fbe814cf 100644 --- a/arch/risc-v/include/rv32im/irq.h +++ b/arch/risc-v/include/rv32im/irq.h @@ -1,37 +1,20 @@ /**************************************************************************** * arch/risc-v/include/rv32im/irq.h * - * Copyright (C) 2011, 2013, 2015 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at * - * Modified for RISC-V: + * http://www.apache.org/licenses/LICENSE-2.0 * - * Copyright (C) 2016 Ken Pettit. All rights reserved. - * Author: Ken Pettit - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. * ****************************************************************************/ @@ -53,6 +36,17 @@ * Pre-processor Definitions ****************************************************************************/ +/* In mstatus register */ + +#define MSTATUS_MIE (0x1 << 3) /* Machine Interrupt Enable */ +#define MSTATUS_MPIE (0x1 << 7) /* Machine Previous Interrupt Enable */ +#define MSTATUS_MPPM (0x3 << 11) /* Machine Previous Privilege (m-mode) */ + +/* In mie (machine interrupt enable) register */ + +#define MIE_MTIE (0x1 << 7) /* Machine Timer Interrupt Enable */ +#define MIE_MEIE (0x1 << 11) /* Machine External Interrupt Enable */ + /* Configuration ************************************************************/ /* How many nested system calls should we support? */ diff --git a/arch/risc-v/include/rv32im/syscall.h b/arch/risc-v/include/rv32im/syscall.h index 8be3c75e66..0ec1f88897 100644 --- a/arch/risc-v/include/rv32im/syscall.h +++ b/arch/risc-v/include/rv32im/syscall.h @@ -1,35 +1,20 @@ /**************************************************************************** * arch/risc-v/include/rv32im/syscall.h * - * Copyright (C) 2011-2013, 2015 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. * ****************************************************************************/ @@ -56,11 +41,12 @@ #define SYS_syscall 0x00 -/* Configuration ********************************************************************/ +/* Configuration ************************************************************/ + /* SYS call 1 and 2 are defined for internal use by the RISC-V port (see - * arch/riscv/include/mips32/syscall.h). In addition, SYS call 3 is the return from - * a SYS call in kernel mode. The first four syscall values must, therefore, be - * reserved (0 is not used). + * arch/riscv/include/mips32/syscall.h). In addition, SYS call 3 is the + * return from a SYS call in kernel mode. The first four syscall values + * must, therefore, be reserved (0 is not used). */ #ifdef CONFIG_BUILD_KERNEL @@ -71,13 +57,24 @@ # endif #endif -/* sys_call macros ******************************************************************/ +/* sys_call macros **********************************************************/ #ifndef __ASSEMBLY__ -/* Context switching system calls ***************************************************/ +/* Context switching system calls *******************************************/ -/* SYS call 0: (not used) */ +/* SYS call 0: + * + * int up_saveusercontext(uint32_t *saveregs); + * + * Return: + * 0: Normal Return + * 1: Context Switch Return + */ + +#define SYS_save_context (0) +#define up_saveusercontext(saveregs) \ + (int)sys_call1(SYS_save_context, (uintptr_t)saveregs) /* SYS call 1: * diff --git a/arch/risc-v/src/rv32im/riscv_schedulesigaction.c b/arch/risc-v/src/rv32im/riscv_schedulesigaction.c new file mode 100644 index 0000000000..00aef90788 --- /dev/null +++ b/arch/risc-v/src/rv32im/riscv_schedulesigaction.c @@ -0,0 +1,195 @@ +/**************************************************************************** + * arch/risc-v/src/rv32im/riscv_schedulesigaction.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'igdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + uint32_t int_ctx; + + sinfo("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (!tcb->xcp.sigdeliver) + { + /* First, handle some special cases when the signal is + * being delivered to the currently executing task. + */ + + sinfo("rtcb=0x%p g_current_regs=0x%p\n", + this_task(), g_current_regs); + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and + * a task is signalling itself for some reason. + */ + + if (!g_current_regs) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the + * interrupted task is the same as the one that + * must receive the signal, then we will have to modify + * the return state as well as the state in the TCB. + * + * Hmmm... there looks like a latent bug here: The following + * logic would fail in the strange case where we are in an + * interrupt handler, the thread is signalling itself, but + * a context switch to another task has occurred so that + * g_current_regs does not refer to the thread of this_task()! + */ + + else + { + /* Save the return EPC and STATUS registers. These will be + * restored by the signal trampoline after the signals have + * been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_epc = g_current_regs[REG_EPC]; + tcb->xcp.saved_int_ctx = g_current_regs[REG_INT_CTX]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + g_current_regs[REG_EPC] = (uint32_t)up_sigdeliver; + + int_ctx = g_current_regs[REG_INT_CTX]; + int_ctx &= ~MSTATUS_MIE; + + g_current_regs[REG_INT_CTX] = int_ctx; + + /* And make sure that the saved context in the TCB + * is the same as the interrupt return context. + */ + + up_savestate(tcb->xcp.regs); + + sinfo("PC/STATUS Saved: %08x/%08x New: %08x/%08x\n", + tcb->xcp.saved_epc, tcb->xcp.saved_int_ctx, + g_current_regs[REG_EPC], g_current_regs[REG_INT_CTX]); + } + } + + /* Otherwise, we are (1) signaling a task is not running + * from an interrupt handler or (2) we are not in an + * interrupt handler and the running task is signalling + * some non-running task. + */ + + else + { + /* Save the return EPC and STATUS registers. These will be + * restored by the signal trampoline after the signals have + * been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_epc = tcb->xcp.regs[REG_EPC]; + tcb->xcp.saved_int_ctx = tcb->xcp.regs[REG_INT_CTX]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + tcb->xcp.regs[REG_EPC] = (uint32_t)up_sigdeliver; + + int_ctx = tcb->xcp.regs[REG_INT_CTX]; + int_ctx &= ~MSTATUS_MIE; + + tcb->xcp.regs[REG_INT_CTX] = int_ctx; + + sinfo("PC/STATUS Saved: %08x/%08x New: %08x/%08x\n", + tcb->xcp.saved_epc, tcb->xcp.saved_int_ctx, + tcb->xcp.regs[REG_EPC], tcb->xcp.regs[REG_INT_CTX]); + } + } + + leave_critical_section(flags); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/risc-v/src/rv32im/riscv_swint.c b/arch/risc-v/src/rv32im/riscv_swint.c index 21712f51ef..51204cd0cd 100644 --- a/arch/risc-v/src/rv32im/riscv_swint.c +++ b/arch/risc-v/src/rv32im/riscv_swint.c @@ -1,35 +1,20 @@ /**************************************************************************** - * arch/riscv/src/rv32im/up_swint.c + * arch/risc-v/src/rv32im/riscv_swint.c * - * Copyright (C) 2011-2012, 2015, 2019 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. * ****************************************************************************/ @@ -151,10 +136,39 @@ int up_swint(int irq, FAR void *context, FAR void *arg) up_registerdump(regs); #endif + /* Skip ECALL instruction */ + + regs[REG_EPC] += 4; + /* Handle the SWInt according to the command in $a0 */ switch (regs[REG_A0]) { + /* A0=SYS_save_context: This is a save context command: + * + * int up_saveusercontext(uint32_t *saveregs); + * + * At this point, the following values are saved in context: + * + * A0 = SYS_save_context + * A1 = saveregs + * + * Return: + * 0: Normal return + * 1: Context switch return + * + * In this case, we simply need to copy the current registers to the + * save register space references in the saved A1 and return. + */ + + case SYS_save_context: + { + DEBUGASSERT(regs[REG_A1] != 0); + up_copystate((uint32_t *)regs[REG_A1], regs); + ((uint32_t *)regs[REG_A1])[REG_A0] = 1; + } + break; + /* A0=SYS_restore_context: This a restore context command: * * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function;