diff --git a/arch/misoc/Kconfig b/arch/misoc/Kconfig index eee7005c38e..cc124f77741 100644 --- a/arch/misoc/Kconfig +++ b/arch/misoc/Kconfig @@ -15,17 +15,18 @@ config ARCH_CHIP_LM32 ---help--- LM32 Chip Selected -config ARCH_CHIP_MOR1K - bool "MOR1K" +config ARCH_CHIP_MINERVA + bool "MINERVA" + select MISOC_HAVE_UART1 ---help--- - MOR1K Chip Selected + LambdaConcept MINERVAL Chip Selected endchoice # Misoc Chip Selection config ARCH_CHIP string default "lm32" if ARCH_CHIP_LM32 - default "mor1k" if ARCH_CHIP_MOR1K + default "minerva" if ARCH_CHIP_MINERVA menu "MISOC Peripheral Support" @@ -72,8 +73,8 @@ config MISOC_UART_TX_BUF_SIZE if ARCH_CHIP_LM32 source arch/misoc/src/lm32/Kconfig endif -if ARCH_CHIP_MOR1K -#source arch/misoc/src/mor1k/Kconfig +if ARCH_CHIP_MINERVA +source arch/misoc/src/minerva/Kconfig endif endif # ARCH_MISOC diff --git a/arch/misoc/include/irq.h b/arch/misoc/include/irq.h index 5d5624031ce..8220ef185d6 100644 --- a/arch/misoc/include/irq.h +++ b/arch/misoc/include/irq.h @@ -47,7 +47,12 @@ #include #include -#include +#ifdef CONFIG_ARCH_CHIP_LM32 +# include +#endif +#ifdef CONFIG_ARCH_CHIP_MINERVA +# include +#endif /**************************************************************************** * Pre-processor Definitions @@ -69,8 +74,8 @@ extern "C" #endif irqstate_t up_irq_save(void); -void up_irq_restore(irqstate_t flags); irqstate_t up_irq_enable(void); +void up_irq_restore(irqstate_t flags); #undef EXTERN #ifdef __cplusplus diff --git a/arch/misoc/include/minerva/csrdefs.h b/arch/misoc/include/minerva/csrdefs.h new file mode 100644 index 00000000000..86ee006f01e --- /dev/null +++ b/arch/misoc/include/minerva/csrdefs.h @@ -0,0 +1,80 @@ +/**************************************************************************** + * arch/misoc/src/minerva/csrdefs.h + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +#ifndef __RISCV_CSR_DEFS__ +#define __RISCV_CSR_DEFS__ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CSR_MVENDORID_ADDR 0xf11 +#define CSR_MARCHID_ADDR 0xf12 +#define CSR_MIMPID_ADDR 0xf13 +#define CSR_MHARTID_ADDR 0xf14 +#define CSR_MSTATUS_ADDR 0x300 +#define CSR_MISA_ADDR 0x301 +#define CSR_MEDELEG_ADDR 0x302 +#define CSR_MIDELEG_ADDR 0x303 +#define CSR_MIE_ADDR 0x304 +#define CSR_MTVEC_ADDR 0x305 +#define CSR_MCOUTEREN_ADDR 0x306 +#define CSR_MSCRATCH_ADDR 0x340 +#define CSR_MEPC_ADDR 0x341 +#define CSR_MCAUSE_ADDR 0x342 +#define CSR_MTVAL_ADDR 0x343 +#define CSR_MIP_ADDR 0x344 +#define CSR_IRQ_MASK_ADDR 0x330 +#define CSR_IRQ_PENDING_ADDR 0x360 + +#define CSR_MSTATUS_UIE (1 << 0) +#define CSR_MSTATUS_SIE (1 << 1) +#define CSR_MSTATUS_MIE (1 << 3) +#define CSR_MSTATUS_UPIE (1 << 4) +#define CSR_MSTATUS_SPIE (1 << 5) +#define CSR_MSTATUS_MPIE (1 << 7) +#define CSR_MSTATUS_SPP (1 << 8) +#define CSR_MSTATUS_MPP (1 << 11) +#define CSR_MSTATUS_FS (1 << 13) +#define CSR_MSTATUS_XS (1 << 15) +#define CSR_MSTATUS_MPRV (1 << 17) +#define CSR_MSTATUS_SUM (1 << 18) +#define CSR_MSTATUS_MXR (1 << 19) +#define CSR_MSTATUS_TVM (1 << 20) +#define CSR_MSTATUS_TW (1 << 21) +#define CSR_MSTATUS_TSR (1 << 22) +#define CSR_MSTATUS_SD (1 << 31) + +#endif diff --git a/arch/misoc/include/minerva/irq.h b/arch/misoc/include/minerva/irq.h new file mode 100644 index 00000000000..32a720bfe0f --- /dev/null +++ b/arch/misoc/include/minerva/irq.h @@ -0,0 +1,327 @@ +/**************************************************************************** + * arch/risc-v/include/rv32im/irq.h + * + * Copyright (C) 2011, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Modified for RISC-V: + * + * 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. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_MINERVA_INCLUDE_IRQ_H +#define __ARCH_MINERVA_INCLUDE_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* If this is a kernel build, how many nested system calls should we support? */ + +#define MINERVA_NINTERRUPTS 32 +#define MINERVA_IRQ_SWINT 32 +#define NR_IRQS 33 + +#ifndef CONFIG_SYS_NNEST +# define CONFIG_SYS_NNEST 2 +#endif + +#define REG_X0_NDX 0 +#define REG_X1_NDX 1 +#define REG_X2_NDX 2 +#define REG_X3_NDX 3 +#define REG_X4_NDX 4 +#define REG_X5_NDX 5 +#define REG_X6_NDX 6 +#define REG_X7_NDX 7 +#define REG_X8_NDX 8 +#define REG_X9_NDX 9 +#define REG_X10_NDX 10 +#define REG_X11_NDX 11 +#define REG_X12_NDX 12 +#define REG_X13_NDX 13 +#define REG_X14_NDX 14 +#define REG_X15_NDX 15 +#define REG_X16_NDX 16 +#define REG_X17_NDX 17 +#define REG_X18_NDX 18 +#define REG_X19_NDX 19 +#define REG_X20_NDX 20 +#define REG_X21_NDX 21 +#define REG_X22_NDX 22 +#define REG_X23_NDX 23 +#define REG_X24_NDX 24 +#define REG_X25_NDX 25 +#define REG_X26_NDX 26 +#define REG_X27_NDX 27 +#define REG_X28_NDX 28 +#define REG_X29_NDX 29 +#define REG_X30_NDX 30 +#define REG_X31_NDX 31 + +#define REG_CSR_MSTATUS_NDX 32 +#define REG_CSR_MEPC_NDX 33 +#define REG_CSR_MBADADDR_NDX 34 +#define REG_CSR_MCAUSE_NDX 35 + +#define XCPTCONTEXT_REGS 36 +#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) + +/* In assembly language, values have to be referenced as byte address + * offsets. But in C, it is more convenient to reference registers as + * register save table offsets. + */ + +#ifdef __ASSEMBLY__ +# define REG_X0 (4*REG_X0_NDX) +# define REG_X1 (4*REG_X1_NDX) +# define REG_X2 (4*REG_X2_NDX) +# define REG_X3 (4*REG_X3_NDX) +# define REG_X4 (4*REG_X4_NDX) +# define REG_X5 (4*REG_X5_NDX) +# define REG_X6 (4*REG_X6_NDX) +# define REG_X7 (4*REG_X7_NDX) +# define REG_X8 (4*REG_X8_NDX) +# define REG_X9 (4*REG_X9_NDX) +# define REG_X10 (4*REG_X10_NDX) +# define REG_X11 (4*REG_X11_NDX) +# define REG_X12 (4*REG_X12_NDX) +# define REG_X13 (4*REG_X13_NDX) +# define REG_X14 (4*REG_X14_NDX) +# define REG_X15 (4*REG_X15_NDX) +# define REG_X16 (4*REG_X16_NDX) +# define REG_X17 (4*REG_X17_NDX) +# define REG_X18 (4*REG_X18_NDX) +# define REG_X19 (4*REG_X19_NDX) +# define REG_X20 (4*REG_X20_NDX) +# define REG_X21 (4*REG_X21_NDX) +# define REG_X22 (4*REG_X22_NDX) +# define REG_X23 (4*REG_X23_NDX) +# define REG_X24 (4*REG_X24_NDX) +# define REG_X25 (4*REG_X25_NDX) +# define REG_X26 (4*REG_X26_NDX) +# define REG_X27 (4*REG_X27_NDX) +# define REG_X28 (4*REG_X28_NDX) +# define REG_X29 (4*REG_X29_NDX) +# define REG_X30 (4*REG_X30_NDX) +# define REG_X31 (4*REG_X31_NDX) +# define REG_CSR_MSTATUS (4*REG_CSR_MSTATUS_NDX) +# define REG_CSR_MEPC (4*REG_CSR_MEPC_NDX) +# define REG_CSR_MBADADDR (4*REG_CSR_MBADADDR_NDX) +# define REG_CSR_MCAUSE (4*REG_CSR_MCAUSE_NDX) +#else +# define REG_X0 REG_X0_NDX +# define REG_X1 REG_X1_NDX +# define REG_X2 REG_X2_NDX +# define REG_X3 REG_X3_NDX +# define REG_X4 REG_X4_NDX +# define REG_X5 REG_X5_NDX +# define REG_X6 REG_X6_NDX +# define REG_X7 REG_X7_NDX +# define REG_X8 REG_X8_NDX +# define REG_X9 REG_X9_NDX +# define REG_X10 REG_X10_NDX +# define REG_X11 REG_X11_NDX +# define REG_X12 REG_X12_NDX +# define REG_X13 REG_X13_NDX +# define REG_X14 REG_X14_NDX +# define REG_X15 REG_X15_NDX +# define REG_X16 REG_X16_NDX +# define REG_X17 REG_X17_NDX +# define REG_X18 REG_X18_NDX +# define REG_X19 REG_X19_NDX +# define REG_X20 REG_X20_NDX +# define REG_X21 REG_X21_NDX +# define REG_X22 REG_X22_NDX +# define REG_X23 REG_X23_NDX +# define REG_X24 REG_X24_NDX +# define REG_X25 REG_X25_NDX +# define REG_X26 REG_X26_NDX +# define REG_X27 REG_X27_NDX +# define REG_X28 REG_X28_NDX +# define REG_X29 REG_X29_NDX +# define REG_X30 REG_X30_NDX +# define REG_X31 REG_X31_NDX +# define REG_CSR_MSTATUS REG_CSR_MSTATUS_NDX +# define REG_CSR_MEPC REG_CSR_MEPC_NDX +# define REG_CSR_MBADADDR REG_CSR_MBADADDR_NDX +# define REG_CSR_MCAUSE REG_CSR_MCAUSE_NDX +#endif + +/* Now define more user friendly alternative name that can be used either + * in assembly or C contexts. + */ + +/* $1 = ra: Return address */ + +#define REG_RA REG_X1 + +/* $2 = sp: The value of the stack pointer on return from the exception */ + +#define REG_SP REG_X2 + +/* $3 = gp: Only needs to be saved under conditions where there are + * multiple, per-thread values for the GP. + */ + +#define REG_GP REG_X3 + +/* $4 = tp: Thread Pointer */ + +#define REG_TP REG_X4 + +/* $5-$7 = t0-t2: Caller saved temporary registers */ + +#define REG_T0 REG_X5 +#define REG_T1 REG_X6 +#define REG_T2 REG_X7 + +/* $8 = either s0 or fp: Depends if a frame pointer is used or not */ + +#define REG_S0 REG_X8 +#define REG_FP REG_X8 + +/* $9 = s1: Caller saved register */ + +#define REG_S1 REG_X9 + +/* $10-$17 = a0-a7: Argument registers */ + +#define REG_A0 REG_X10 +#define REG_A1 REG_X11 +#define REG_A2 REG_X12 +#define REG_A3 REG_X13 +#define REG_A4 REG_X14 +#define REG_A5 REG_X15 +#define REG_A6 REG_X16 +#define REG_A7 REG_X17 + +/* $18-$27 = s2-s11: Callee saved registers */ + +#define REG_S2 REG_X18 +#define REG_S3 REG_X19 +#define REG_S4 REG_X20 +#define REG_S5 REG_X21 +#define REG_S6 REG_X22 +#define REG_S7 REG_X23 +#define REG_S8 REG_X24 +#define REG_S9 REG_X25 +#define REG_S10 REG_X26 +#define REG_S11 REG_X27 + +/* $28-$31 = t3-t6: Caller saved temporary registers */ + +#define REG_T3 REG_X28 +#define REG_T4 REG_X29 +#define REG_T5 REG_X30 +#define REG_T6 REG_X31 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* This structure represents the return state from a system call */ + +#ifdef CONFIG_BUILD_KERNEL +struct xcpt_syscall_s +{ + uint32_t sysreturn; /* The return PC */ +}; +#endif + +/* The following structure is included in the TCB and defines the complete + * state of the thread. + */ + +struct xcptcontext +{ +#ifndef CONFIG_DISABLE_SIGNALS + /* The following function pointer is non-NULL if there are pending signals + * to be processed. + */ + + void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* These additional register save locations are used to implement the + * signal delivery trampoline. + */ + + uint32_t saved_epc; /* Trampoline PC */ + uint32_t saved_int_ctx; /* Interrupt context with interrupts disabled. */ + +#ifdef CONFIG_BUILD_KERNEL + /* This is the saved address to use when returning from a user-space signal + * handler. + */ + + uint32_t sigreturn; + +#endif +#endif + +#ifdef CONFIG_BUILD_KERNEL + /* The following array holds information needed to return from each nested + * system call. + */ + + uint8_t nsyscalls; + struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST]; + +#endif + + /* Register save area */ + + uint32_t regs[XCPTCONTEXT_REGS]; +}; + +/**************************************************************************** + * Public Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_INCLUDE_RV32IM_IRQ_H */ diff --git a/arch/misoc/include/minerva/syscall.h b/arch/misoc/include/minerva/syscall.h new file mode 100644 index 00000000000..f4d34e10cf1 --- /dev/null +++ b/arch/misoc/include/minerva/syscall.h @@ -0,0 +1,208 @@ +/**************************************************************************** + * arch/misoc/include/minerva/syscall.h + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_MISOC_INCLUDE_MINERVA_SYSCALL_H +#define __ARCH_MISOC_INCLUDE_MINERVA_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +#include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SYS_syscall 0x00 + +/* Configuration ************************************************************/ + +/* SYS call 1 and 2 are defined for internal use by the MINERVA port (see + * arch/miscoc/include/minerva/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 +# ifndef CONFIG_SYS_RESERVED +# error "CONFIG_SYS_RESERVED must be defined to the value 4" +# elif CONFIG_SYS_RESERVED != 4 +# error "CONFIG_SYS_RESERVED must have the value 4" +# endif +#endif + +/* sys_call macros **********************************************************/ + +#ifndef __ASSEMBLY__ + +/* Context switching system calls *******************************************/ + +/* SYS call 0: (not used) */ + +/* SYS call 1: + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + */ + +#define SYS_restore_context (1) +#define up_fullcontextrestore(restoreregs) \ + (void)sys_call1(SYS_restore_context, (uintptr_t)restoreregs) + +/* SYS call 2: + * + * void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); + */ + +#define SYS_switch_context (2) +#define up_switchcontext(saveregs, restoreregs) \ + (void)sys_call2(SYS_switch_context, (uintptr_t)saveregs, \ + (uintptr_t)restoreregs) + +#ifdef CONFIG_BUILD_KERNEL + +/* SYS call 3: + * + * void up_syscall_return(void); + */ + +#define SYS_syscall_return (3) +#define up_syscall_return() (void)sys_call0(SYS_syscall_return) + +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +# define EXTERN extern "C" +extern "C" +{ +#else +# define EXTERN extern +#endif + +/**************************************************************************** + * Name: up_syscall0 + * + * Description: + * System call SYS_ argument and no additional parameters. + * + ****************************************************************************/ + +uintptr_t sys_call0(unsigned int nbr); + +/**************************************************************************** + * Name: up_syscall1 + * + * Description: + * System call SYS_ argument and one additional parameter. + * + ****************************************************************************/ + +uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1); + +/**************************************************************************** + * Name: up_syscall2 + * + * Description: + * System call SYS_ argument and two additional parameters. + * + ****************************************************************************/ + +uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, uintptr_t parm2); + +/**************************************************************************** + * Name: up_syscall3 + * + * Description: + * System call SYS_ argument and three additional parameters. + * + ****************************************************************************/ + +uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, + uintptr_t parm3); + +/**************************************************************************** + * Name: up_syscall4 + * + * Description: + * System call SYS_ argument and four additional parameters. + * + ****************************************************************************/ + +uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, + uintptr_t parm3, uintptr_t parm4); + +/**************************************************************************** + * Name: up_syscall5 + * + * Description: + * System call SYS_ argument and five additional parameters. + * + ****************************************************************************/ + +uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, + uintptr_t parm3, uintptr_t parm4, uintptr_t parm5); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MISOC_INCLUDE_MINERVA_SYSCALL_H */ diff --git a/arch/misoc/include/minerva/types.h b/arch/misoc/include/minerva/types.h new file mode 100644 index 00000000000..625a542c0bb --- /dev/null +++ b/arch/misoc/include/minerva/types.h @@ -0,0 +1,94 @@ +/**************************************************************************** + * arch/misoc/include/minerva/types.h + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through stdint.h + */ + +#ifndef __ARCH_MISOC_INCLUDE_MINERVA_TYPES_H +#define __ARCH_MISOC_INCLUDE_MINERVA_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed short _int16_t; +typedef unsigned short _uint16_t; + +typedef signed int _int32_t; +typedef unsigned int _uint32_t; + +typedef signed long long _int64_t; +typedef unsigned long long _uint64_t; +#define __INT64_DEFINED + +/* A pointer is 4 bytes */ + +typedef signed int _intptr_t; +typedef unsigned int _uintptr_t; + +/* This is the size of the interrupt state save returned by up_irq_save(). */ + +typedef unsigned int irqstate_t; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MISOC_INCLUDE_MINERVA_TYPES_H */ diff --git a/arch/misoc/include/stdarg.h b/arch/misoc/include/stdarg.h new file mode 100644 index 00000000000..4491034cf50 --- /dev/null +++ b/arch/misoc/include/stdarg.h @@ -0,0 +1,60 @@ +/**************************************************************************** + * arch/misoc/include/stdarg.h + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_MISOC_INCLUDE_STDARG_H +#define __ARCH_MISOC_INCLUDE_STDARG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* This should work with any modern gcc (newer than 3.4 or so) */ + +#define va_start(v,l) __builtin_va_start(v,l) +#define va_end(v) __builtin_va_end(v) +#define va_arg(v,l) __builtin_va_arg(v,l) +#define va_copy(d,s) __builtin_va_copy(d,s) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef __builtin_va_list va_list; + +#endif /* __ARCH_MISOC_INCLUDE_STDARG_H */ diff --git a/arch/misoc/include/syscall.h b/arch/misoc/include/syscall.h index 709ac8fa075..9fb655dc35d 100644 --- a/arch/misoc/include/syscall.h +++ b/arch/misoc/include/syscall.h @@ -50,4 +50,8 @@ # include #endif +#ifdef CONFIG_ARCH_CHIP_MINERVA +# include +#endif + #endif /* __ARCH_MISOC_INCLUDE_SYSCALL_H */ diff --git a/arch/misoc/src/Makefile b/arch/misoc/src/Makefile index 8d0052578a1..10e753a9897 100644 --- a/arch/misoc/src/Makefile +++ b/arch/misoc/src/Makefile @@ -1,7 +1,7 @@ ############################################################################ # arch/misoc/src/Makefile # -# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -36,7 +36,13 @@ -include $(TOPDIR)/Make.defs -include chip/Make.defs -ARCH_SUBDIR = lm32 +ifeq ($(CONFIG_ARCH_CHIP_LM32),y) + ARCH_SUBDIR = lm32 +endif + +ifeq ($(CONFIG_ARCH_CHIP_MINERVA),y) + ARCH_SUBDIR = minerva +endif ifeq ($(CONFIG_WINDOWS_NATIVE),y) ARCH_SRCDIR = $(TOPDIR)\arch\$(CONFIG_ARCH)\src diff --git a/arch/misoc/src/common/hw/common.h b/arch/misoc/src/common/hw/common.h index a6a7a92159f..e763f835fb7 100644 --- a/arch/misoc/src/common/hw/common.h +++ b/arch/misoc/src/common/hw/common.h @@ -1,7 +1,7 @@ /**************************************************************************** * arch/misoc/src/common/hw/common.h * - * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. * Author: Ramtin Amin * * Redistribution and use in source and binary forms, with or without @@ -36,14 +36,63 @@ #ifndef __ARCH_MISOC_SRC_COMMON_HW_COMMON_H #define __ARCH_MISOC_SRC_COMMON_HW_COMMON_H +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +/* To overwrite CSR accessors, define extern, non-inlined versions + * of csr_read[bwl]() and csr_write[bwl](), and define + * CSR_ACCESSORS_DEFINED. + */ + +#ifndef CSR_ACCESSORS_DEFINED +#define CSR_ACCESSORS_DEFINED + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + #ifdef __ASSEMBLER__ # define MMPTR(x) x #else # define MMPTR(x) (*((volatile unsigned int *)(x))) -#endif +static inline void csr_writeb(uint8_t value, uint32_t addr) +{ + *((volatile uint8_t *)addr) = value; +} + +static inline uint8_t csr_readb(uint32_t addr) +{ + return *(volatile uint8_t *)addr; +} + +static inline void csr_writew(uint16_t value, uint32_t addr) +{ + *((volatile uint16_t *)addr) = value; +} + +static inline uint16_t csr_readw(uint32_t addr) +{ + return *(volatile uint16_t *)addr; +} + +static inline void csr_writel(uint32_t value, uint32_t addr) +{ + *((volatile uint32_t *)addr) = value; +} + +static inline uint32_t csr_readl(uint32_t addr) +{ + return *(volatile uint32_t *)addr; +} + +#endif /* !__ASSEMBLER__ */ +#endif /* !CSR_ACCESSORS_DEFINED */ #endif /* __ARCH_MISOC_SRC_COMMON_HW_COMMON_H */ diff --git a/arch/misoc/src/common/misoc_net.c b/arch/misoc/src/common/misoc_net.c index af696a7a5c3..298da7b2d38 100644 --- a/arch/misoc/src/common/misoc_net.c +++ b/arch/misoc/src/common/misoc_net.c @@ -612,6 +612,9 @@ static void misoc_net_interrupt_work(FAR void *arg) net_unlock(); + ethmac_sram_reader_ev_enable_write(1); + ethmac_sram_writer_ev_enable_write(1); + /* Re-enable Ethernet interrupts */ up_enable_irq(ETHMAC_INTERRUPT); @@ -643,6 +646,9 @@ static int misoc_net_interrupt(int irq, FAR void *context, FAR void *arg) * condition here. */ + ethmac_sram_reader_ev_enable_write(0); + ethmac_sram_writer_ev_enable_write(0); + /* TODO: Determine if a TX transfer just completed */ if (ethmac_sram_reader_ev_pending_read() & ETHMAC_EV_SRAM_READER) @@ -820,6 +826,7 @@ static void misoc_net_poll_expiry(int argc, wdparm_t arg, ...) static int misoc_net_ifup(FAR struct net_driver_s *dev) { + irqstate_t flags; FAR struct misoc_net_driver_s *priv = (FAR struct misoc_net_driver_s *)dev->d_private; #ifdef CONFIG_NET_IPv4 @@ -844,6 +851,8 @@ static int misoc_net_ifup(FAR struct net_driver_s *dev) misoc_net_ipv6multicast(priv); #endif + flags = enter_critical_section(); + /* Set and activate a timer process */ (void)wd_start(priv->misoc_net_txpoll, MISOC_NET_WDDELAY, misoc_net_poll_expiry, 1, @@ -855,6 +864,7 @@ static int misoc_net_ifup(FAR struct net_driver_s *dev) /* Enable the RX Event Handler */ ethmac_sram_writer_ev_enable_write(1); + leave_critical_section(flags); return OK; } @@ -884,6 +894,9 @@ static int misoc_net_ifdown(FAR struct net_driver_s *dev) flags = enter_critical_section(); up_disable_irq(ETHMAC_INTERRUPT); + ethmac_sram_reader_ev_enable_write(0); + ethmac_sram_writer_ev_enable_write(0); + /* Cancel the TX poll timer and TX timeout timers */ wd_cancel(priv->misoc_net_txpoll); @@ -1150,10 +1163,10 @@ int misoc_net_initialize(int intf) return -EAGAIN; } - /* clear pending int */ + /* Clear pending int */ - ethmac_sram_writer_ev_pending_write(1); - ethmac_sram_reader_ev_pending_write(1); + ethmac_sram_reader_ev_pending_write(ETHMAC_EV_SRAM_READER); + ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER); /* Initialize the driver structure */ diff --git a/arch/misoc/src/common/misoc_timerisr.c b/arch/misoc/src/common/misoc_timerisr.c index 3c4b4919d36..18d724354f4 100644 --- a/arch/misoc/src/common/misoc_timerisr.c +++ b/arch/misoc/src/common/misoc_timerisr.c @@ -130,8 +130,8 @@ void misoc_timer_initialize(void) * CLOCKS_PER_SEC. */ - timer0_reload_write(SYSTICK_RELOAD); - timer0_load_write(SYSTICK_RELOAD); + timer0_reload_write(SYSTICK_RELOAD * 20); + timer0_load_write(SYSTICK_RELOAD * 20); /* Enable timer */ diff --git a/arch/misoc/src/lm32/lm32_assert.c b/arch/misoc/src/lm32/lm32_assert.c index 9569aae2898..5f57dc20f22 100644 --- a/arch/misoc/src/lm32/lm32_assert.c +++ b/arch/misoc/src/lm32/lm32_assert.c @@ -85,7 +85,12 @@ static void _up_assert(int errorcode) (void)syslog_flush(); - /* Are we in an interrupt handler or the idle task? */ + /* Are we in an interrupt handler or the idle task? + * NOTE: You cannot use the PID to determine if this is an IDLE task. In + * the SMP case, there may be multiple IDLE tasks with different PIDs. The + * only consistent way to test for the IDLE task is to check it is at the + * end of the list (flink == NULL) + */ if (g_current_regs || running_task()->flink == NULL) { diff --git a/arch/misoc/src/lm32/lm32_dumpstate.c b/arch/misoc/src/lm32/lm32_dumpstate.c index 8576c2969bc..a88a3015737 100644 --- a/arch/misoc/src/lm32/lm32_dumpstate.c +++ b/arch/misoc/src/lm32/lm32_dumpstate.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/misoc/src/lm32/lm32_dumpstate.c * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * Ramtin Amin * diff --git a/arch/misoc/src/lm32/lm32_initialize.c b/arch/misoc/src/lm32/lm32_initialize.c index 1c4aeb9eede..6e9d7187210 100644 --- a/arch/misoc/src/lm32/lm32_initialize.c +++ b/arch/misoc/src/lm32/lm32_initialize.c @@ -85,7 +85,9 @@ void up_initialize(void) iob_initialize(); #endif +#if 0 /* REVISIT */ /* Initialize the network cores */ misoc_net_initialize(0); +#endif } diff --git a/arch/misoc/src/lm32/lm32_irq.c b/arch/misoc/src/lm32/lm32_irq.c index 17f7310af5a..78bfa0b3df7 100644 --- a/arch/misoc/src/lm32/lm32_irq.c +++ b/arch/misoc/src/lm32/lm32_irq.c @@ -123,7 +123,7 @@ void up_irq_restore(irqstate_t flags) * ****************************************************************************/ -irqstate_t up_irq_restore(irqstate_t flags) +irqstate_t up_irq_enable(void) { irqstate_t flags; diff --git a/arch/misoc/src/lm32/lm32_swint.c b/arch/misoc/src/lm32/lm32_swint.c index 17bbc487525..3f5aeb73cd2 100644 --- a/arch/misoc/src/lm32/lm32_swint.c +++ b/arch/misoc/src/lm32/lm32_swint.c @@ -134,7 +134,7 @@ int lm32_swint(int irq, FAR void *context, FAR void *arg) { uint32_t *regs = (uint32_t *)context; - DEBUGASSERT(g_current_regs == NULL); + DEBUGASSERT(regs != NULL && regs == g_current_regs); g_current_regs = regs; /* Software interrupt 0 is invoked with REG_A0 (REG_X10) = system call diff --git a/arch/misoc/src/minerva/Kconfig b/arch/misoc/src/minerva/Kconfig new file mode 100644 index 00000000000..91a93b54905 --- /dev/null +++ b/arch/misoc/src/minerva/Kconfig @@ -0,0 +1,35 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_MINERVA + +choice + prompt "Toolchain Selection" + default MINERVA_TOOLCHAIN_GNUW if TOOLCHAIN_WINDOWS + default MINERVA_TOOLCHAIN_GNUL if !TOOLCHAIN_WINDOWS + +config MINERVA_TOOLCHAIN_BUILDROOT + bool "Buildroot (Cygwin or Linux)" + depends on !WINDOWS_NATIVE + select ARCH_TOOLCHAIN_GNU + +config MINERVA_TOOLCHAIN_GNUL + bool "Generic GNU toolchain under Linux (or other POSIX environment)" + select ARCH_TOOLCHAIN_GNU + ---help--- + This option should work for any modern GNU toolchain (GCC 4.5 or newer) + configured for risc64-elf-. + +config MINERVA_TOOLCHAIN_GNUW + bool "Generic GNU toolchain under Windows" + depends on TOOLCHAIN_WINDOWS + select ARCH_TOOLCHAIN_GNU + ---help--- + This option should work for any modern GNU toolchain (GCC 4.5 or newer) + configured for risc64-elf-. + +endchoice # Toolchain Selection + +endif # ARCH_CHIP_MINERVA diff --git a/arch/misoc/src/minerva/Make.defs b/arch/misoc/src/minerva/Make.defs new file mode 100644 index 00000000000..f859b8280da --- /dev/null +++ b/arch/misoc/src/minerva/Make.defs @@ -0,0 +1,55 @@ +############################################################################ +# arch/misoc/src/Makefile +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# Ramtin Amin +# +# 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. +# 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. +# +############################################################################ + +HEAD_ASRC = minerva_vectors.S + +CMN_ASRCS = +CMN_CSRCS = misoc_lowputs.c misoc_serial.c misoc_mdelay.c +CMN_CSRCS += misoc_modifyreg8.c misoc_modifyreg16.c misoc_modifyreg32.c +CMN_CSRCS += misoc_puts.c misoc_udelay.c misoc_timerisr.c misoc_net.c +CMN_CSRCS += misoc_flushcache.c + +CHIP_ASRCS = minerva_syscall.S + +CHIP_CSRCS = minerva_allocateheap.c minerva_assert.c minerva_blocktask.c +CHIP_CSRCS += minerva_copystate.c minerva_createstack.c minerva_decodeirq.c +CHIP_CSRCS += minerva_doirq.c minerva_dumpstate.c minerva_exit.c minerva_idle.c +CHIP_CSRCS += minerva_initialize.c minerva_initialstate.c minerva_interruptcontext.c +CHIP_CSRCS += minerva_irq.c minerva_releasepending.c minerva_releasestack.c +CHIP_CSRCS += minerva_stackframe.c minerva_swint.c minerva_unblocktask.c +CHIP_CSRCS += minerva_reprioritizertr.c minerva_schedulesigaction.c minerva_sigdeliver.c +CHIP_CSRCS += minerva_flushcache.c minerva_doexceptions.c + diff --git a/arch/misoc/src/minerva/Toolchain.defs b/arch/misoc/src/minerva/Toolchain.defs new file mode 100644 index 00000000000..3036dcc1d10 --- /dev/null +++ b/arch/misoc/src/minerva/Toolchain.defs @@ -0,0 +1,44 @@ +############################################################################ +# arch/misoc/src/minerva/Toolchain.defs +# +# Copyright (C) 2012-2013, 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# modified for RISC-V: +# +# 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. +# +############################################################################ + +CROSSDEV = riscv32-unknown-elf- +ARCROSSDEV = riscv32-unknown-elf- +ARCHCPUFLAGS = -march=rv32i + +ifeq ($(CONFIG_DEBUG_SYMBOLS),) +MAXOPTIMIZATION ?= -Os +endif diff --git a/arch/misoc/src/minerva/chip.h b/arch/misoc/src/minerva/chip.h new file mode 100644 index 00000000000..ceddbcb2469 --- /dev/null +++ b/arch/misoc/src/minerva/chip.h @@ -0,0 +1,138 @@ +/**************************************************************************** + * arch/misoc/src/minerva/chip.h + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_MISOC_SRC_MINERVA_CHIP_H +#define __ARCH_MISOC_SRC_MINERVA_CHIP_H 1 + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#include "minerva.h" +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CSR_IRQ_MASK 0x330 +#define CSR_IRQ_PENDING 0x360 + +#define CSR_DCACHE_INFO 0xcc0 + +#define csrr(reg) \ + ({ \ + unsigned long __tmp; \ + asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ + __tmp; \ + }) + +#define csrw(reg, val) \ + ({ \ + if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + { \ + asm volatile ("csrw " #reg ", %0" :: "i"(val)); \ + } \ + else \ + { \ + asm volatile ("csrw " #reg ", %0" :: "r"(val)); \ + } \ + }) + +#define csrs(reg, bit) \ + ({ \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + { \ + asm volatile ("csrrs x0, " #reg ", %0" :: "i"(bit)); \ + } \ + else \ + { \ + asm volatile ("csrrs x0, " #reg ", %0" :: "r"(bit)); \ + } \ + }) + +#define csrc(reg, bit) \ + ({ \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + { \ + asm volatile ("csrrc x0, " #reg ", %0" :: "i"(bit)); \ + } \ + else \ + { \ + asm volatile ("csrrc x0, " #reg ", %0" :: "r"(bit)); \ + } \ + }) + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +static inline unsigned int irq_getie(void) +{ + return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0; +} + +static inline void irq_setie(unsigned int ie) +{ + if (ie) + csrs(mstatus, CSR_MSTATUS_MIE); + else + csrc(mstatus, CSR_MSTATUS_MIE); +} + +static inline unsigned int irq_getmask(void) +{ + unsigned int mask; + asm volatile ("csrr %0, %1":"=r" (mask):"i"(CSR_IRQ_MASK)); + return mask; +} + +static inline void irq_setmask(unsigned int mask) +{ + asm volatile ("csrw %0, %1"::"i" (CSR_IRQ_MASK), "r"(mask)); +} + +static inline unsigned int irq_pending(void) +{ + unsigned int pending; + asm volatile ("csrr %0, %1":"=r" (pending):"i"(CSR_IRQ_PENDING)); + return pending; +} + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_MISOC_SRC_MINERVA_CHIP_H */ diff --git a/arch/misoc/src/minerva/minerva.h b/arch/misoc/src/minerva/minerva.h new file mode 100644 index 00000000000..b6245f70034 --- /dev/null +++ b/arch/misoc/src/minerva/minerva.h @@ -0,0 +1,162 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_MISOC_SRC_MINERVA_MINERVA_H +#define __ARCH_MISOC_SRC_MINERVA_MINERVA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* This is the value used to mark the stack for subsequent stack monitoring + * logic. + */ + +#define STACK_COLOR 0xdeadbeef +#define INTSTACK_COLOR 0xdeadbeef +#define HEAP_COLOR 'h' + +/* In the MINERVA model, the state is copied from the stack to the TCB, but + * only a referenced is passed to get the state from the TCB. + */ + +#define up_savestate(regs) minerva_copystate(regs, (uint32_t*)g_current_regs) +#define up_copystate(rega,regb) minerva_copystate(rega, regb) +#define up_restorestate(regs) (g_current_regs = regs) + +/* Determine which (if any) console driver to use. If a console is enabled + * and no other console device is specified, then a serial console is + * assumed. + */ + +#if !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS <= 0 +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# undef CONFIG_RAMLOG_CONSOLE +#else +# if defined(CONFIG_RAMLOG_CONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# elif defined(CONFIG_DEV_LOWCONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# else +# define USE_SERIALDRIVER 1 +# define USE_EARLYSERIALINIT 1 +# endif +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +extern volatile uint32_t *g_current_regs; +extern uint32_t g_idle_topstack; + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* Low level initialization provided by board-level logic ******************/ + +void minerva_board_initialize(void); + +/* Memory allocation ********************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void minerva_add_region(void); +#endif + +/* Context switching ********************************************************/ + +void minerva_copystate(uint32_t * dest, uint32_t * src); + +/* IRQ initialization *******************************************************/ + +void minerva_irq_initialize(void); + +/* Interrupt decode *********************************************************/ + +uint32_t *minerva_decodeirq(uint32_t intstat, uint32_t * regs); +uint32_t *minerva_doirq(int irq, uint32_t * regs); + +/* Software interrupts ******************************************************/ + +int minerva_swint(int irq, FAR void *context, FAR void *arg); + +/* System timer *************************************************************/ + +void minerva_timer_initialize(void); + +/* Signal handling **********************************************************/ + +void minerva_sigdeliver(void); + +/* Cache flushing ***********************************************************/ + +void minerva_flush_dcache(void); +void minerva_flush_icache(void); + +/* Debug ********************************************************************/ + +void minerva_dumpstate(void); + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MISOC_SRC_MINERVA_MINERVA_H */ diff --git a/arch/misoc/src/minerva/minerva_allocateheap.c b/arch/misoc/src/minerva/minerva_allocateheap.c new file mode 100644 index 00000000000..4efcce966ce --- /dev/null +++ b/arch/misoc/src/minerva/minerva_allocateheap.c @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_allocateheap.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "minerva.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t * heap_size) +{ + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = CONFIG_RAM_END - g_idle_topstack; +} + +/**************************************************************************** + * Name: minerva_add_region + * + * Description: + * Memory may be added in non-contiguous chunks. Additional chunks are + * added by calling this function. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void minerva_add_region(void) +{ +# warning Missing logic +} +#endif diff --git a/arch/misoc/src/minerva/minerva_assert.c b/arch/misoc/src/minerva/minerva_assert.c new file mode 100644 index 00000000000..383f5cb590e --- /dev/null +++ b/arch/misoc/src/minerva/minerva_assert.c @@ -0,0 +1,189 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_assert.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "sched/sched.h" +#include "minerva.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* USB trace dumping */ + +#ifndef CONFIG_USBDEV_TRACE +# undef CONFIG_ARCH_USBDUMP +#endif + +#ifndef CONFIG_BOARD_RESET_ON_ASSERT +# define CONFIG_BOARD_RESET_ON_ASSERT 0 +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _up_assert + ****************************************************************************/ + +static void _up_assert(int errorcode) noreturn_function; +static void _up_assert(int errorcode) +{ + /* Flush any buffered SYSLOG data */ + + (void)syslog_flush(); + + /* Are we in an interrupt handler or the idle task? NOTE: You cannot use the + * PID to determine if this is an IDLE task. In the SMP case, there may be + * multiple IDLE tasks with different PIDs. The only consistent way to test + * for the IDLE task is to check it is at the end of the list (flink == + * NULL) + */ + + if (g_current_regs || running_task()->flink == NULL) + { + (void)up_irq_save(); + for (; ; ) + { +#if CONFIG_BOARD_RESET_ON_ASSERT >= 1 + board_reset(CONFIG_BOARD_ASSERT_RESET_VALUE); +#endif +#ifdef CONFIG_ARCH_LEDS + board_autoled_on(LED_PANIC); + up_mdelay(250); + board_autoled_off(LED_PANIC); + up_mdelay(250); +#endif + } + } + else + { +#if CONFIG_BOARD_RESET_ON_ASSERT >= 2 + board_reset(CONFIG_BOARD_ASSERT_RESET_VALUE); +#endif + exit(errorcode); + } +} + +/**************************************************************************** + * Name: assert_tracecallback + ****************************************************************************/ + +#ifdef CONFIG_ARCH_USBDUMP +static int usbtrace_syslog(FAR const char *fmt, ...) +{ + va_list ap; + int ret; + + /* Let nx_vsyslog do the real work */ + + va_start(ap, fmt); + ret = nx_vsyslog(LOG_EMERG, fmt, &ap); + va_end(ap); + return ret; +} + +static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg) +{ + usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); + return 0; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_assert + ****************************************************************************/ + +void up_assert(const uint8_t * filename, int lineno) +{ +#if CONFIG_TASK_NAME_SIZE > 0 && defined(CONFIG_DEBUG_ALERT) + struct tcb_s *rtcb = running_task(); +#endif + + board_autoled_on(LED_ASSERTION); + + /* Flush any buffered SYSLOG data (prior to the assertion) */ + + (void)syslog_flush(); + +#if CONFIG_TASK_NAME_SIZE > 0 + _alert("Assertion failed at file:%s line: %d task: %s\n", + filename, lineno, rtcb->name); +#else + _alert("Assertion failed at file:%s line: %d\n", filename, lineno); +#endif + + minerva_dumpstate(); + +#ifdef CONFIG_ARCH_USBDUMP + /* Dump USB trace data */ + + (void)usbtrace_enumerate(assert_tracecallback, NULL); +#endif + + /* Flush any buffered SYSLOG data (from the above) */ + + (void)syslog_flush(); + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), running_task(), filename, lineno); +#endif + + _up_assert(EXIT_FAILURE); +} diff --git a/arch/misoc/src/minerva/minerva_blocktask.c b/arch/misoc/src/minerva/minerva_blocktask.c new file mode 100644 index 00000000000..b4e9da07af8 --- /dev/null +++ b/arch/misoc/src/minerva/minerva_blocktask.c @@ -0,0 +1,177 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_blocktask.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "minerva.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of + * the ready to run list must be stopped. Save its context + * and move it to the inactive list specified by task_state. + * + * Input Parameters: + * tcb: Refers to a task in the ready-to-run list (normally + * the task at the head of the list). It most be + * stopped, its context saved and moved into one of the + * waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new + * ready to run task must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(struct tcb_s *tcb, tstate_t task_state) +{ + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + /* Verify that the context switch can be performed */ + + DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) && + (tcb->task_state <= LAST_READY_TO_RUN_STATE)); + + /* Remove the tcb task from the ready-to-run list. If we are blocking the + * task at the head of the task list (the most likely case), then a context + * switch to the next ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t) task_state); + + /* If there are any pending tasks, then add them to the ready-to-run task + * list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. Just copy the + * g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head of + * the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment changes + * will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Get the context of the task at the head of the ready to run list. */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously running + * task is closed down gracefully (data caches dump, MMU flushed) + * and set up the address environment for the new thread at the head + * of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Reset scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Then switch contexts */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the head + * of the ready-to-run list. It does not 'return' in the normal + * sense. When it does return, it is because the blocked task is + * again ready to run and has execution priority. + */ + } + } +} diff --git a/arch/misoc/src/minerva/minerva_config.h b/arch/misoc/src/minerva/minerva_config.h new file mode 100644 index 00000000000..af62235c28f --- /dev/null +++ b/arch/misoc/src/minerva/minerva_config.h @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_config.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Modified for MINERVA: + * + * Copyright (C) 2016 Ramin Amin. All rights reserved. + * Author: Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_MISOC_SRC_MINERVA_MINERVA_CONFIG_H +#define __ARCH_MISOC_SRC_MINERVA_MINERVA_CONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* UARTs ********************************************************************/ + +/* Are any UARTs enabled? */ + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_MISOC_UART1) || defined(CONFIG_MISOC_UART2) +# define HAVE_UART_DEVICE 1 +#endif + +/* Is there a serial console? There should be no more than one defined. It + * could be on any UARTn, n=1,.. CHIP_NUARTS + */ + +#if defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_MISOC_UART1) +# undef CONFIG_UART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_MISOC_UART2) +# undef CONFIG_UART1_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +#endif /* __ARCH_MISOC_SRC_MINERVA_MINERVA_CONFIG_H */ diff --git a/arch/misoc/src/minerva/minerva_copystate.c b/arch/misoc/src/minerva/minerva_copystate.c new file mode 100644 index 00000000000..5c9b5207d6e --- /dev/null +++ b/arch/misoc/src/minerva/minerva_copystate.c @@ -0,0 +1,74 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_copystate.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "minerva.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: minerva_copystate + ****************************************************************************/ + +/* A little faster than most memcpy's */ + +void minerva_copystate(uint32_t * dest, uint32_t * src) +{ + int i; + + /* In the MINERVA model, the state is copied from the stack to the TCB, but + * only a reference is passed to get the state from the TCB. So the + * following check avoids copying the TCB save area onto itself: + */ + + if (src != dest) + { + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } + } +} diff --git a/arch/misoc/src/minerva/minerva_createstack.c b/arch/misoc/src/minerva/minerva_createstack.c new file mode 100644 index 00000000000..782cc0750e0 --- /dev/null +++ b/arch/misoc/src/minerva/minerva_createstack.c @@ -0,0 +1,206 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_createstack.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "minerva.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ + +/* MINERVA requires at least a 4-byte stack alignment. For floating point + * use, however, the stack must be aligned to 8-byte addresses. + */ + +#ifdef CONFIG_LIBC_FLOATINGPOINT +# define STACK_ALIGNMENT 8 +#else +# define STACK_ALIGNMENT 4 +#endif + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_create_stack + * + * Description: + * Allocate a stack for a new thread and setup up stack-related information + * in the TCB. + * + * The following TCB fields must be initialized by this function: + * + * - adj_stack_size: Stack size after adjustment for hardware, processor, + * etc. This value is retained only for debug purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of + * the stack pointer. + * + * Input Parameters: + * - tcb: The TCB of new task + * - stack_size: The requested stack size. At least this much + * must be allocated. + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain contexts where the TCB may not be fully + * initialized when up_create_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is allocated. For example, kernel thread stacks should + * be allocated from protected kernel memory. Stacks for user tasks and + * threads must come from memory that is accessible to user code. + * + ****************************************************************************/ + +int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) +{ + /* Is there already a stack allocated of a different size? Because of + * alignment issues, stack_size might erroneously appear to be of a + * different size. Fortunately, this is not a critical operation. + */ + + if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) + { + /* Yes.. Release the old stack */ + + up_release_stack(tcb, ttype); + } + + /* Do we need to allocate a new stack? */ + + if (!tcb->stack_alloc_ptr) + { + /* Allocate the stack. If DEBUG is enabled (but not stack debug), then + * create a zeroed stack to make stack dumps easier to trace. + */ + +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = (uint32_t *) kmm_malloc(stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = (uint32_t *) kumm_malloc(stack_size); + } + +#ifdef CONFIG_DEBUG_FEATURES + /* Was the allocation successful? */ + + if (!tcb->stack_alloc_ptr) + { + serr("ERROR: Failed to allocate stack, size %d\n", stack_size); + } +#endif + } + + /* Did we successfully allocate a stack? */ + + if (tcb->stack_alloc_ptr) + { + size_t top_of_stack; + size_t size_of_stack; + + /* Yes.. If stack debug is enabled, then fill the stack with a + * recognizable value that we can use later to test for high water + * marks. + */ + +#ifdef CONFIG_STACK_COLORATION + memset(tcb->stack_alloc_ptr, 0xaa, stack_size); +#endif + + /* MINERVA uses a push-down stack: the stack grows toward lower + * addresses in memory. The stack pointer register points to the + * lowest, valid working address (the "top" of the stack). Items on + * the stack are referenced as positive word offsets from sp. + */ + + top_of_stack = (uint32_t) tcb->stack_alloc_ptr + stack_size - 4; + + /* The MINERVA stack must be aligned at word (4 byte) boundaries; for + * floating point use, the stack must be aligned to 8-byte addresses. If + * necessary top_of_stack must be rounded down to the next boundary to + * meet these alignment requirements. + */ + + top_of_stack = STACK_ALIGN_DOWN(top_of_stack); + size_of_stack = top_of_stack - (uint32_t) tcb->stack_alloc_ptr + 4; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (FAR uint32_t *) top_of_stack; + tcb->adj_stack_size = size_of_stack; + + board_autoled_on(LED_STACKCREATED); + return OK; + } + + return ERROR; +} diff --git a/arch/misoc/src/minerva/minerva_decodeirq.c b/arch/misoc/src/minerva/minerva_decodeirq.c new file mode 100644 index 00000000000..d6ce0ce4b52 --- /dev/null +++ b/arch/misoc/src/minerva/minerva_decodeirq.c @@ -0,0 +1,107 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_decodeirq.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "chip.h" +#include "minerva.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: minerva_decodeirq + * + * Description: + * This function is called from the IRQ vector handler in minerva_vectors.S. + * At this point, the interrupt has been taken and the registers have + * been saved on the stack. This function simply needs to determine the + * the irq number of the interrupt and then to call minerva_doirq to + * dispatch the interrupt. + * + * Input parameters: + * regs - A pointer to the register save area on the stack. + * + ****************************************************************************/ + +uint32_t *minerva_decodeirq(uint32_t intstat, uint32_t * regs) +{ + int irq; + + irqinfo("intstat=%08lx\n", (unsigned long)intstat); + + /* Decode and dispatch interrupts */ + + for (irq = 0; irq < MINERVA_NINTERRUPTS && intstat != 0; irq++) + { + uint32_t bit = (1 << irq); + + /* Is this interrupt pending? */ + + if ((intstat & bit) != 0) + { + /* Yes.. Dispatch the interrupt + * REVIST: Do I need to acknowledge the interrupt first? + */ + + irqinfo("irq=%d\n", irq); + regs = minerva_doirq(irq, regs); + + /* Clear the bit in the interrupt status copy so that maybe we can + * break out of the loop early. + */ + + intstat &= ~bit; + } + } + + /* Return the final task register save area. This will typically be the + * same as the value of regs on input. In the event of a context switch, + * however, it will differ. It will refere to the register save are in + * the TCB of the new thread. + */ + + return regs; +} diff --git a/arch/misoc/src/minerva/minerva_doexceptions.c b/arch/misoc/src/minerva/minerva_doexceptions.c new file mode 100644 index 00000000000..8575679f59b --- /dev/null +++ b/arch/misoc/src/minerva/minerva_doexceptions.c @@ -0,0 +1,93 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_doexception.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "group/group.h" +#include "minerva.h" +#include "chip.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +uint32_t *minerva_doexception(uint32_t * regs) +{ + uint32_t mcause; + uint32_t pending; + uint32_t *ret; + + board_autoled_on(LED_INIRQ); + + mcause = regs[REG_CSR_MCAUSE_NDX]; + + if (mcause & 0x80000000) + { + pending = irq_pending(); + ret = minerva_decodeirq(pending, regs); + } + else + { + mcause = mcause & 0x7fffffff; + if (mcause == 11) + { + regs[REG_CSR_MEPC_NDX] += 4; + ret = minerva_doirq(MINERVA_IRQ_SWINT, regs); + } + else + { + while (1); + } + } + + board_autoled_off(LED_INIRQ); + return ret; +} diff --git a/arch/misoc/src/minerva/minerva_doirq.c b/arch/misoc/src/minerva/minerva_doirq.c new file mode 100644 index 00000000000..daa32021bfb --- /dev/null +++ b/arch/misoc/src/minerva/minerva_doirq.c @@ -0,0 +1,130 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_doirq.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "group/group.h" +#include "minerva.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +uint32_t *minerva_doirq(int irq, uint32_t * regs) +{ + board_autoled_on(LED_INIRQ); + + /* Current regs non-zero indicates that we are processing an interrupt; + * g_current_regs is also used to manage interrupt level context switches. + * Nested interrupts are not supported + */ + + DEBUGASSERT(g_current_regs == NULL); + g_current_regs = regs; + + /* Disable further occurrences of this interrupt (until the interrupt + * sources have been clear by the driver). + */ + + up_disable_irq(irq); + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * g_current_regs will have a different value than it did on entry. If an + * interrupt level context switch has occurred, then restore the floating + * point state and the establish the correct address environment before + * returning from the interrupt. + */ + + if (regs != g_current_regs) + { +# ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint32_t *) g_current_regs); +# endif + +# ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously running + * task is closed down gracefully (data caches dump, MMU flushed) and + * set up the address environment for the new thread at the head of + * the ready-to-run list. + */ + + (void)group_addrenv(NULL); +# endif + } +#endif + + /* If a context switch occurred while processing the interrupt then + * g_current_regs may have change value. If we return any value different + * from the input regs, then the lower level will know that a context switch + * occurred during interrupt processing. + */ + + regs = (uint32_t *) g_current_regs; + + /* Set g_current_regs to NULL to indicate that we are no longer in an + * interrupt handler. + */ + + g_current_regs = NULL; + + /* Unmask the last interrupt (global interrupts are still disabled) */ + + up_enable_irq(irq); + board_autoled_off(LED_INIRQ); + return regs; +} diff --git a/arch/misoc/src/minerva/minerva_dumpstate.c b/arch/misoc/src/minerva/minerva_dumpstate.c new file mode 100644 index 00000000000..57a17d49543 --- /dev/null +++ b/arch/misoc/src/minerva/minerva_dumpstate.c @@ -0,0 +1,232 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_dumpstate.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "sched/sched.h" +#include "minerva.h" + +#ifdef CONFIG_ARCH_STACKDUMP + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getsp + ****************************************************************************/ + +static inline uint32_t up_getsp(void) +{ + register uint32_t sp; + + __asm__ __volatile__("addi %0, sp, 0":"=r"(sp)); + + return sp; +} + +/**************************************************************************** + * Name: up_stackdump + ****************************************************************************/ + +static void up_stackdump(uint32_t sp, uint32_t stack_base) +{ + uint32_t stack; + + for (stack = sp & ~0x1f; stack < stack_base; stack += 32) + { + uint32_t *ptr = (uint32_t *) stack; + _alert("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } +} + +/**************************************************************************** + * Name: up_registerdump + ****************************************************************************/ + +static inline void up_registerdump(void) +{ + /* Are user registers available from interrupt processing? */ + + if (g_current_regs) + { + _alert("EPC:%08x \n", g_current_regs[REG_CSR_MEPC]); + _alert + (" X0:%08x A0:%08x A1:%08x A2:%08x A3:%08x A4:%08x A5:%08x A6:%08x\n", + g_current_regs[REG_X0_NDX], g_current_regs[REG_X1_NDX], + g_current_regs[REG_X2_NDX], g_current_regs[REG_X3_NDX], + g_current_regs[REG_X4_NDX], g_current_regs[REG_X5_NDX], + g_current_regs[REG_X6_NDX], g_current_regs[REG_X7_NDX]); + _alert + (" A7:%08x X9:%08x X10:%08x X11:%08x X12:%08x X13:%08x X14:%08x X15:%08x\n", + g_current_regs[REG_X8_NDX], g_current_regs[REG_X9_NDX], + g_current_regs[REG_X10_NDX], g_current_regs[REG_X11_NDX], + g_current_regs[REG_X12_NDX], g_current_regs[REG_X13_NDX], + g_current_regs[REG_X14_NDX], g_current_regs[REG_X15_NDX]); + _alert + ("X16:%08x X17:%08x X18:%08x X19:%08x X20:%08x X21:%08x X22:%08x X23:%08x\n", + g_current_regs[REG_X16_NDX], g_current_regs[REG_X17_NDX], + g_current_regs[REG_X18_NDX], g_current_regs[REG_X19_NDX], + g_current_regs[REG_X20_NDX], g_current_regs[REG_X21_NDX], + g_current_regs[REG_X22_NDX], g_current_regs[REG_X23_NDX]); + _alert + ("X24:%08x X25:%08x GP:%08x FP:%08x SP:%08x RA:%08x EA:%08x BA:%08x\n", + g_current_regs[REG_X24_NDX], g_current_regs[REG_X25_NDX], + g_current_regs[REG_X26_NDX], g_current_regs[REG_X27_NDX], + g_current_regs[REG_X28_NDX], g_current_regs[REG_X29_NDX], + g_current_regs[REG_X30_NDX], g_current_regs[REG_X31_NDX]); + _alert(" IE:%08x\n", g_current_regs[REG_CSR_MSTATUS]); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: minerva_dumpstate + ****************************************************************************/ + +void minerva_dumpstate(void) +{ + struct tcb_s *rtcb = running_task(); + uint32_t sp = up_getsp(); + uint32_t ustackbase; + uint32_t ustacksize; +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + uint32_t istackbase; + uint32_t istacksize; +#endif + + /* Dump the registers (if available) */ + + up_registerdump(); + + /* Get the limits on the user stack memory NOTE: You cannot use the PID to + * determine if this is an IDLE task. In the SMP case, there may be + * multiple IDLE tasks with different PIDs. The only consistent way to + * test for the IDLE task is to check it is at the end of the list (flink + * == NULL) + */ + + if (rtcb->flink == NULL) + { + ustackbase = g_idle_topstack - 4; + ustacksize = CONFIG_IDLETHREAD_STACKSIZE; + } + else + { + ustackbase = (uint32_t) rtcb->adj_stack_ptr; + ustacksize = (uint32_t) rtcb->adj_stack_size; + } + + /* Get the limits on the interrupt stack memory */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + istackbase = (uint32_t) & g_intstackbase; + istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4; + + /* Show interrupt stack info */ + + _alert("sp: %08x\n", sp); + _alert("IRQ stack:\n"); + _alert(" base: %08x\n", istackbase); + _alert(" size: %08x\n", istacksize); + + /* Does the current stack pointer lie within the interrupt stack? */ + + if (sp <= istackbase && sp > istackbase - istacksize) + { + /* Yes.. dump the interrupt stack */ + + up_stackdump(sp, istackbase); + + /* Extract the user stack pointer which should lie at the base of the + * interrupt stack. + */ + + sp = g_intstackbase; + _alert("sp: %08x\n", sp); + } + else if (g_current_regs) + { + _alert("ERROR: Stack pointer is not within the interrupt stack\n"); + up_stackdump(istackbase - istacksize, istackbase); + } + + /* Show user stack info */ + + _alert("User stack:\n"); + _alert(" base: %08x\n", ustackbase); + _alert(" size: %08x\n", ustacksize); +#else + _alert("sp: %08x\n", sp); + _alert("stack base: %08x\n", ustackbase); + _alert("stack size: %08x\n", ustacksize); +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp > ustackbase || sp <= ustackbase - ustacksize) + { + _alert("ERROR: Stack pointer is not within allocated stack\n"); + up_stackdump(ustackbase - ustacksize, ustackbase); + } + else + { + up_stackdump(sp, ustackbase); + } +} + +#endif /* CONFIG_ARCH_STACKDUMP */ + diff --git a/arch/misoc/src/minerva/minerva_exit.c b/arch/misoc/src/minerva/minerva_exit.c new file mode 100644 index 00000000000..1a24b5ce4cd --- /dev/null +++ b/arch/misoc/src/minerva/minerva_exit.c @@ -0,0 +1,187 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_exit.c + * + * Copyright (C) 2010, 2013-2014, 2017-2018 Gregory Nutt. All rights + * reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#ifdef CONFIG_DUMP_ON_EXIT +# include +#endif + +#include + +#include "task/task.h" +#include "sched/sched.h" +#include "group/group.h" +#include "minerva.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _up_dumponexit + * + * Description: + * Dump the state of all tasks whenever on task exits. This is debug + * instrumentation that was added to check file-related reference counting + * but could be useful again sometime in the future. + * + ****************************************************************************/ + +#ifdef CONFIG_DUMP_ON_EXIT +static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg) +{ +#if CONFIG_NFILE_DESCRIPTORS > 0 + FAR struct filelist *filelist; +#if CONFIG_NFILE_STREAMS > 0 + FAR struct streamlist *streamlist; +#endif + int i; +#endif + + sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid); + sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state); + +#if CONFIG_NFILE_DESCRIPTORS > 0 + filelist = tcb->group->tg_filelist; + for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) + { + struct inode *inode = filelist->fl_files[i].f_inode; + if (inode) + { + sinfo(" fd=%d refcount=%d\n", i, inode->i_crefssinfo); + } + } +#endif + +#if CONFIG_NFILE_STREAMS > 0 + streamlist = tcb->group->tg_streamlist; + for (i = 0; i < CONFIG_NFILE_STREAMS; i++) + { + struct file_struct *filep = &streamlist->sl_streams[i]; + if (filep->fs_fd >= 0) + { +#ifndef CONFIG_STDIO_DISABLE_BUFFERING + if (filep->fs_bufstart != NULL) + { + sinfo(" fd=%d nbytes=%d\n", + filep->fs_fd, filep->fs_bufpos - filep->fs_bufstart); + } + else +#endif + { + sinfo(" fd=%d\n", filep->fs_fd); + } + } + } +#endif +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _exit + * + * Description: + * This function causes the currently executing task to cease + * to exist. This is a special case of task_delete() where the task to + * be deleted is the currently executing task. It is more complex because + * a context switch must be perform to the next ready to run task. + * + ****************************************************************************/ + +void _exit(int status) +{ + struct tcb_s *tcb = this_task(); + + /* Make sure that we are in a critical section with local interrupts. The + * IRQ state will be restored when the next task is started. + */ + + (void)enter_critical_section(); + + sinfo("TCB=%p exiting\n", tcb); + +#ifdef CONFIG_DUMP_ON_EXIT + sinfo("Other tasks:\n"); + sched_foreach(_up_dumponexit, NULL); +#endif + + /* Update scheduler parameters */ + + sched_suspend_scheduler(tcb); + + /* Destroy the task at the head of the ready to run list. */ + + (void)nxtask_exit(); + + /* Now, perform the context switch to the new ready-to-run task at the head + * of the list. + */ + + tcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously running task is + * closed down gracefully (data caches dump, MMU flushed) and set up the + * address environment for the new thread at the head of the ready-to-run + * list. + */ + + (void)group_addrenv(tcb); +#endif + + /* Reset scheduler parameters */ + + sched_resume_scheduler(tcb); + + /* Then switch contexts */ + + up_fullcontextrestore(tcb->xcp.regs); +} diff --git a/arch/misoc/src/minerva/minerva_flushcache.c b/arch/misoc/src/minerva/minerva_flushcache.c new file mode 100644 index 00000000000..e9def568b5a --- /dev/null +++ b/arch/misoc/src/minerva/minerva_flushcache.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_flushcache.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "chip.h" +#include "minerva.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: minerva_flush_dcache + * + * Description: + * Flush the data cache of the cpu + * + ****************************************************************************/ + +void minerva_flush_dcache(void) +{ +#warning "FIX D CACHE FLUSH" + asm volatile ("nop\n" "nop\n" "nop\n" "nop\n"); +} + +/**************************************************************************** + * Name: minerva_flush_icache + * + * Description: + * Flush the instruction cache of the cpu + * + ****************************************************************************/ + +void minerva_flush_icache(void) +{ + asm volatile ("fence.i\n" "nop\n" "nop\n" "nop\n" "nop\n"); +} diff --git a/arch/misoc/src/minerva/minerva_idle.c b/arch/misoc/src/minerva/minerva_idle.c new file mode 100644 index 00000000000..4871309da90 --- /dev/null +++ b/arch/misoc/src/minerva/minerva_idle.c @@ -0,0 +1,94 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_idle.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "minerva.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + + /* This would be an appropriate place to put some MCU-specific logic to + * sleep in a reduced power mode until an interrupt occurs to save power + * + * This is a kludge that I still don't understand. The call to + * kmm_trysemaphore() in the nx_start.c IDLE loop seems necessary for the + * good health of the IDLE loop. When the work queue is enabled, this logic + * is removed from the IDLE loop and it appears that we are somehow left + * idling with interrupts non- functional. The following should be no-op, it + * just disables then re-enables interrupts. But it fixes the problem and + * will stay here until I understand the problem/fix better. And no, the + * contents of the CP0 status register are not incorrect. But for some + * reason the status register needs to be re-written again on this thread + * for it to take effect. + */ + +#ifdef CONFIG_SCHED_WORKQUEUE + irqstate_t flags = enter_critical_section(); + leave_critical_section(flags); +#endif +#endif +} diff --git a/arch/misoc/src/minerva/minerva_initialize.c b/arch/misoc/src/minerva/minerva_initialize.c new file mode 100644 index 00000000000..7a82698b094 --- /dev/null +++ b/arch/misoc/src/minerva/minerva_initialize.c @@ -0,0 +1,93 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_initialize.c + * + * Copyright (C) 2016-2017 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "misoc.h" +#include "minerva.h" + +/**************************************************************************** + * Public Functionis + ****************************************************************************/ + +void up_initialize(void) +{ + /* Initialize the System Timer */ + + minerva_irq_initialize(); + + /* Initialize the serial driver */ + + misoc_serial_initialize(); + + /* Initialize the system timer */ + + misoc_timer_initialize(); + +#ifdef CONFIG_MM_IOB + /* Initialize IO buffering */ + + iob_initialize(); +#endif + + /* Initialize the network cores */ + +#ifdef CONFIG_MISOC_ETHERNET + misoc_net_initialize(0); +#endif +} diff --git a/arch/misoc/src/minerva/minerva_initialstate.c b/arch/misoc/src/minerva/minerva_initialstate.c new file mode 100644 index 00000000000..55b4c27603a --- /dev/null +++ b/arch/misoc/src/minerva/minerva_initialstate.c @@ -0,0 +1,112 @@ +/**************************************************************************** + * arch/misoc/src/minerva/up_initialstate.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "minerva.h" +#include "chip.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB + * has been created. This function is called to initialize + * the processor specific portions of the new TCB. + * + * This function must setup the intial architecture registers + * and/or stack so that execution will begin at tcb->start + * on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + uint32_t regval; + struct xcptcontext *xcp = &tcb->xcp; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); + + /* Save the initial stack pointer. Hmmm.. the stack is set to the very + * beginning of the stack region. Some functions may want to store data on + * the caller's stack and it might be good to reserve some space. However, + * only the start function would do that and we have control over that one. + */ + + xcp->regs[REG_SP] = (uint32_t) tcb->adj_stack_ptr; + + /* Save the task entry point */ + + xcp->regs[REG_CSR_MEPC] = (uint32_t) tcb->start; + + xcp->regs[REG_CSR_MSTATUS] = CSR_MSTATUS_MPIE; + + /* If this task is running PIC, then set the PIC base register to the + * address of the allocated D-Space region. + */ + +#ifdef CONFIG_PIC +# warning "Missing logic" +#endif + + /* Set privileged- or unprivileged-mode, depending on how NuttX is + * configured and what kind of thread is being started. If the kernel + * build is not selected, then all threads run in privileged thread mode. + */ + +#ifdef CONFIG_BUILD_KERNEL +# warning "Missing logic" +#endif +} diff --git a/arch/misoc/src/minerva/minerva_interruptcontext.c b/arch/misoc/src/minerva/minerva_interruptcontext.c new file mode 100644 index 00000000000..89c7233eb8a --- /dev/null +++ b/arch/misoc/src/minerva/minerva_interruptcontext.c @@ -0,0 +1,62 @@ +/**************************************************************************** + * arch/misoc/src/minerva/up_interruptcontext.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "minerva.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_interrupt_context + * + * Description: Return true is we are currently executing in + * the interrupt handler context. + ****************************************************************************/ + +bool up_interrupt_context(void) +{ + return g_current_regs != NULL; +} diff --git a/arch/misoc/src/minerva/minerva_irq.c b/arch/misoc/src/minerva/minerva_irq.c new file mode 100644 index 00000000000..f2d0bf1e514 --- /dev/null +++ b/arch/misoc/src/minerva/minerva_irq.c @@ -0,0 +1,189 @@ +/**************************************************************************** + * arch/misoc/src/minerva/_irq.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include + +#include "chip.h" +#include "minerva.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +volatile uint32_t *g_current_regs; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: minerva_irq_initialize + ****************************************************************************/ + +void minerva_irq_initialize(void) +{ + /* currents_regs is non-NULL only while processing an interrupt */ + + g_current_regs = NULL; + + /* Attach the software interrupt */ + + (void)irq_attach(MINERVA_IRQ_SWINT, minerva_swint, NULL); + + /* Enable interrupts */ + + irq_setie(1); +} + +/**************************************************************************** + * Name: up_irq_save + * + * Description: + * Return the current interrupt enable state and disable all interrupts. + * + ****************************************************************************/ + +irqstate_t up_irq_save(void) +{ + irqstate_t flags; + + /* Get the previous value of IE */ + + flags = irq_getie(); + + /* Disable interrupts and return the previous interrupt state */ + + irq_setie(0); + return flags; +} + +/**************************************************************************** + * Name: up_irq_restore + * + * Description: + * Restore saved interrupt state + * + ****************************************************************************/ + +void up_irq_restore(irqstate_t flags) +{ + /* Restore the interrupt state returned by up_save_irq() */ + + irq_setie(flags); +} + +/**************************************************************************** + * Name: up_irq_enable + * + * Description: + * Return the current interrupt enable state and enable all interrupts + * + ****************************************************************************/ + +irqstate_t up_irq_enable(void) +{ + irqstate_t flags; + + /* Get the previous value of IE */ + + flags = irq_getie(); + + /* Enable interrupts and return the previous interrupt state */ + + irq_setie(1); + return flags; +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + irqstate_t flags; + + DEBUGASSERT(irq >= 0 && irq < NR_IRQS); + + /* Ignore any attempt to disable software interrupts */ + + if (irq < MINERVA_NINTERRUPTS) + { + /* Disable interrupts by clearing the bit that corresponds to the irq */ + + flags = irq_getmask(); + flags &= ~(1 << irq); + irq_setmask(flags); + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + irqstate_t flags; + DEBUGASSERT(irq >= 0 && irq < NR_IRQS); + + /* Ignore any attempt to enable software interrupts */ + + if (irq < MINERVA_NINTERRUPTS) + { + /* Enable interrupts by setting the bit that corresponds to the irq */ + + flags = irq_getmask(); + flags |= (1 << irq); + irq_setmask(flags); + } +} diff --git a/arch/misoc/src/minerva/minerva_releasepending.c b/arch/misoc/src/minerva/minerva_releasepending.c new file mode 100644 index 00000000000..f950e765ba3 --- /dev/null +++ b/arch/misoc/src/minerva/minerva_releasepending.c @@ -0,0 +1,148 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_releasepending.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "minerva.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have + * collected in the pending task list. This can call a + * context switch if a new task is placed at the head of + * the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + struct tcb_s *rtcb = this_task(); + + sinfo("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + /* sched_lock(); */ + + if (sched_mergepending()) + { + /* The currently active task has changed! We will need to switch + * contexts. Update scheduler parameters. + */ + + sched_suspend_scheduler(rtcb); + + /* Are we operating in interrupt context? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. Just copy the + * g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head of + * the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment changes + * will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously running + * task is closed down gracefully (data caches dump, MMU flushed) + * and set up the address environment for the new thread at the head + * of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Then switch contexts */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the head + * of the ready-to-run list. It does not 'return' in the normal + * sense. When it does return, it is because the blocked task is + * again ready to run and has execution priority. + */ + } + } +} diff --git a/arch/misoc/src/minerva/minerva_releasestack.c b/arch/misoc/src/minerva/minerva_releasestack.c new file mode 100644 index 00000000000..5c480232c1f --- /dev/null +++ b/arch/misoc/src/minerva/minerva_releasestack.c @@ -0,0 +1,121 @@ +/**************************************************************************** + * arch/misoc/src/minerva/up_releasestack.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "minerva.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_stack + * + * Description: + * A task has been stopped. Free all stack related resources retained in + * the defunct TCB. + * + * Input Parameters: + * - dtcb: The TCB containing information about the stack to be released + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain error recovery contexts where the TCB may + * not be fully initialized when up_release_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is freed. For example, kernel thread stacks may have + * been allocated from protected kernel memory. Stacks for user tasks + * and threads must have come from memory that is accessible to user + * code. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype) +{ + /* Is there a stack allocated? */ + + if (dtcb->stack_alloc_ptr) + { +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + if (kmm_heapmember(dtcb->stack_alloc_ptr)) + { + sched_kfree(dtcb->stack_alloc_ptr); + } + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + if (umm_heapmember(dtcb->stack_alloc_ptr)) + { + sched_ufree(dtcb->stack_alloc_ptr); + } + } + + /* Mark the stack freed */ + + dtcb->stack_alloc_ptr = NULL; + } + + /* The size of the allocated stack is now zero */ + + dtcb->adj_stack_size = 0; +} diff --git a/arch/misoc/src/minerva/minerva_reprioritizertr.c b/arch/misoc/src/minerva/minerva_reprioritizertr.c new file mode 100644 index 00000000000..64d771a5d17 --- /dev/null +++ b/arch/misoc/src/minerva/minerva_reprioritizertr.c @@ -0,0 +1,201 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_reprioritizertr.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "minerva.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Input Parameters: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > 0 + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + DEBUGPANIC(); + } + else + { + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + sinfo("TCB=%p PRI=%d\n", tcb, priority); + + /* Remove the tcb task from the ready-to-run list. sched_removereadytorun + * will return true if we just remove the head of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t) priority; + + /* Return the task to the specified blocked task list. + * sched_addreadytorun will return true if the task was added to the new + * list. We will need to perform a context switch only if the EXCLUSIVE + * or of the two calls is non-zero (i.e., one and only one the calls + * changes the head of the ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list + * task list now. + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. Just copy the + * g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, MMU + * flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Then switch contexts */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } + } +} diff --git a/arch/misoc/src/minerva/minerva_schedulesigaction.c b/arch/misoc/src/minerva/minerva_schedulesigaction.c new file mode 100644 index 00000000000..2f1a11205a4 --- /dev/null +++ b/arch/misoc/src/minerva/minerva_schedulesigaction.c @@ -0,0 +1,202 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_schedulesigaction.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Modified for MISOC: + * + * Copyright (C) 2016 Ramtin Amin. All rights reserved. + * Author: Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "minerva.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; + + 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_CSR_MEPC]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + g_current_regs[REG_CSR_MEPC] = (uint32_t) minerva_sigdeliver; + g_current_regs[REG_CSR_MSTATUS] &= ~CSR_MSTATUS_MIE; + + /* 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_status, + g_current_regs[REG_CSR_MEPC], + g_current_regs[REG_CSR_MSTATUS]); + } + } + + /* 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_CSR_MEPC]; + tcb->xcp.saved_int_ctx = tcb->xcp.regs[REG_CSR_MSTATUS]; + + /* Then set up to vector to the trampoline with interrupts disabled */ + + tcb->xcp.regs[REG_CSR_MEPC] = (uint32_t) minerva_sigdeliver; + g_current_regs[REG_CSR_MSTATUS] &= ~CSR_MSTATUS_MIE; + + sinfo("PC/STATUS Saved: %08x/%08x New: %08x/%08x\n", + tcb->xcp.saved_epc, tcb->xcp.saved_status, + tcb->xcp.regs[REG_CSR_MEPC], tcb->xcp.regs[REG_CSR_MSTATUS]); + } + } + + leave_critical_section(flags); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/misoc/src/minerva/minerva_sigdeliver.c b/arch/misoc/src/minerva/minerva_sigdeliver.c new file mode 100644 index 00000000000..b3d7816107d --- /dev/null +++ b/arch/misoc/src/minerva/minerva_sigdeliver.c @@ -0,0 +1,139 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_sigdeliver.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "sched/sched.h" +#include "minerva.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: minerva_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void minerva_sigdeliver(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t regs[XCPTCONTEXT_REGS]; + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling so + * that the user code final gets the correct errno value (probably EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sinfo("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + DEBUGASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + up_copystate(regs, rtcb->xcp.regs); + regs[REG_CSR_MEPC] = rtcb->xcp.saved_epc; + regs[REG_CSR_MSTATUS] = rtcb->xcp.saved_int_ctx; + + /* Get a local copy of the sigdeliver function pointer. We do this so that + * we can nullify the sigdeliver function pointer in the TCB and accept + * more signal deliveries while processing the current pending signals. + */ + + sigdeliver = rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + +# ifndef CONFIG_SUPPRESS_INTERRUPTS + /* Then make sure that interrupts are enabled. Signal handlers must always + * run with interrupts enabled. + */ + + up_irq_enable(); +# endif + + /* Deliver the signals */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may alter + * errno), then disable interrupts again and restore the original errno that + * is needed by the user logic (it is probably EINTR). + */ + + sinfo("Resuming EPC: %08x INT_CTX: %08x\n", regs[REG_CSR_MEPC], + regs[REG_CSR_MSTATUS]); + + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of execution. */ + + board_autoled_off(LED_SIGNAL); + up_fullcontextrestore(regs); + + /* up_fullcontextrestore() should not return but could if the software + * interrupts are disabled. + */ + + DEBUGPANIC(); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/misoc/src/minerva/minerva_stackframe.c b/arch/misoc/src/minerva/minerva_stackframe.c new file mode 100644 index 00000000000..fb56a226bc6 --- /dev/null +++ b/arch/misoc/src/minerva/minerva_stackframe.c @@ -0,0 +1,136 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_stackframe.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "minerva.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ + +/* MINERVA requires at least a 4-byte stack alignment. For floating point + * use, however, the stack must be aligned to 8-byte addresses. + */ + +#ifdef CONFIG_LIBC_FLOATINGPOINT +# define STACK_ALIGNMENT 8 +#else +# define STACK_ALIGNMENT 4 +#endif + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_stack_frame + * + * Description: + * Allocate a stack frame in the TCB's stack to hold thread-specific data. + * This function may be called anytime after up_create_stack() or + * up_use_stack() have been called but before the task has been started. + * + * Thread data may be kept in the stack (instead of in the TCB) if it is + * accessed by the user code directly. This includes such things as + * argv[]. The stack memory is guaranteed to be in the same protection + * domain as the thread. + * + * The following TCB fields will be re-initialized: + * + * - adj_stack_size: Stack size after removal of the stack frame from + * the stack + * - adj_stack_ptr: Adjusted initial stack pointer after the frame has + * been removed from the stack. This will still be the initial value + * of the stack pointer when the task is started. + * + * Input Parameters: + * - tcb: The TCB of new task + * - frame_size: The size of the stack frame to allocate. + * + * Returned Value: + * - A pointer to bottom of the allocated stack frame. NULL will be + * returned on any failures. The alignment of the returned value is + * the same as the alignment of the stack itself. + * + ****************************************************************************/ + +FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) +{ + uintptr_t topaddr; + + /* Align the frame_size */ + + frame_size = STACK_ALIGN_UP(frame_size); + + /* Is there already a stack allocated? Is it big enough? */ + + if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size) + { + return NULL; + } + + /* Save the adjusted stack values in the struct tcb_s */ + + topaddr = (uintptr_t) tcb->adj_stack_ptr - frame_size; + tcb->adj_stack_ptr = (FAR void *)topaddr; + tcb->adj_stack_size -= frame_size; + + /* Reset the initial stack pointer */ + + tcb->xcp.regs[REG_SP] = (uint32_t) tcb->adj_stack_ptr; + + /* And return the pointer to the allocated region */ + + return (FAR void *)(topaddr + sizeof(uint32_t)); +} diff --git a/arch/misoc/src/minerva/minerva_swint.c b/arch/misoc/src/minerva/minerva_swint.c new file mode 100644 index 00000000000..76be63fc619 --- /dev/null +++ b/arch/misoc/src/minerva/minerva_swint.c @@ -0,0 +1,305 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_swint.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "minerva.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_registerdump + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_SYSCALL_INFO +static void up_registerdump(const uint32_t * regs) +{ +#if 0 + svcinfo("EPC:%08x\n", regs[REG_CSR_MEPC]); + svcinfo("A0:%08x A1:%08x A2:%08x A3:%08x A4:%08x A5:%08x A6:%08x A7:%08x\n", + regs[REG_A0], regs[REG_A1], regs[REG_A2], regs[REG_A3], + regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]); + svcinfo("T0:%08x T1:%08x T2:%08x T3:%08x T4:%08x T5:%08x T6:%08x\n", + regs[REG_T0], regs[REG_T1], regs[REG_T2], regs[REG_T3], + regs[REG_T4], regs[REG_T5], regs[REG_T6]); + svcinfo("S0:%08x S1:%08x S2:%08x S3:%08x S4:%08x S5:%08x S6:%08x S7:%08x\n", + regs[REG_S0], regs[REG_S1], regs[REG_S2], regs[REG_S3], + regs[REG_S4], regs[REG_S5], regs[REG_S6], regs[REG_S7]); + svcinfo("S8:%08x S9:%08x S10:%08x S11:%08x\n", + regs[REG_S8], regs[REG_S9], regs[REG_S10], regs[REG_S11]); +#ifdef MINERVA32_SAVE_GP + svcinfo("GP:%08x SP:%08x FP:%08x TP:%08x RA:%08x\n", + regs[REG_GP], regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]); +#else + svcinfo("SP:%08x FP:%08x TP:%08x RA:%08x\n", + regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]); +#endif +#endif +} +#else +# define up_registerdump(regs) +#endif + +/**************************************************************************** + * Name: dispatch_syscall + * + * Description: + * Call the stub function corresponding to the system call. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_KERNEL +static void dispatch_syscall(void) naked_function; + static void dispatch_syscall(void) +{ +#error "Missing logic" + +/* Refer to arch/arm/src/armv7-m/up_svcall.h for how this is done for ARM */ + +/* __asm__ __volatile__ */ + +/* Save registers */ + +/* Get the base of the stub lookup table */ + +/* Get the offset of the stub for this syscall */ + +/* Load the entry of the stub for this syscall */ + +/* Call the stub */ + +/* Restore regsisters */ + +/* Return from the syscall */ +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: minerva_swint + * + * Description: + * This is software interrupt exception handler that performs context + * switching and manages system calls + * + ****************************************************************************/ + +int minerva_swint(int irq, FAR void *context, FAR void *arg) +{ + uint32_t *regs = (uint32_t *) context; + + DEBUGASSERT(regs != NULL && regs == g_current_regs); + + /* Software interrupt 0 is invoked with REG_A0 (REG_X10) = system call + * command and REG_A1-6 = variable number of arguments depending on the + * system call. + */ + +#ifdef CONFIG_DEBUG_SYSCALL_INFO + svcinfo("Entry: regs: %p cmd: %d\n", regs, regs[REG_A0]); + up_registerdump(regs); +#endif + + /* Handle the SWInt according to the command in $a0 */ + + switch (regs[REG_A0]) + { + /* A0=SYS_restore_context: This a restore context command: void + * up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; At + * this point, the following values are saved in context: A0 = + * SYS_restore_context A1 = restoreregs In this case, we simply need to + * set g_current_regs to restore register area referenced in the saved + * R1. context == g_current_regs is the normal exception return. By + * setting g_current_regs = context[R1], we force the return to the + * saved context referenced in $a1. + */ + + case SYS_restore_context: + { + DEBUGASSERT(regs[REG_A1] != 0); + g_current_regs = (uint32_t *) regs[REG_A1]; + } + break; + + /* A0=SYS_switch_context: This a switch context command: void + * up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); At this + * point, the following values are saved in context: A0 = + * SYS_switch_context A1 = saveregs A2 = restoreregs In this case, we + * save the context registers to the save register area reference by the + * saved contents of R5 and then set g_current_regs to to the save + * register area referenced by the saved contents of R6. + */ + + case SYS_switch_context: + { + DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0); + minerva_copystate((uint32_t *) regs[REG_A1], regs); + g_current_regs = (uint32_t *) regs[REG_A2]; + } + break; + + /* A0=SYS_syscall_return: This a switch context command: void + * up_sycall_return(void); At this point, the following values are saved + * in context: A0 = SYS_syscall_return We need to restore the saved + * return address and return in unprivileged thread mode. + */ + +#ifdef CONFIG_BUILD_KERNEL + case SYS_syscall_return: + { + struct tcb_s *rtcb = sched_self(); + int index = (int)rtcb->xcp.nsyscalls - 1; + + /* Make sure that there is a saved syscall return address. */ + + DEBUGASSERT(index >= 0); + + /* Setup to return to the saved syscall return address in the original + * mode. + */ + + g_current_regs[REG_CSR_MEPC] = rtcb->xcp.syscall[index].sysreturn; +#error "Missing logic -- need to restore the original mode" + rtcb->xcp.nsyscalls = index; + } + break; +#endif + + /* This is not an architecture-specify system call. If NuttX is built + * as a standalone kernel with a system call interface, then all of the + * additional system calls must be handled as in the default case. + */ + + default: + { +#ifdef CONFIG_BUILD_KERNEL + FAR struct tcb_s *rtcb = sched_self(); + int index = rtcb->xcp.nsyscalls; + + /* Verify that the SYS call number is within range */ + + DEBUGASSERT(g_current_regs[REG_A0] < SYS_maxsyscall); + + /* Make sure that we got here that there is a no saved syscall return + * address. We cannot yet handle nested system calls. + */ + + DEBUGASSERT(index < CONFIG_SYS_NNEST); + + /* Setup to return to dispatch_syscall in privileged mode. + */ + + rtcb->xcpsyscall[index].sysreturn = regs[REG_CSR_MEPC]; +#error "Missing logic -- Need to save mode" + rtcb->xcp.nsyscalls = index + 1; + + regs[REG_CSR_MEPC] = (uint32_t) dispatch_syscall; +#error "Missing logic -- Need to set privileged mode" + + /* Offset R0 to account for the reserved values */ + + g_current_regs[REG_A0] -= CONFIG_SYS_RESERVED; +#else + svcerr("ERROR: Bad SYS call: %d\n", regs[REG_A0]); +#endif + } + break; + } + + /* Report what happened. That might difficult in the case of a context + * switch + */ + +#ifdef CONFIG_DEBUG_SYSCALL_INFO + if (regs != g_current_regs) + { + svcinfo("SWInt Return: Context switch!\n"); + up_registerdump((const uint32_t *)g_current_regs); + } + else + { + svcinfo("SWInt Return: %d\n", regs[REG_A0]); + } +#endif + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * g_current_regs will have a different value than it did on entry. If an + * interrupt level context switch has occurred, then restore the floating + * point state and the establish the correct address environment before + * returning from the interrupt. + */ + + if (regs != g_current_regs) + { +#ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint32_t *) g_current_regs); +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously running + * task is closed down gracefully (data caches dump, MMU flushed) and + * set up the address environment for the new thread at the head of + * the ready-to-run list. + */ + + (void)group_addrenv(NULL); +#endif + } +#endif + + return OK; +} diff --git a/arch/misoc/src/minerva/minerva_syscall.S b/arch/misoc/src/minerva/minerva_syscall.S new file mode 100644 index 00000000000..bebd5aa3e48 --- /dev/null +++ b/arch/misoc/src/minerva/minerva_syscall.S @@ -0,0 +1,103 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_syscall.S + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * Derives from RISC-V version: + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .file "up_syscall.S" + .global sys_call0 + .global sys_call1 + .global sys_call2 + .global sys_call3 + .global sys_call4 + .global sys_call5 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_syscall0, up_syscall1, up_syscall2, up_syscall3 + * + * Description: + * up_syscall0 - System call SYS_ argument and no additional parameters. + * up_syscall1 - System call SYS_ argument and one additional parameter. + * up_syscall2 - System call SYS_ argument and two additional parameters. + * up_syscall3 - System call SYS_ argument and three additional parameters. + * up_syscall4 - System call SYS_ argument and four additional parameters. + * up_syscall5 - System call SYS_ argument and five additional parameters. + * + * Assumption: + * All interrupts are disabled except for the software interrupts. + * + ****************************************************************************/ + + .text + +sys_call0: /* a0 holds the syscall number */ +sys_call1: /* a0 holds the syscall number, argument in a1 */ +sys_call2: /* a0 holds the syscall number, arguments in a1 and a2 */ +sys_call3: /* a0 holds the syscall number, arguments in a1, a2, and a3 */ +sys_call4: /* a0 holds the syscall number, arguments in a1, a2, a3 and a4 */ +sys_call5: /* a0 holds the syscall number, arguments in a1, a2, a3, a4 and a5 */ + + /* Issue the ECALL opcode to perform a SW interrupt to the OS */ + + ecall + + /* The actual interrupt may not a occur for a few more cycles. Let's + * put a few nop's here in hope that the SW interrupt occurs during + * the sequence of nops. + */ + + nop + nop + + /* Then return with the result of the software interrupt in v0 */ + + ret + nop diff --git a/arch/misoc/src/minerva/minerva_unblocktask.c b/arch/misoc/src/minerva/minerva_unblocktask.c new file mode 100644 index 00000000000..d28bc04a4b1 --- /dev/null +++ b/arch/misoc/src/minerva/minerva_unblocktask.c @@ -0,0 +1,164 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_unblocktask.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "clock/clock.h" +#include "minerva.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list + * but has been prepped to execute. Move the TCB to the + * ready-to-run list, restore its context, and start execution. + * + * Input Parameters: + * tcb: Refers to the tcb to be unblocked. This tcb is + * in one of the waiting tasks lists. It must be moved to + * the ready-to-run list and, if it is the highest priority + * ready to run task, executed. + * + ****************************************************************************/ + +void up_unblock_task(struct tcb_s *tcb) +{ + struct tcb_s *rtcb = this_task(); + + /* Verify that the context switch can be performed */ + + DEBUGASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) && + (tcb->task_state <= LAST_BLOCKED_STATE)); + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized ready-to-run task + * list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! We need to do a context switch + * to the new task. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. Just copy the + * g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head of + * the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment changes + * will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Restore the exception context of the new task that is ready to + * run (probably tcb). This is the new rtcb at the head of the + * ready-to-run task list. + */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously running + * task is closed down gracefully (data caches dump, MMU flushed) + * and set up the address environment for the new thread at the + * head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Then switch contexts */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the head + * of the ready-to-run list. It does not 'return' in the normal + * sense. When it does return, it is because the blocked task is + * again ready to run and has execution priority. + */ + } + } +} diff --git a/arch/misoc/src/minerva/minerva_vectors.S b/arch/misoc/src/minerva/minerva_vectors.S new file mode 100644 index 00000000000..defe23323d7 --- /dev/null +++ b/arch/misoc/src/minerva/minerva_vectors.S @@ -0,0 +1,204 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_vectors.S + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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. + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Defintions + ****************************************************************************/ + +#define MINERVA_STACK_BASE _ebss +#define MINERVA_STACK_TOP _ebss+CONFIG_IDLETHREAD_STACKSIZE +#define MINERVA_HEAP_BASE MINERVA_STACK_TOP + +#define MIE_MEIE 0x800 +#define CSR_IRQ_MASK 0x330 + +/**************************************************************************** + * Macros + ****************************************************************************/ + + .section .text, "ax", @progbits + .global g_idle_topstack + .global __start + +.macro SAVE_REGS + addi sp, sp, -XCPTCONTEXT_SIZE + sw x0, REG_X0(sp) + sw x1, REG_X1(sp) + sw x3, REG_X3(sp) + sw x4, REG_X4(sp) + sw x5, REG_X5(sp) + sw x6, REG_X6(sp) + sw x7, REG_X7(sp) + sw x8, REG_X8(sp) + sw x9, REG_X9(sp) + sw x10, REG_X10(sp) + sw x11, REG_X11(sp) + sw x12, REG_X12(sp) + sw x13, REG_X13(sp) + sw x14, REG_X14(sp) + sw x15, REG_X15(sp) + sw x16, REG_X16(sp) + sw x17, REG_X17(sp) + sw x18, REG_X18(sp) + sw x19, REG_X19(sp) + sw x20, REG_X20(sp) + sw x21, REG_X21(sp) + sw x22, REG_X22(sp) + sw x23, REG_X23(sp) + sw x24, REG_X24(sp) + sw x25, REG_X25(sp) + sw x26, REG_X26(sp) + sw x27, REG_X27(sp) + sw x28, REG_X28(sp) + sw x29, REG_X29(sp) + sw x30, REG_X30(sp) + sw x31, REG_X31(sp) + csrr t0, mstatus + csrr t1, mepc + csrr t2, mbadaddr + csrr t3, mcause + sw t0, REG_CSR_MSTATUS(sp) + sw t1, REG_CSR_MEPC(sp) + sw t2, REG_CSR_MBADADDR(sp) + sw t3, REG_CSR_MCAUSE(sp) + addi t0, sp, XCPTCONTEXT_SIZE + sw t0, REG_X2(sp) + .endm + +/* restore regs and `mret` */ + + .macro RESTORE_REGS + lw x1, REG_X1(a0) + lw x2, REG_X2(a0) + lw x3, REG_X3(a0) + lw x4, REG_X4(a0) + lw x6, REG_X6(a0) + lw x7, REG_X7(a0) + lw x8, REG_X8(a0) + lw x9, REG_X9(a0) + lw x11, REG_X11(a0) + lw x12, REG_X12(a0) + lw x13, REG_X13(a0) + lw x14, REG_X14(a0) + lw x15, REG_X15(a0) + lw x16, REG_X16(a0) + lw x17, REG_X17(a0) + lw x18, REG_X18(a0) + lw x19, REG_X19(a0) + lw x20, REG_X20(a0) + lw x21, REG_X21(a0) + lw x22, REG_X22(a0) + lw x23, REG_X23(a0) + lw x24, REG_X24(a0) + lw x25, REG_X25(a0) + lw x26, REG_X26(a0) + lw x27, REG_X27(a0) + lw x28, REG_X28(a0) + lw x29, REG_X29(a0) + lw x30, REG_X30(a0) + lw x31, REG_X31(a0) + + lw t0, REG_CSR_MEPC(a0) + csrw mepc, t0 + + lw t0, REG_CSR_MSTATUS(a0) + csrw mstatus, t0 + + lw x5, REG_X5(a0) + lw x10, REG_X10(a0) + .endm + +/**************************************************************************** + * Reset Handler + ****************************************************************************/ + +__start: +_reset_handler: + /* Set stack pointer */ + + la sp, _fstack + la t0, trap_entry + csrw mtvec, t0 + + /* Initialize .bss */ + + la t0, _sbss + la t1, _ebss +1: beq t0, t1, 2f + sw zero, 0(t0) + addi t0, t0, 4 + j 1b +2: +#if 0 /* REVISIT */ + /* Enable external interrupts */ + + li t0, MIE_MEIE + csrs mie, t0 +#endif + + call nx_start +1: j 1b + +trap_entry: + SAVE_REGS + mv a0, sp + call minerva_doexception + RESTORE_REGS + mret + nop + nop + nop + nop + + /* This global variable is unsigned long g_idle_topstack and is + * exported from here only because of its coupling to other + * uses of _ebss in this file + */ + + .data + .align 4 + .type g_idle_topstack, object + +g_idle_topstack: + .long MINERVA_STACK_TOP + .size g_idle_topstack, .-g_idle_topstack + .end diff --git a/configs/Kconfig b/configs/Kconfig index 034ecbd2fe7..eded6478280 100644 --- a/configs/Kconfig +++ b/configs/Kconfig @@ -520,13 +520,19 @@ config ARCH_BOARD_MICROPENDOUS3 be populated with either an AVR AT90USB646, 647, 1286, or 1287 MCU. Support is configured for the AT90USB647. -config ARCH_BOARD_MISOC +config ARCH_BOARD_MISOC_QEMU bool "Qemu LM32 demo" depends on ARCH_CHIP_LM32 ---help--- This configuration is port to NuttX running on a Qemu LM32 system. You can find the Qemu setup at https://bitbucket.org/key2/qemu +config ARCH_BOARD_MISOC_VERILATOR + bool "Verilator Misoc demo" + depends on ARCH_CHIP_LM32 || ARCH_CHIP_MINERVA + ---help--- + This configuration is port to NuttX running on Verilator. + config ARCH_BOARD_MOTEINO_MEGA bool "LowPowerLab MoteinoMEGA" depends on ARCH_CHIP_ATMEGA1284P @@ -1823,7 +1829,7 @@ config ARCH_BOARD default "metro-m4" if ARCH_BOARD_METRO_M4 default "micropendous3" if ARCH_BOARD_MICROPENDOUS3 default "mirtoo" if ARCH_BOARD_MIRTOO - default "misoc" if ARCH_BOARD_MISOC + default "misoc" if ARCH_BOARD_MISOC_QEMU || ARCH_BOARD_MISOC_VERILATOR default "moteino-mega" if ARCH_BOARD_MOTEINO_MEGA default "ne64badge" if ARCH_BOARD_NE64BADGE default "nrf52-generic" if ARCH_BOARD_NRF52_GENERIC @@ -2138,7 +2144,7 @@ endif if ARCH_BOARD_MIRTOO source "configs/mirtoo/Kconfig" endif -if ARCH_BOARD_MISOC +if ARCH_BOARD_MISOC_QEMU || ARCH_BOARD_MISOC_VERILATOR source "configs/misoc/Kconfig" endif if ARCH_BOARD_MOTEINO_MEGA diff --git a/configs/misoc/include/generated-sample/csr.h b/configs/misoc/include/generated-sample/csr.h deleted file mode 100644 index e58b0e0bf4f..00000000000 --- a/configs/misoc/include/generated-sample/csr.h +++ /dev/null @@ -1,653 +0,0 @@ -#ifndef __GENERATED_CSR_H -#define __GENERATED_CSR_H -#include - -/* ddrphy */ -#define CSR_DDRPHY_BASE 0xe0008800 -#define CSR_DDRPHY_DLY_SEL_ADDR 0xe0008800 -#define CSR_DDRPHY_DLY_SEL_SIZE 1 -static inline unsigned char ddrphy_dly_sel_read(void) { - unsigned char r = MMPTR(0xe0008800); - return r; -} -static inline void ddrphy_dly_sel_write(unsigned char value) { - MMPTR(0xe0008800) = value; -} -#define CSR_DDRPHY_RDLY_DQ_RST_ADDR 0xe0008804 -#define CSR_DDRPHY_RDLY_DQ_RST_SIZE 1 -static inline unsigned char ddrphy_rdly_dq_rst_read(void) { - unsigned char r = MMPTR(0xe0008804); - return r; -} -static inline void ddrphy_rdly_dq_rst_write(unsigned char value) { - MMPTR(0xe0008804) = value; -} -#define CSR_DDRPHY_RDLY_DQ_INC_ADDR 0xe0008808 -#define CSR_DDRPHY_RDLY_DQ_INC_SIZE 1 -static inline unsigned char ddrphy_rdly_dq_inc_read(void) { - unsigned char r = MMPTR(0xe0008808); - return r; -} -static inline void ddrphy_rdly_dq_inc_write(unsigned char value) { - MMPTR(0xe0008808) = value; -} -#define CSR_DDRPHY_RDLY_DQ_BITSLIP_ADDR 0xe000880c -#define CSR_DDRPHY_RDLY_DQ_BITSLIP_SIZE 1 -static inline unsigned char ddrphy_rdly_dq_bitslip_read(void) { - unsigned char r = MMPTR(0xe000880c); - return r; -} -static inline void ddrphy_rdly_dq_bitslip_write(unsigned char value) { - MMPTR(0xe000880c) = value; -} - -/* ethmac */ -#define CSR_ETHMAC_BASE 0xe000f800 -#define CSR_ETHMAC_SRAM_WRITER_SLOT_ADDR 0xe000f800 -#define CSR_ETHMAC_SRAM_WRITER_SLOT_SIZE 1 -static inline unsigned char ethmac_sram_writer_slot_read(void) { - unsigned char r = MMPTR(0xe000f800); - return r; -} -#define CSR_ETHMAC_SRAM_WRITER_LENGTH_ADDR 0xe000f804 -#define CSR_ETHMAC_SRAM_WRITER_LENGTH_SIZE 4 -static inline unsigned int ethmac_sram_writer_length_read(void) { - unsigned int r = MMPTR(0xe000f804); - r <<= 8; - r |= MMPTR(0xe000f808); - r <<= 8; - r |= MMPTR(0xe000f80c); - r <<= 8; - r |= MMPTR(0xe000f810); - return r; -} -#define CSR_ETHMAC_SRAM_WRITER_EV_STATUS_ADDR 0xe000f814 -#define CSR_ETHMAC_SRAM_WRITER_EV_STATUS_SIZE 1 -static inline unsigned char ethmac_sram_writer_ev_status_read(void) { - unsigned char r = MMPTR(0xe000f814); - return r; -} -static inline void ethmac_sram_writer_ev_status_write(unsigned char value) { - MMPTR(0xe000f814) = value; -} -#define CSR_ETHMAC_SRAM_WRITER_EV_PENDING_ADDR 0xe000f818 -#define CSR_ETHMAC_SRAM_WRITER_EV_PENDING_SIZE 1 -static inline unsigned char ethmac_sram_writer_ev_pending_read(void) { - unsigned char r = MMPTR(0xe000f818); - return r; -} -static inline void ethmac_sram_writer_ev_pending_write(unsigned char value) { - MMPTR(0xe000f818) = value; -} -#define CSR_ETHMAC_SRAM_WRITER_EV_ENABLE_ADDR 0xe000f81c -#define CSR_ETHMAC_SRAM_WRITER_EV_ENABLE_SIZE 1 -static inline unsigned char ethmac_sram_writer_ev_enable_read(void) { - unsigned char r = MMPTR(0xe000f81c); - return r; -} -static inline void ethmac_sram_writer_ev_enable_write(unsigned char value) { - MMPTR(0xe000f81c) = value; -} -#define CSR_ETHMAC_SRAM_READER_START_ADDR 0xe000f820 -#define CSR_ETHMAC_SRAM_READER_START_SIZE 1 -static inline unsigned char ethmac_sram_reader_start_read(void) { - unsigned char r = MMPTR(0xe000f820); - return r; -} -static inline void ethmac_sram_reader_start_write(unsigned char value) { - MMPTR(0xe000f820) = value; -} -#define CSR_ETHMAC_SRAM_READER_READY_ADDR 0xe000f824 -#define CSR_ETHMAC_SRAM_READER_READY_SIZE 1 -static inline unsigned char ethmac_sram_reader_ready_read(void) { - unsigned char r = MMPTR(0xe000f824); - return r; -} -#define CSR_ETHMAC_SRAM_READER_SLOT_ADDR 0xe000f828 -#define CSR_ETHMAC_SRAM_READER_SLOT_SIZE 1 -static inline unsigned char ethmac_sram_reader_slot_read(void) { - unsigned char r = MMPTR(0xe000f828); - return r; -} -static inline void ethmac_sram_reader_slot_write(unsigned char value) { - MMPTR(0xe000f828) = value; -} -#define CSR_ETHMAC_SRAM_READER_LENGTH_ADDR 0xe000f82c -#define CSR_ETHMAC_SRAM_READER_LENGTH_SIZE 2 -static inline unsigned short int ethmac_sram_reader_length_read(void) { - unsigned short int r = MMPTR(0xe000f82c); - r <<= 8; - r |= MMPTR(0xe000f830); - return r; -} -static inline void ethmac_sram_reader_length_write(unsigned short int value) { - MMPTR(0xe000f82c) = value >> 8; - MMPTR(0xe000f830) = value; -} -#define CSR_ETHMAC_SRAM_READER_EV_STATUS_ADDR 0xe000f834 -#define CSR_ETHMAC_SRAM_READER_EV_STATUS_SIZE 1 -static inline unsigned char ethmac_sram_reader_ev_status_read(void) { - unsigned char r = MMPTR(0xe000f834); - return r; -} -static inline void ethmac_sram_reader_ev_status_write(unsigned char value) { - MMPTR(0xe000f834) = value; -} -#define CSR_ETHMAC_SRAM_READER_EV_PENDING_ADDR 0xe000f838 -#define CSR_ETHMAC_SRAM_READER_EV_PENDING_SIZE 1 -static inline unsigned char ethmac_sram_reader_ev_pending_read(void) { - unsigned char r = MMPTR(0xe000f838); - return r; -} -static inline void ethmac_sram_reader_ev_pending_write(unsigned char value) { - MMPTR(0xe000f838) = value; -} -#define CSR_ETHMAC_SRAM_READER_EV_ENABLE_ADDR 0xe000f83c -#define CSR_ETHMAC_SRAM_READER_EV_ENABLE_SIZE 1 -static inline unsigned char ethmac_sram_reader_ev_enable_read(void) { - unsigned char r = MMPTR(0xe000f83c); - return r; -} -static inline void ethmac_sram_reader_ev_enable_write(unsigned char value) { - MMPTR(0xe000f83c) = value; -} -#define CSR_ETHMAC_PREAMBLE_CRC_ADDR 0xe000f840 -#define CSR_ETHMAC_PREAMBLE_CRC_SIZE 1 -static inline unsigned char ethmac_preamble_crc_read(void) { - unsigned char r = MMPTR(0xe000f840); - return r; -} - -/* ethphy */ -#define CSR_ETHPHY_BASE 0xe000f000 -#define CSR_ETHPHY_CRG_RESET_ADDR 0xe000f000 -#define CSR_ETHPHY_CRG_RESET_SIZE 1 -static inline unsigned char ethphy_crg_reset_read(void) { - unsigned char r = MMPTR(0xe000f000); - return r; -} -static inline void ethphy_crg_reset_write(unsigned char value) { - MMPTR(0xe000f000) = value; -} -#define CSR_ETHPHY_MDIO_W_ADDR 0xe000f004 -#define CSR_ETHPHY_MDIO_W_SIZE 1 -static inline unsigned char ethphy_mdio_w_read(void) { - unsigned char r = MMPTR(0xe000f004); - return r; -} -static inline void ethphy_mdio_w_write(unsigned char value) { - MMPTR(0xe000f004) = value; -} -#define CSR_ETHPHY_MDIO_R_ADDR 0xe000f008 -#define CSR_ETHPHY_MDIO_R_SIZE 1 -static inline unsigned char ethphy_mdio_r_read(void) { - unsigned char r = MMPTR(0xe000f008); - return r; -} - -/* sdram */ -#define CSR_SDRAM_BASE 0xe0004000 -#define CSR_SDRAM_DFII_CONTROL_ADDR 0xe0004000 -#define CSR_SDRAM_DFII_CONTROL_SIZE 1 -static inline unsigned char sdram_dfii_control_read(void) { - unsigned char r = MMPTR(0xe0004000); - return r; -} -static inline void sdram_dfii_control_write(unsigned char value) { - MMPTR(0xe0004000) = value; -} -#define CSR_SDRAM_DFII_PI0_COMMAND_ADDR 0xe0004004 -#define CSR_SDRAM_DFII_PI0_COMMAND_SIZE 1 -static inline unsigned char sdram_dfii_pi0_command_read(void) { - unsigned char r = MMPTR(0xe0004004); - return r; -} -static inline void sdram_dfii_pi0_command_write(unsigned char value) { - MMPTR(0xe0004004) = value; -} -#define CSR_SDRAM_DFII_PI0_COMMAND_ISSUE_ADDR 0xe0004008 -#define CSR_SDRAM_DFII_PI0_COMMAND_ISSUE_SIZE 1 -static inline unsigned char sdram_dfii_pi0_command_issue_read(void) { - unsigned char r = MMPTR(0xe0004008); - return r; -} -static inline void sdram_dfii_pi0_command_issue_write(unsigned char value) { - MMPTR(0xe0004008) = value; -} -#define CSR_SDRAM_DFII_PI0_ADDRESS_ADDR 0xe000400c -#define CSR_SDRAM_DFII_PI0_ADDRESS_SIZE 2 -static inline unsigned short int sdram_dfii_pi0_address_read(void) { - unsigned short int r = MMPTR(0xe000400c); - r <<= 8; - r |= MMPTR(0xe0004010); - return r; -} -static inline void sdram_dfii_pi0_address_write(unsigned short int value) { - MMPTR(0xe000400c) = value >> 8; - MMPTR(0xe0004010) = value; -} -#define CSR_SDRAM_DFII_PI0_BADDRESS_ADDR 0xe0004014 -#define CSR_SDRAM_DFII_PI0_BADDRESS_SIZE 1 -static inline unsigned char sdram_dfii_pi0_baddress_read(void) { - unsigned char r = MMPTR(0xe0004014); - return r; -} -static inline void sdram_dfii_pi0_baddress_write(unsigned char value) { - MMPTR(0xe0004014) = value; -} -#define CSR_SDRAM_DFII_PI0_WRDATA_ADDR 0xe0004018 -#define CSR_SDRAM_DFII_PI0_WRDATA_SIZE 4 -static inline unsigned int sdram_dfii_pi0_wrdata_read(void) { - unsigned int r = MMPTR(0xe0004018); - r <<= 8; - r |= MMPTR(0xe000401c); - r <<= 8; - r |= MMPTR(0xe0004020); - r <<= 8; - r |= MMPTR(0xe0004024); - return r; -} -static inline void sdram_dfii_pi0_wrdata_write(unsigned int value) { - MMPTR(0xe0004018) = value >> 24; - MMPTR(0xe000401c) = value >> 16; - MMPTR(0xe0004020) = value >> 8; - MMPTR(0xe0004024) = value; -} -#define CSR_SDRAM_DFII_PI0_RDDATA_ADDR 0xe0004028 -#define CSR_SDRAM_DFII_PI0_RDDATA_SIZE 4 -static inline unsigned int sdram_dfii_pi0_rddata_read(void) { - unsigned int r = MMPTR(0xe0004028); - r <<= 8; - r |= MMPTR(0xe000402c); - r <<= 8; - r |= MMPTR(0xe0004030); - r <<= 8; - r |= MMPTR(0xe0004034); - return r; -} -#define CSR_SDRAM_DFII_PI1_COMMAND_ADDR 0xe0004038 -#define CSR_SDRAM_DFII_PI1_COMMAND_SIZE 1 -static inline unsigned char sdram_dfii_pi1_command_read(void) { - unsigned char r = MMPTR(0xe0004038); - return r; -} -static inline void sdram_dfii_pi1_command_write(unsigned char value) { - MMPTR(0xe0004038) = value; -} -#define CSR_SDRAM_DFII_PI1_COMMAND_ISSUE_ADDR 0xe000403c -#define CSR_SDRAM_DFII_PI1_COMMAND_ISSUE_SIZE 1 -static inline unsigned char sdram_dfii_pi1_command_issue_read(void) { - unsigned char r = MMPTR(0xe000403c); - return r; -} -static inline void sdram_dfii_pi1_command_issue_write(unsigned char value) { - MMPTR(0xe000403c) = value; -} -#define CSR_SDRAM_DFII_PI1_ADDRESS_ADDR 0xe0004040 -#define CSR_SDRAM_DFII_PI1_ADDRESS_SIZE 2 -static inline unsigned short int sdram_dfii_pi1_address_read(void) { - unsigned short int r = MMPTR(0xe0004040); - r <<= 8; - r |= MMPTR(0xe0004044); - return r; -} -static inline void sdram_dfii_pi1_address_write(unsigned short int value) { - MMPTR(0xe0004040) = value >> 8; - MMPTR(0xe0004044) = value; -} -#define CSR_SDRAM_DFII_PI1_BADDRESS_ADDR 0xe0004048 -#define CSR_SDRAM_DFII_PI1_BADDRESS_SIZE 1 -static inline unsigned char sdram_dfii_pi1_baddress_read(void) { - unsigned char r = MMPTR(0xe0004048); - return r; -} -static inline void sdram_dfii_pi1_baddress_write(unsigned char value) { - MMPTR(0xe0004048) = value; -} -#define CSR_SDRAM_DFII_PI1_WRDATA_ADDR 0xe000404c -#define CSR_SDRAM_DFII_PI1_WRDATA_SIZE 4 -static inline unsigned int sdram_dfii_pi1_wrdata_read(void) { - unsigned int r = MMPTR(0xe000404c); - r <<= 8; - r |= MMPTR(0xe0004050); - r <<= 8; - r |= MMPTR(0xe0004054); - r <<= 8; - r |= MMPTR(0xe0004058); - return r; -} -static inline void sdram_dfii_pi1_wrdata_write(unsigned int value) { - MMPTR(0xe000404c) = value >> 24; - MMPTR(0xe0004050) = value >> 16; - MMPTR(0xe0004054) = value >> 8; - MMPTR(0xe0004058) = value; -} -#define CSR_SDRAM_DFII_PI1_RDDATA_ADDR 0xe000405c -#define CSR_SDRAM_DFII_PI1_RDDATA_SIZE 4 -static inline unsigned int sdram_dfii_pi1_rddata_read(void) { - unsigned int r = MMPTR(0xe000405c); - r <<= 8; - r |= MMPTR(0xe0004060); - r <<= 8; - r |= MMPTR(0xe0004064); - r <<= 8; - r |= MMPTR(0xe0004068); - return r; -} -#define CSR_SDRAM_DFII_PI2_COMMAND_ADDR 0xe000406c -#define CSR_SDRAM_DFII_PI2_COMMAND_SIZE 1 -static inline unsigned char sdram_dfii_pi2_command_read(void) { - unsigned char r = MMPTR(0xe000406c); - return r; -} -static inline void sdram_dfii_pi2_command_write(unsigned char value) { - MMPTR(0xe000406c) = value; -} -#define CSR_SDRAM_DFII_PI2_COMMAND_ISSUE_ADDR 0xe0004070 -#define CSR_SDRAM_DFII_PI2_COMMAND_ISSUE_SIZE 1 -static inline unsigned char sdram_dfii_pi2_command_issue_read(void) { - unsigned char r = MMPTR(0xe0004070); - return r; -} -static inline void sdram_dfii_pi2_command_issue_write(unsigned char value) { - MMPTR(0xe0004070) = value; -} -#define CSR_SDRAM_DFII_PI2_ADDRESS_ADDR 0xe0004074 -#define CSR_SDRAM_DFII_PI2_ADDRESS_SIZE 2 -static inline unsigned short int sdram_dfii_pi2_address_read(void) { - unsigned short int r = MMPTR(0xe0004074); - r <<= 8; - r |= MMPTR(0xe0004078); - return r; -} -static inline void sdram_dfii_pi2_address_write(unsigned short int value) { - MMPTR(0xe0004074) = value >> 8; - MMPTR(0xe0004078) = value; -} -#define CSR_SDRAM_DFII_PI2_BADDRESS_ADDR 0xe000407c -#define CSR_SDRAM_DFII_PI2_BADDRESS_SIZE 1 -static inline unsigned char sdram_dfii_pi2_baddress_read(void) { - unsigned char r = MMPTR(0xe000407c); - return r; -} -static inline void sdram_dfii_pi2_baddress_write(unsigned char value) { - MMPTR(0xe000407c) = value; -} -#define CSR_SDRAM_DFII_PI2_WRDATA_ADDR 0xe0004080 -#define CSR_SDRAM_DFII_PI2_WRDATA_SIZE 4 -static inline unsigned int sdram_dfii_pi2_wrdata_read(void) { - unsigned int r = MMPTR(0xe0004080); - r <<= 8; - r |= MMPTR(0xe0004084); - r <<= 8; - r |= MMPTR(0xe0004088); - r <<= 8; - r |= MMPTR(0xe000408c); - return r; -} -static inline void sdram_dfii_pi2_wrdata_write(unsigned int value) { - MMPTR(0xe0004080) = value >> 24; - MMPTR(0xe0004084) = value >> 16; - MMPTR(0xe0004088) = value >> 8; - MMPTR(0xe000408c) = value; -} -#define CSR_SDRAM_DFII_PI2_RDDATA_ADDR 0xe0004090 -#define CSR_SDRAM_DFII_PI2_RDDATA_SIZE 4 -static inline unsigned int sdram_dfii_pi2_rddata_read(void) { - unsigned int r = MMPTR(0xe0004090); - r <<= 8; - r |= MMPTR(0xe0004094); - r <<= 8; - r |= MMPTR(0xe0004098); - r <<= 8; - r |= MMPTR(0xe000409c); - return r; -} -#define CSR_SDRAM_DFII_PI3_COMMAND_ADDR 0xe00040a0 -#define CSR_SDRAM_DFII_PI3_COMMAND_SIZE 1 -static inline unsigned char sdram_dfii_pi3_command_read(void) { - unsigned char r = MMPTR(0xe00040a0); - return r; -} -static inline void sdram_dfii_pi3_command_write(unsigned char value) { - MMPTR(0xe00040a0) = value; -} -#define CSR_SDRAM_DFII_PI3_COMMAND_ISSUE_ADDR 0xe00040a4 -#define CSR_SDRAM_DFII_PI3_COMMAND_ISSUE_SIZE 1 -static inline unsigned char sdram_dfii_pi3_command_issue_read(void) { - unsigned char r = MMPTR(0xe00040a4); - return r; -} -static inline void sdram_dfii_pi3_command_issue_write(unsigned char value) { - MMPTR(0xe00040a4) = value; -} -#define CSR_SDRAM_DFII_PI3_ADDRESS_ADDR 0xe00040a8 -#define CSR_SDRAM_DFII_PI3_ADDRESS_SIZE 2 -static inline unsigned short int sdram_dfii_pi3_address_read(void) { - unsigned short int r = MMPTR(0xe00040a8); - r <<= 8; - r |= MMPTR(0xe00040ac); - return r; -} -static inline void sdram_dfii_pi3_address_write(unsigned short int value) { - MMPTR(0xe00040a8) = value >> 8; - MMPTR(0xe00040ac) = value; -} -#define CSR_SDRAM_DFII_PI3_BADDRESS_ADDR 0xe00040b0 -#define CSR_SDRAM_DFII_PI3_BADDRESS_SIZE 1 -static inline unsigned char sdram_dfii_pi3_baddress_read(void) { - unsigned char r = MMPTR(0xe00040b0); - return r; -} -static inline void sdram_dfii_pi3_baddress_write(unsigned char value) { - MMPTR(0xe00040b0) = value; -} -#define CSR_SDRAM_DFII_PI3_WRDATA_ADDR 0xe00040b4 -#define CSR_SDRAM_DFII_PI3_WRDATA_SIZE 4 -static inline unsigned int sdram_dfii_pi3_wrdata_read(void) { - unsigned int r = MMPTR(0xe00040b4); - r <<= 8; - r |= MMPTR(0xe00040b8); - r <<= 8; - r |= MMPTR(0xe00040bc); - r <<= 8; - r |= MMPTR(0xe00040c0); - return r; -} -static inline void sdram_dfii_pi3_wrdata_write(unsigned int value) { - MMPTR(0xe00040b4) = value >> 24; - MMPTR(0xe00040b8) = value >> 16; - MMPTR(0xe00040bc) = value >> 8; - MMPTR(0xe00040c0) = value; -} -#define CSR_SDRAM_DFII_PI3_RDDATA_ADDR 0xe00040c4 -#define CSR_SDRAM_DFII_PI3_RDDATA_SIZE 4 -static inline unsigned int sdram_dfii_pi3_rddata_read(void) { - unsigned int r = MMPTR(0xe00040c4); - r <<= 8; - r |= MMPTR(0xe00040c8); - r <<= 8; - r |= MMPTR(0xe00040cc); - r <<= 8; - r |= MMPTR(0xe00040d0); - return r; -} - -/* timer0 */ -#define CSR_TIMER0_BASE 0xe0002000 -#define CSR_TIMER0_LOAD_ADDR 0xe0002000 -#define CSR_TIMER0_LOAD_SIZE 4 -static inline unsigned int timer0_load_read(void) { - unsigned int r = MMPTR(0xe0002000); - r <<= 8; - r |= MMPTR(0xe0002004); - r <<= 8; - r |= MMPTR(0xe0002008); - r <<= 8; - r |= MMPTR(0xe000200c); - return r; -} -static inline void timer0_load_write(unsigned int value) { - MMPTR(0xe0002000) = value >> 24; - MMPTR(0xe0002004) = value >> 16; - MMPTR(0xe0002008) = value >> 8; - MMPTR(0xe000200c) = value; -} -#define CSR_TIMER0_RELOAD_ADDR 0xe0002010 -#define CSR_TIMER0_RELOAD_SIZE 4 -static inline unsigned int timer0_reload_read(void) { - unsigned int r = MMPTR(0xe0002010); - r <<= 8; - r |= MMPTR(0xe0002014); - r <<= 8; - r |= MMPTR(0xe0002018); - r <<= 8; - r |= MMPTR(0xe000201c); - return r; -} -static inline void timer0_reload_write(unsigned int value) { - MMPTR(0xe0002010) = value >> 24; - MMPTR(0xe0002014) = value >> 16; - MMPTR(0xe0002018) = value >> 8; - MMPTR(0xe000201c) = value; -} -#define CSR_TIMER0_EN_ADDR 0xe0002020 -#define CSR_TIMER0_EN_SIZE 1 -static inline unsigned char timer0_en_read(void) { - unsigned char r = MMPTR(0xe0002020); - return r; -} -static inline void timer0_en_write(unsigned char value) { - MMPTR(0xe0002020) = value; -} -#define CSR_TIMER0_UPDATE_VALUE_ADDR 0xe0002024 -#define CSR_TIMER0_UPDATE_VALUE_SIZE 1 -static inline unsigned char timer0_update_value_read(void) { - unsigned char r = MMPTR(0xe0002024); - return r; -} -static inline void timer0_update_value_write(unsigned char value) { - MMPTR(0xe0002024) = value; -} -#define CSR_TIMER0_VALUE_ADDR 0xe0002028 -#define CSR_TIMER0_VALUE_SIZE 4 -static inline unsigned int timer0_value_read(void) { - unsigned int r = MMPTR(0xe0002028); - r <<= 8; - r |= MMPTR(0xe000202c); - r <<= 8; - r |= MMPTR(0xe0002030); - r <<= 8; - r |= MMPTR(0xe0002034); - return r; -} -#define CSR_TIMER0_EV_STATUS_ADDR 0xe0002038 -#define CSR_TIMER0_EV_STATUS_SIZE 1 -static inline unsigned char timer0_ev_status_read(void) { - unsigned char r = MMPTR(0xe0002038); - return r; -} -static inline void timer0_ev_status_write(unsigned char value) { - MMPTR(0xe0002038) = value; -} -#define CSR_TIMER0_EV_PENDING_ADDR 0xe000203c -#define CSR_TIMER0_EV_PENDING_SIZE 1 -static inline unsigned char timer0_ev_pending_read(void) { - unsigned char r = MMPTR(0xe000203c); - return r; -} -static inline void timer0_ev_pending_write(unsigned char value) { - MMPTR(0xe000203c) = value; -} -#define CSR_TIMER0_EV_ENABLE_ADDR 0xe0002040 -#define CSR_TIMER0_EV_ENABLE_SIZE 1 -static inline unsigned char timer0_ev_enable_read(void) { - unsigned char r = MMPTR(0xe0002040); - return r; -} -static inline void timer0_ev_enable_write(unsigned char value) { - MMPTR(0xe0002040) = value; -} - -/* uart */ -#define CSR_UART_BASE 0xe0001000 -#define CSR_UART_RXTX_ADDR 0xe0001000 -#define CSR_UART_RXTX_SIZE 1 -static inline unsigned char uart_rxtx_read(void) { - unsigned char r = MMPTR(0xe0001000); - return r; -} -static inline void uart_rxtx_write(unsigned char value) { - MMPTR(0xe0001000) = value; -} -#define CSR_UART_TXFULL_ADDR 0xe0001004 -#define CSR_UART_TXFULL_SIZE 1 -static inline unsigned char uart_txfull_read(void) { - unsigned char r = MMPTR(0xe0001004); - return r; -} -#define CSR_UART_RXEMPTY_ADDR 0xe0001008 -#define CSR_UART_RXEMPTY_SIZE 1 -static inline unsigned char uart_rxempty_read(void) { - unsigned char r = MMPTR(0xe0001008); - return r; -} -#define CSR_UART_EV_STATUS_ADDR 0xe000100c -#define CSR_UART_EV_STATUS_SIZE 1 -static inline unsigned char uart_ev_status_read(void) { - unsigned char r = MMPTR(0xe000100c); - return r; -} -static inline void uart_ev_status_write(unsigned char value) { - MMPTR(0xe000100c) = value; -} -#define CSR_UART_EV_PENDING_ADDR 0xe0001010 -#define CSR_UART_EV_PENDING_SIZE 1 -static inline unsigned char uart_ev_pending_read(void) { - unsigned char r = MMPTR(0xe0001010); - return r; -} -static inline void uart_ev_pending_write(unsigned char value) { - MMPTR(0xe0001010) = value; -} -#define CSR_UART_EV_ENABLE_ADDR 0xe0001014 -#define CSR_UART_EV_ENABLE_SIZE 1 -static inline unsigned char uart_ev_enable_read(void) { - unsigned char r = MMPTR(0xe0001014); - return r; -} -static inline void uart_ev_enable_write(unsigned char value) { - MMPTR(0xe0001014) = value; -} - -/* uart_phy */ -#define CSR_UART_PHY_BASE 0xe0000800 -#define CSR_UART_PHY_TUNING_WORD_ADDR 0xe0000800 -#define CSR_UART_PHY_TUNING_WORD_SIZE 4 -static inline unsigned int uart_phy_tuning_word_read(void) { - unsigned int r = MMPTR(0xe0000800); - r <<= 8; - r |= MMPTR(0xe0000804); - r <<= 8; - r |= MMPTR(0xe0000808); - r <<= 8; - r |= MMPTR(0xe000080c); - return r; -} -static inline void uart_phy_tuning_word_write(unsigned int value) { - MMPTR(0xe0000800) = value >> 24; - MMPTR(0xe0000804) = value >> 16; - MMPTR(0xe0000808) = value >> 8; - MMPTR(0xe000080c) = value; -} - -/* constants */ -#define UART_INTERRUPT 0 -#define TIMER0_INTERRUPT 1 -#define ETHMAC_INTERRUPT 2 -#define SYSTEM_CLOCK_FREQUENCY 100000000 -#define A7DDRPHY_BITSLIP 2 -#define A7DDRPHY_DELAY 6 -#define L2_SIZE 8192 - -#endif diff --git a/configs/misoc/include/generated-sample/mem.h b/configs/misoc/include/generated-sample/mem.h deleted file mode 100644 index f4a9c9c6435..00000000000 --- a/configs/misoc/include/generated-sample/mem.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __GENERATED_MEM_H -#define __GENERATED_MEM_H - -#define ROM_BASE 0x00000000 -#define ROM_SIZE 0x00008000 - -#define SRAM_BASE 0x10000000 -#define SRAM_SIZE 0x00008000 - -#define MAIN_RAM_BASE 0x40000000 -#define MAIN_RAM_SIZE 0x10000000 - -#define ETHMAC_BASE 0xb0000000 -#define ETHMAC_SIZE 0x00002000 - -#endif diff --git a/configs/misoc/include/generated-sample/output_format.ld b/configs/misoc/include/generated-sample/output_format.ld deleted file mode 100644 index 72acc74d0f7..00000000000 --- a/configs/misoc/include/generated-sample/output_format.ld +++ /dev/null @@ -1 +0,0 @@ -OUTPUT_FORMAT("elf32-lm32") diff --git a/configs/misoc/include/generated-sample/regions.ld b/configs/misoc/include/generated-sample/regions.ld deleted file mode 100644 index 1708c3a309a..00000000000 --- a/configs/misoc/include/generated-sample/regions.ld +++ /dev/null @@ -1,6 +0,0 @@ -MEMORY { - rom : ORIGIN = 0x00000000, LENGTH = 0x00008000 - sram : ORIGIN = 0x10000000, LENGTH = 0x00008000 - main_ram : ORIGIN = 0x40000000, LENGTH = 0x10000000 - ethmac : ORIGIN = 0xb0000000, LENGTH = 0x00002000 -} diff --git a/configs/misoc/include/generated-sample/sdram_phy.h b/configs/misoc/include/generated-sample/sdram_phy.h deleted file mode 100644 index 646cf7009ad..00000000000 --- a/configs/misoc/include/generated-sample/sdram_phy.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef __GENERATED_SDRAM_PHY_H -#define __GENERATED_SDRAM_PHY_H -#include -#include -#include - -#define DFII_NPHASES 4 - -static void cdelay(int i); - -static void command_p0(int cmd) -{ - sdram_dfii_pi0_command_write(cmd); - sdram_dfii_pi0_command_issue_write(1); -} -static void command_p1(int cmd) -{ - sdram_dfii_pi1_command_write(cmd); - sdram_dfii_pi1_command_issue_write(1); -} -static void command_p2(int cmd) -{ - sdram_dfii_pi2_command_write(cmd); - sdram_dfii_pi2_command_issue_write(1); -} -static void command_p3(int cmd) -{ - sdram_dfii_pi3_command_write(cmd); - sdram_dfii_pi3_command_issue_write(1); -} - - -#define sdram_dfii_pird_address_write(X) sdram_dfii_pi0_address_write(X) -#define sdram_dfii_piwr_address_write(X) sdram_dfii_pi2_address_write(X) - -#define sdram_dfii_pird_baddress_write(X) sdram_dfii_pi0_baddress_write(X) -#define sdram_dfii_piwr_baddress_write(X) sdram_dfii_pi2_baddress_write(X) - -#define command_prd(X) command_p0(X) -#define command_pwr(X) command_p2(X) - -#define DFII_PIX_DATA_SIZE CSR_SDRAM_DFII_PI0_WRDATA_SIZE - -const unsigned int sdram_dfii_pix_wrdata_addr[4] = { - CSR_SDRAM_DFII_PI0_WRDATA_ADDR, - CSR_SDRAM_DFII_PI1_WRDATA_ADDR, - CSR_SDRAM_DFII_PI2_WRDATA_ADDR, - CSR_SDRAM_DFII_PI3_WRDATA_ADDR -}; - -const unsigned int sdram_dfii_pix_rddata_addr[4] = { - CSR_SDRAM_DFII_PI0_RDDATA_ADDR, - CSR_SDRAM_DFII_PI1_RDDATA_ADDR, - CSR_SDRAM_DFII_PI2_RDDATA_ADDR, - CSR_SDRAM_DFII_PI3_RDDATA_ADDR -}; - -#define DDR3_MR1 6 - -static void init_sequence(void) -{ - /* Release reset */ - sdram_dfii_pi0_address_write(0x0); - sdram_dfii_pi0_baddress_write(0); - sdram_dfii_control_write(DFII_CONTROL_ODT|DFII_CONTROL_RESET_N); - cdelay(50000); - - /* Bring CKE high */ - sdram_dfii_pi0_address_write(0x0); - sdram_dfii_pi0_baddress_write(0); - sdram_dfii_control_write(DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N); - cdelay(10000); - - /* Load Mode Register 2 */ - sdram_dfii_pi0_address_write(0x408); - sdram_dfii_pi0_baddress_write(2); - command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS); - - /* Load Mode Register 3 */ - sdram_dfii_pi0_address_write(0x0); - sdram_dfii_pi0_baddress_write(3); - command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS); - - /* Load Mode Register 1 */ - sdram_dfii_pi0_address_write(0x6); - sdram_dfii_pi0_baddress_write(1); - command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS); - - /* Load Mode Register 0, CL=7, BL=8 */ - sdram_dfii_pi0_address_write(0x930); - sdram_dfii_pi0_baddress_write(0); - command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS); - cdelay(200); - - /* ZQ Calibration */ - sdram_dfii_pi0_address_write(0x400); - sdram_dfii_pi0_baddress_write(0); - command_p0(DFII_COMMAND_WE|DFII_COMMAND_CS); - cdelay(200); - -} -#endif diff --git a/configs/misoc/include/generated-sample/variables.mak b/configs/misoc/include/generated-sample/variables.mak deleted file mode 100644 index 2bd0474215a..00000000000 --- a/configs/misoc/include/generated-sample/variables.mak +++ /dev/null @@ -1,11 +0,0 @@ -TRIPLE=lm32-elf -CPU=lm32 -CPUFLAGS=-mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled -CPUENDIANNESS=big -CLANG=0 -SOC_DIRECTORY=/usr/local/lib/python3.5/dist-packages/litex-0.1-py3.5.egg/litex/soc -BUILDINC_DIRECTORY=/home/lenovo/fpga/arty-soc/build/software/include -LIBBASE_DIRECTORY=/usr/local/lib/python3.5/dist-packages/litex-0.1-py3.5.egg/litex/soc/software/libbase -LIBCOMPILER_RT_DIRECTORY=/usr/local/lib/python3.5/dist-packages/litex-0.1-py3.5.egg/litex/soc/software/libcompiler_rt -LIBNET_DIRECTORY=/usr/local/lib/python3.5/dist-packages/litex-0.1-py3.5.egg/litex/soc/software/libnet -BIOS_DIRECTORY=/usr/local/lib/python3.5/dist-packages/litex-0.1-py3.5.egg/litex/soc/software/bios diff --git a/configs/misoc/nsh/defconfig b/configs/misoc/nsh/defconfig index 597d38cec9e..ba6ecd27ddf 100644 --- a/configs/misoc/nsh/defconfig +++ b/configs/misoc/nsh/defconfig @@ -2,12 +2,39 @@ # CONFIG_STANDARD_SERIAL is not set CONFIG_ARCH="misoc" CONFIG_ARCH_BOARD="misoc" -CONFIG_ARCH_BOARD_MISOC=y -CONFIG_ARCH_CHIP_LM32=y +CONFIG_ARCH_BOARD_MISOC_VERILATOR=y +CONFIG_ARCH_CHIP_MINERVA=y CONFIG_ARCH_MISOC=y CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_STDARG_H=y CONFIG_BOARD_LOOPSPERMSEC=800 +CONFIG_BOOT_RUNFROMEXTSRAM=y +CONFIG_BUILTIN=y +CONFIG_DEBUG_ASSERTIONS=y +CONFIG_DEBUG_BINFMT=y +CONFIG_DEBUG_BINFMT_ERROR=y +CONFIG_DEBUG_BINFMT_WARN=y +CONFIG_DEBUG_ERROR=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_FS_ERROR=y +CONFIG_DEBUG_FS_INFO=y +CONFIG_DEBUG_FS_WARN=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_LIB=y +CONFIG_DEBUG_LIB_ERROR=y +CONFIG_DEBUG_LIB_WARN=y +CONFIG_DEBUG_MM=y +CONFIG_DEBUG_MM_ERROR=y +CONFIG_DEBUG_MM_WARN=y +CONFIG_DEBUG_SCHED=y +CONFIG_DEBUG_SCHED_ERROR=y +CONFIG_DEBUG_SCHED_WARN=y CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TIMER=y +CONFIG_DEBUG_TIMER_ERROR=y +CONFIG_DEBUG_TIMER_WARN=y +CONFIG_DEBUG_WARN=y CONFIG_DISABLE_ENVIRON=y CONFIG_DISABLE_MOUNTPOINT=y CONFIG_DISABLE_MQUEUE=y @@ -16,17 +43,21 @@ CONFIG_DISABLE_POSIX_TIMERS=y CONFIG_DISABLE_PSEUDOFS_OPERATIONS=y CONFIG_DISABLE_PTHREAD=y CONFIG_EXAMPLES_HELLO=y +CONFIG_EXPERIMENTAL=y +CONFIG_IDLETHREAD_STACKSIZE=4096 CONFIG_MAX_TASKS=4 CONFIG_MAX_WDOGPARMS=2 CONFIG_MISOC_UART1=y CONFIG_NFILE_DESCRIPTORS=4 CONFIG_NFILE_STREAMS=4 +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_READLINE=y CONFIG_NUNGET_CHARS=0 CONFIG_PREALLOC_TIMERS=0 CONFIG_PREALLOC_WDOGS=4 -CONFIG_PTHREAD_STACK_DEFAULT=1024 -CONFIG_PTHREAD_STACK_MIN=512 -CONFIG_RAM_SIZE=524288 +CONFIG_PTHREAD_STACK_DEFAULT=4096 +CONFIG_PTHREAD_STACK_MIN=2048 +CONFIG_RAM_SIZE=33554432 CONFIG_RAM_START=0x40000000 CONFIG_RAW_BINARY=y CONFIG_SDCLONE_DISABLE=y @@ -34,10 +65,11 @@ CONFIG_START_DAY=16 CONFIG_START_MONTH=6 CONFIG_START_YEAR=2011 CONFIG_STDIO_DISABLE_BUFFERING=y +CONFIG_SYSTEM_CLE=y CONFIG_SYSTEM_NSH=y CONFIG_TASK_NAME_SIZE=0 CONFIG_TESTING_OSTEST=y CONFIG_UART1_SERIAL_CONSOLE=y -CONFIG_USERMAIN_STACKSIZE=1024 +CONFIG_USERMAIN_STACKSIZE=4096 CONFIG_USER_ENTRYPOINT="nsh_main" CONFIG_WDOG_INTRESERVE=0 diff --git a/configs/misoc/scripts/Make.defs b/configs/misoc/scripts/Make.defs index f2a216a7f58..6cdb2ec02ce 100644 --- a/configs/misoc/scripts/Make.defs +++ b/configs/misoc/scripts/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # configs/misoc/scripts/Make.defs # -# Copyright (C) 2016m 2017 Gregory Nutt. All rights reserved. +# Copyright (C) 2016, 2017 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # Ramtin Amin # @@ -36,9 +36,15 @@ include ${TOPDIR}/.config include ${TOPDIR}/tools/Config.mk -include ${TOPDIR}/arch/misoc/src/lm32/Toolchain.defs -LDSCRIPT = ld.script +ifeq ($(CONFIG_ARCH_CHIP_LM32),y) + include ${TOPDIR}/arch/misoc/src/lm32/Toolchain.defs + LDSCRIPT=lm32.ld +endif +ifeq ($(CONFIG_ARCH_CHIP_MINERVA),y) + include ${TOPDIR}/arch/misoc/src/minerva/Toolchain.defs + LDSCRIPT=minerva.ld +endif ifeq ($(WINTOOL),y) # Windows-native toolchains @@ -95,8 +101,8 @@ OBJEXT = .o LIBEXT = .a EXEEXT = - HOSTCC = gcc HOSTINCLUDES = -I. HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -g -pipe HOSTLDFLAGS = + diff --git a/configs/misoc/scripts/ld.script b/configs/misoc/scripts/lm32.ld similarity index 95% rename from configs/misoc/scripts/ld.script rename to configs/misoc/scripts/lm32.ld index f7514790676..32b7f44e2c5 100644 --- a/configs/misoc/scripts/ld.script +++ b/configs/misoc/scripts/lm32.ld @@ -36,12 +36,11 @@ OUTPUT_FORMAT("elf32-lm32") ENTRY(_stext) -/*INCLUDE configs/misoc/include/generated/regions.ld*/ MEMORY { rom : ORIGIN = 0x00000000, LENGTH = 0x00008000 - sram : ORIGIN = 0x10000000, LENGTH = 0x00004000 - main_ram : ORIGIN = 0x40000000, LENGTH = 0x00080000 + sram : ORIGIN = 0x10000000, LENGTH = 0x00001000 + main_ram : ORIGIN = 0x40000000, LENGTH = 0x02000000 } SECTIONS @@ -95,3 +94,4 @@ SECTIONS } PROVIDE(_fstack = ORIGIN(main_ram) + LENGTH(main_ram) - 4); + diff --git a/configs/misoc/scripts/minerva.ld b/configs/misoc/scripts/minerva.ld new file mode 100644 index 00000000000..0c9089b7f33 --- /dev/null +++ b/configs/misoc/scripts/minerva.ld @@ -0,0 +1,102 @@ +/**************************************************************************** + * configs/misoc/scripts/ld.script + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * 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. + * + ****************************************************************************/ + +OUTPUT_FORMAT("elf32-littleriscv") + +ENTRY(_stext) + +MEMORY +{ + rom : ORIGIN = 0x00000000, LENGTH = 0x00008000 + sram : ORIGIN = 0x10000000, LENGTH = 0x00001000 + main_ram : ORIGIN = 0x40000000, LENGTH = 0x02000000 +} + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > main_ram + + _eronly = ABSOLUTE(.); /* See below */ + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > main_ram + + .bss : { /* BSS */ + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(.sbss .sbss.*) + *(.gnu.linkonce.sb.*) + *(COMMON) + _ebss = ABSOLUTE(.); + } > main_ram + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} + +PROVIDE(_fstack = ORIGIN(main_ram) + LENGTH(main_ram) - 4); +