diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index 0e601a1b27..c7a4115be8 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -26,6 +26,12 @@ config ARCH_CHIP_K210 ---help--- Kendryte K210 processor (RISC-V 64bit core with GC extensions) +config ARCH_CHIP_LITEX + bool "Enjoy Digital LITEX VEXRISCV" + select ARCH_RV32IM + ---help--- + Enjoy Digital LITEX VEXRISCV softcore processor (RV32IMA). + config ARCH_CHIP_NR5 bool "NEXT NanoRisc5" select ARCH_RV32IM @@ -62,6 +68,7 @@ config ARCH_CHIP string default "fe310" if ARCH_CHIP_FE310 default "k210" if ARCH_CHIP_K210 + default "litex" if ARCH_CHIP_LITEX default "nr5m100" if ARCH_CHIP_NR5 default "gap8" if ARCH_CHIP_GAP8 @@ -87,6 +94,9 @@ endif if ARCH_CHIP_K210 source arch/risc-v/src/k210/Kconfig endif +if ARCH_CHIP_LITEX +source arch/risc-v/src/litex/Kconfig +endif if ARCH_CHIP_NR5 source arch/risc-v/src/nr5m100/Kconfig endif diff --git a/arch/risc-v/include/litex/chip.h b/arch/risc-v/include/litex/chip.h new file mode 100644 index 0000000000..5072b88b35 --- /dev/null +++ b/arch/risc-v/include/litex/chip.h @@ -0,0 +1,24 @@ +/**************************************************************************** + * arch/risc-v/include/litex/chip.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_INCLUDE_LITEX_CHIP_H +#define __ARCH_RISCV_INCLUDE_LITEX_CHIP_H + +#endif /* __ARCH_RISCV_INCLUDE_LITEX_CHIP_H */ diff --git a/arch/risc-v/include/litex/irq.h b/arch/risc-v/include/litex/irq.h new file mode 100644 index 0000000000..c2f5e0c1e3 --- /dev/null +++ b/arch/risc-v/include/litex/irq.h @@ -0,0 +1,113 @@ +/**************************************************************************** + * arch/risc-v/include/litex/irq.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_INCLUDE_LITEX_IRQ_H +#define __ARCH_RISCV_INCLUDE_LITEX_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* In mstatus register */ + +#define MSTATUS_MIE (0x1 << 3) /* Machine Interrupt Enable */ +#define MSTATUS_MPIE (0x1 << 7) /* Machine Previous Interrupt Enable */ +#define MSTATUS_MPPM (0x3 << 11) /* Machine Previous Privilege (m-mode) */ + +/* In mie (machine interrupt enable) register */ + +#define MIE_MSIE (0x1 << 3) /* Machine Software Interrupt Enable */ +#define MIE_MTIE (0x1 << 7) /* Machine Timer Interrupt Enable */ +#define MIE_MEIE (0x1 << 11) /* Machine External Interrupt Enable */ +#define MIP_MTIP (1 << 7) + +/* Map RISC-V exception code to NuttX IRQ */ + +/* IRQ 0-15 : (exception:interrupt=0) */ + +#define LITEX_IRQ_IAMISALIGNED (0) /* Instruction Address Misaligned */ +#define LITEX_IRQ_IAFAULT (1) /* Instruction Address Fault */ +#define LITEX_IRQ_IINSTRUCTION (2) /* Illegal Instruction */ +#define LITEX_IRQ_BPOINT (3) /* Break Point */ +#define LITEX_IRQ_LAMISALIGNED (4) /* Load Address Misaligned */ +#define LITEX_IRQ_LAFAULT (5) /* Load Access Fault */ +#define LITEX_IRQ_SAMISALIGNED (6) /* Store/AMO Address Misaligned */ +#define LITEX_IRQ_SAFAULT (7) /* Store/AMO Access Fault */ +#define LITEX_IRQ_ECALLU (8) /* Environment Call from U-mode */ + /* 9-10: Reserved */ + +#define LITEX_IRQ_ECALLM (11) /* Environment Call from M-mode */ + /* 12-15: Reserved */ + +/* IRQ 16- : (async event:interrupt=1) */ + +#define LITEX_IRQ_ASYNC (16) +#define LITEX_IRQ_MSOFT (LITEX_IRQ_ASYNC + 3) /* Machine Software Int */ +#define LITEX_IRQ_MTIMER (LITEX_IRQ_ASYNC + 7) /* Machine Timer Int */ +#define LITEX_IRQ_MEXT (LITEX_IRQ_ASYNC + 11) /* Machine External Int */ + +/* Machine Global External Interrupt */ + +#define LITEX_IRQ_UART0 (LITEX_IRQ_MEXT + 1) +#define LITEX_IRQ_TIMER0 (LITEX_IRQ_MEXT + 2) + +/* Total number of IRQs */ + +#define NR_IRQS (LITEX_IRQ_TIMER0 + 1) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +EXTERN irqstate_t up_irq_save(void); +EXTERN void up_irq_restore(irqstate_t); +EXTERN irqstate_t up_irq_enable(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_INCLUDE_LITEX_IRQ_H */ diff --git a/arch/risc-v/src/litex/Kconfig b/arch/risc-v/src/litex/Kconfig new file mode 100644 index 0000000000..d6b7e3bd9f --- /dev/null +++ b/arch/risc-v/src/litex/Kconfig @@ -0,0 +1,28 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "LITEX Configuration Options" + +menu "LITEX Peripheral Support" + +# These "hidden" settings determine is a peripheral option is available for the +# selection MCU + +config LITEX_HAVE_UART0 + bool + default y + select UART0_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS + +# These are the peripheral selections proper + +config LITEX_UART0 + bool "UART0" + default y + select ARCH_HAVE_UART0 + select ARCH_HAVE_SERIAL_TERMIOS + select LITEX_UART + +endmenu diff --git a/arch/risc-v/src/litex/Make.defs b/arch/risc-v/src/litex/Make.defs new file mode 100644 index 0000000000..7a49f3f8f3 --- /dev/null +++ b/arch/risc-v/src/litex/Make.defs @@ -0,0 +1,49 @@ +############################################################################ +# arch/risc-v/src/litex/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +# Specify our HEAD assembly file. This will be linked as +# the first object file, so it will appear at address 0 +HEAD_ASRC = litex_vectors.S + +# Specify our general Assembly files +CHIP_ASRCS = litex_head.S up_syscall.S + +# Specify C code within the common directory to be included +CMN_CSRCS += up_initialize.c up_swint.c +CMN_CSRCS += up_allocateheap.c up_createstack.c up_exit.c +CMN_CSRCS += up_assert.c up_blocktask.c up_copystate.c up_initialstate.c +CMN_CSRCS += up_interruptcontext.c up_modifyreg32.c up_puts.c up_mdelay.c +CMN_CSRCS += up_releasepending.c up_reprioritizertr.c +CMN_CSRCS += up_releasestack.c up_stackframe.c up_schedulesigaction.c +CMN_CSRCS += up_sigdeliver.c up_udelay.c up_unblocktask.c up_usestack.c + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +ifeq ($(CONFIG_ARCH_HAVE_VFORK),y) +CMN_CSRCS += up_vfork.c +endif + +# Specify our C code within this directory to be included +CHIP_CSRCS = litex_allocateheap.c litex_clockconfig.c +CHIP_CSRCS += litex_idle.c litex_irq.c litex_irq_dispatch.c +CHIP_CSRCS += litex_lowputc.c litex_serial.c +CHIP_CSRCS += litex_start.c litex_timerisr.c diff --git a/arch/risc-v/src/litex/chip.h b/arch/risc-v/src/litex/chip.h new file mode 100644 index 0000000000..228cda581a --- /dev/null +++ b/arch/risc-v/src/litex/chip.h @@ -0,0 +1,32 @@ +/**************************************************************************** + * arch/risc-v/src/litex/chip.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_LITEX_CHIP_H +#define __ARCH_RISCV_SRC_LITEX_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "litex_memorymap.h" + +#endif /* __ARCH_RISCV_SRC_LITEX_CHIP_H */ diff --git a/arch/risc-v/src/litex/hardware/litex_clint.h b/arch/risc-v/src/litex/hardware/litex_clint.h new file mode 100644 index 0000000000..73ff1a670f --- /dev/null +++ b/arch/risc-v/src/litex/hardware/litex_clint.h @@ -0,0 +1,32 @@ +/**************************************************************************** + * arch/risc-v/src/litex/hardware/litex_clint.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_CLINT_H +#define __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_CLINT_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define LITEX_CLINT_LATCH (LITEX_CPUTIMER_BASE) +#define LITEX_CLINT_MTIME (LITEX_CPUTIMER_BASE + 0x04) +#define LITEX_CLINT_MTIMECMP (LITEX_CPUTIMER_BASE + 0x24) + +#endif /* __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_CLINT_H */ diff --git a/arch/risc-v/src/litex/hardware/litex_memorymap.h b/arch/risc-v/src/litex/hardware/litex_memorymap.h new file mode 100644 index 0000000000..f5b208cc8a --- /dev/null +++ b/arch/risc-v/src/litex/hardware/litex_memorymap.h @@ -0,0 +1,38 @@ +/**************************************************************************** + * arch/risc-v/src/litex/hardware/litex_memorymap.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_MEMORYMAP_H +#define __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_MEMORYMAP_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Base Address ****************************************************/ + +/* litex vexRiscv does not follow RISC-V privileged specification and + * uses two additional CSRs: mask and pending. + */ + +#define LITEX_CPUTIMER_BASE 0xf0000800 /* riscv clint timer */ +#define LITEX_TIMER0_BASE 0xf0001800 +#define LITEX_UART0_BASE 0xf0001000 /* 0xf0001000 - : UART0 */ + +#endif /* __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_MEMORYMAP_H */ diff --git a/arch/risc-v/src/litex/hardware/litex_plic.h b/arch/risc-v/src/litex/hardware/litex_plic.h new file mode 100644 index 0000000000..bd9e100209 --- /dev/null +++ b/arch/risc-v/src/litex/hardware/litex_plic.h @@ -0,0 +1,34 @@ +/**************************************************************************** + * arch/risc-v/src/litex/hardware/litex_plic.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_PLIC_H +#define __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_PLIC_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* litex vexRiscv does not follow RISC-V privileged specification and + * uses two additional CSRs: mask and pending. + */ +#define LITEX_MMASK_CSR 0xBC0 +#define LITEX_MPENDING_CSR 0xFC0 + +#endif /* __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_PLIC_H */ diff --git a/arch/risc-v/src/litex/hardware/litex_uart.h b/arch/risc-v/src/litex/hardware/litex_uart.h new file mode 100644 index 0000000000..f6affba58b --- /dev/null +++ b/arch/risc-v/src/litex/hardware/litex_uart.h @@ -0,0 +1,48 @@ +/**************************************************************************** + * arch/risc-v/src/litex/hardware/litex_uart.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef ARCH_RISCV_SRC_LITEX_CHIP_LITEX_UART_H +#define ARCH_RISCV_SRC_LITEX_CHIP_LITEX_UART_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define UART_RXTX_OFFSET 0x00 +#define UART_TXFULL_OFFSET 0x04 +#define UART_RXEMPTY_OFFSET 0x08 +#define UART_EV_STATUS_OFFSET 0x0c +#define UART_EV_PENDING_OFFSET 0x10 +#define UART_EV_ENABLE_OFFSET 0x14 + +#ifdef CONFIG_LITEX_UART0 +# define LITEX_UART0_RXTX (LITEX_UART0_BASE + UART_RXTX_OFFSET) +# define LITEX_UART0_TXFULL (LITEX_UART0_BASE + UART_TXFULL_OFFSET) +# define LITEX_UART0_RXEMPTY (LITEX_UART0_BASE + UART_RXEMPTY_OFFSET) +# define LITEX_UART0_EV_STATUS (LITEX_UART0_BASE + UART_EV_STATUS_OFFSET) +# define LITEX_UART0_EV_PENDING (LITEX_UART0_BASE + UART_EV_PENDING_OFFSET) +# define LITEX_UART0_EV_ENABLE (LITEX_UART0_BASE + UART_EV_ENABLE_OFFSET) +# define LITEX_UART0_PHY_TUNING_WORD 0xf0002000L +#endif + +#define UART_EV_TX 0x1 +#define UART_EV_RX 0x2 + +#endif /* _ARCH_RISCV_SRC_LITEX_CHIP_LITEX_UART_H */ diff --git a/arch/risc-v/src/litex/litex.h b/arch/risc-v/src/litex/litex.h new file mode 100644 index 0000000000..70c4fa8167 --- /dev/null +++ b/arch/risc-v/src/litex/litex.h @@ -0,0 +1,38 @@ +/**************************************************************************** + * arch/risc-v/src/litex/litex.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_LITEX_LITEX_H +#define __ARCH_RISCV_SRC_LITEX_LITEX_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include +#include "up_internal.h" +#include "chip.h" +#include "litex_lowputc.h" + +#endif /* __ARCH_RISCV_SRC_LITEX_LITEX_H */ diff --git a/arch/risc-v/src/litex/litex_allocateheap.c b/arch/risc-v/src/litex/litex_allocateheap.c new file mode 100644 index 0000000000..2edc5bab0c --- /dev/null +++ b/arch/risc-v/src/litex/litex_allocateheap.c @@ -0,0 +1,41 @@ +/**************************************************************************** + * arch/risc-v/src/litex/litex_allocateheap.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "litex.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_addregion + ****************************************************************************/ + +void up_addregion(void) +{ +} diff --git a/arch/risc-v/src/litex/litex_clockconfig.c b/arch/risc-v/src/litex/litex_clockconfig.c new file mode 100644 index 0000000000..5622ae07da --- /dev/null +++ b/arch/risc-v/src/litex/litex_clockconfig.c @@ -0,0 +1,63 @@ +/**************************************************************************** + * arch/risc-v/src/litex/litex_clockconfig.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "litex_clockconfig.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: litex_get_hfclk + ****************************************************************************/ + +uint32_t litex_get_hfclk(void) +{ + /* fpga fabric default sys frequency */ + + return 100000000UL; +} + +/**************************************************************************** + * Name: litex_clockconfig + ****************************************************************************/ + +void litex_clockconfig(void) +{ + /* pll is set by fpga fabric */ +} diff --git a/arch/risc-v/src/litex/litex_clockconfig.h b/arch/risc-v/src/litex/litex_clockconfig.h new file mode 100644 index 0000000000..4ef11b2b49 --- /dev/null +++ b/arch/risc-v/src/litex/litex_clockconfig.h @@ -0,0 +1,65 @@ +/**************************************************************************** + * arch/risc-v/src/litex/litex_clockconfig.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_LITEX_LITEX_CLOCKCONFIG_H +#define __ARCH_RISCV_SRC_LITEX_LITEX_CLOCKCONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "litex_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +EXTERN uint32_t litex_get_hfclk(void); +EXTERN void litex_clockconfig(void); + +#if defined(__cplusplus) +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_LITEX_LITEX_CLOCKCONFIG_H */ diff --git a/arch/risc-v/src/litex/litex_config.h b/arch/risc-v/src/litex/litex_config.h new file mode 100644 index 0000000000..91b871f083 --- /dev/null +++ b/arch/risc-v/src/litex/litex_config.h @@ -0,0 +1,54 @@ +/**************************************************************************** + * arch/risc-v/src/litex/litex_config.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_LITEX_LITEX_CONFIG_H +#define __ARCH_RISCV_SRC_LITEX_LITEX_CONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_LITEX_UART0) || defined(CONFIG_LITEX_UART1) +# define HAVE_UART_DEVICE 1 +#endif + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_LITEX_UART0) +# undef CONFIG_UART1_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_LITEX_UART1) +# undef CONFIG_UART0_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +#endif /* __ARCH_RISCV_SRC_LITEX_LITEX_CONFIG_H */ diff --git a/arch/risc-v/src/litex/litex_head.S b/arch/risc-v/src/litex/litex_head.S new file mode 100644 index 0000000000..bcfb0f87e8 --- /dev/null +++ b/arch/risc-v/src/litex/litex_head.S @@ -0,0 +1,204 @@ +/**************************************************************************** + * arch/risc-v/src/litex/litex_head.S + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "chip.h" + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .global exception_common + + /* Imported symbols */ + + .extern __trap_vec + + .section .text + .global __start + +__start: + + /* Set stack pointer to the idle thread stack */ + + lui sp, %hi(LITEX_IDLESTACK_TOP) + addi sp, sp, %lo(LITEX_IDLESTACK_TOP) + + /* Disable all interrupts (i.e. timer, external) in mie */ + + csrw mie, zero + + /* Initialize the Machine Trap Vector */ + + lui t0, %hi(__trap_vec) + addi t0, t0, %lo(__trap_vec) + csrw mtvec, t0 + + /* Jump to __litex_start */ + + jal x1, __litex_start + + /* We shouldn't return from __litex_start */ + + .global _init + .global _fini + +_init: +_fini: + + /* These don't have to do anything since we use init_array/fini_array. */ + + ret + +/**************************************************************************** + * Name: exception_common + ****************************************************************************/ + +exception_common: + + addi sp, sp, -XCPTCONTEXT_SIZE + + sw x1, 1*4(sp) /* ra */ + sw x3, 3*4(sp) /* gp */ + sw x4, 4*4(sp) /* tp */ + sw x5, 5*4(sp) /* t0 */ + sw x6, 6*4(sp) /* t1 */ + sw x7, 7*4(sp) /* t2 */ + sw x8, 8*4(sp) /* s0 */ + sw x9, 9*4(sp) /* s1 */ + sw x10, 10*4(sp) /* a0 */ + sw x11, 11*4(sp) /* a1 */ + sw x12, 12*4(sp) /* a2 */ + sw x13, 13*4(sp) /* a3 */ + sw x14, 14*4(sp) /* a4 */ + sw x15, 15*4(sp) /* a5 */ + sw x16, 16*4(sp) /* a6 */ + sw x17, 17*4(sp) /* a7 */ + sw x18, 18*4(sp) /* s2 */ + sw x19, 19*4(sp) /* s3 */ + sw x20, 20*4(sp) /* s4 */ + sw x21, 21*4(sp) /* s5 */ + sw x22, 22*4(sp) /* s6 */ + sw x23, 23*4(sp) /* s7 */ + sw x24, 24*4(sp) /* s8 */ + sw x25, 25*4(sp) /* s9 */ + sw x26, 26*4(sp) /* s10 */ + sw x27, 27*4(sp) /* s11 */ + sw x28, 28*4(sp) /* t3 */ + sw x29, 29*4(sp) /* t4 */ + sw x30, 30*4(sp) /* t5 */ + sw x31, 31*4(sp) /* t6 */ + + csrr s0, mstatus + sw s0, 32*4(sp) /* mstatus */ + + addi s0, sp, XCPTCONTEXT_SIZE + sw s0, 2*4(sp) /* original SP */ + + /* Setup arg0(exception cause), arg1(context) */ + + csrr a0, mcause /* exception cause */ + csrr s0, mepc + sw s0, 0(sp) /* exception PC */ + + mv a1, sp /* context = sp */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + /* Switch to interrupt stack */ + + lui sp, %hi(g_intstackbase) + addi sp, sp, %lo(g_intstackbase) +#endif + + /* Call interrupt handler in C */ + + jal x1, litex_dispatch_irq + + /* If context switch is needed, return a new sp */ + + mv sp, a0 + lw s0, 0(sp) /* restore mepc */ + csrw mepc, s0 + + lw s0, 32*4(sp) /* restore mstatus */ + csrw mstatus, s0 + + lw x3, 3*4(sp) /* gp */ + lw x4, 4*4(sp) /* tp */ + lw x5, 5*4(sp) /* t0 */ + lw x6, 6*4(sp) /* t1 */ + lw x7, 7*4(sp) /* t2 */ + lw x8, 8*4(sp) /* s0 */ + lw x9, 9*4(sp) /* s1 */ + lw x10, 10*4(sp) /* a0 */ + lw x11, 11*4(sp) /* a1 */ + lw x12, 12*4(sp) /* a2 */ + lw x13, 13*4(sp) /* a3 */ + lw x14, 14*4(sp) /* a4 */ + lw x15, 15*4(sp) /* a5 */ + lw x16, 16*4(sp) /* a6 */ + lw x17, 17*4(sp) /* a7 */ + lw x18, 18*4(sp) /* s2 */ + lw x19, 19*4(sp) /* s3 */ + lw x20, 20*4(sp) /* s4 */ + lw x21, 21*4(sp) /* s5 */ + lw x22, 22*4(sp) /* s6 */ + lw x23, 23*4(sp) /* s7 */ + lw x24, 24*4(sp) /* s8 */ + lw x25, 25*4(sp) /* s9 */ + lw x26, 26*4(sp) /* s10 */ + lw x27, 27*4(sp) /* s11 */ + lw x28, 28*4(sp) /* t3 */ + lw x29, 29*4(sp) /* t4 */ + lw x30, 30*4(sp) /* t5 */ + lw x31, 31*4(sp) /* t6 */ + + lw x1, 1*4(sp) /* ra */ + + lw sp, 2*4(sp) /* restore original sp */ + + /* Return from Machine Interrupt */ + + mret + +/************************************************************************************ + * Name: g_intstackalloc and g_intstackbase + ************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + .bss + .align 4 + .global g_intstackalloc + .global g_intstackbase + .type g_intstackalloc, object + .type g_intstackbase, object +g_intstackalloc: + .skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3)) +g_intstackbase: + .skip 4 + .size g_intstackbase, 4 + .size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3) +#endif diff --git a/arch/risc-v/src/litex/litex_idle.c b/arch/risc-v/src/litex/litex_idle.c new file mode 100644 index 0000000000..b94230a7d1 --- /dev/null +++ b/arch/risc-v/src/litex/litex_idle.c @@ -0,0 +1,67 @@ +/**************************************************************************** + * arch/risc-v/src/litex/litex_idle.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "up_internal.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. + */ + + nxsched_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 + */ + + asm("WFI"); + +#endif +} diff --git a/arch/risc-v/src/litex/litex_irq.c b/arch/risc-v/src/litex/litex_irq.c new file mode 100644 index 0000000000..0df390b2ec --- /dev/null +++ b/arch/risc-v/src/litex/litex_irq.c @@ -0,0 +1,263 @@ +/**************************************************************************** + * arch/risc-v/src/litex/litex_irq.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "litex.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* Disable Machine interrupts */ + + up_irq_save(); + + /* Disable all global interrupts */ + + asm volatile ("csrw %0, %1" :: "i"(LITEX_MMASK_CSR), "r"(0)); + + /* Colorize the interrupt stack for debug purposes */ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), + intstack_size); +#endif + + /* litex vexriscv dont have priority and threshold control */ + + /* currents_regs is non-NULL only while processing an interrupt */ + + g_current_regs = NULL; + + /* Attach the ecall interrupt handler */ + + irq_attach(LITEX_IRQ_ECALLM, up_swint, NULL); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + + /* And finally, enable interrupts */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + int extirq; + int mask; + uint32_t oldstat; + + if (irq == LITEX_IRQ_MSOFT) + { + /* Read mstatus & clear machine software interrupt enable in mie */ + + asm volatile ("csrrc %0, mie, %1": "=r" (oldstat) : "r"(MIE_MSIE)); + } + else if (irq == LITEX_IRQ_MTIMER) + { + /* Read mstatus & clear machine timer interrupt enable in mie */ + + asm volatile ("csrrc %0, mie, %1": "=r" (oldstat) : "r"(MIE_MTIE)); + } + else if (irq > LITEX_IRQ_MEXT) + { + extirq = irq - LITEX_IRQ_MEXT; + extirq--; + + /* Clear enable bit for the irq */ + + if (0 <= extirq && extirq <= 31) + { + asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(LITEX_MMASK_CSR)); + mask &= ~(1 << extirq); + asm volatile ("csrw %0, %1" :: "i"(LITEX_MMASK_CSR), "r"(mask)); + } + else + { + ASSERT(false); + } + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + int extirq; + int mask; + uint32_t oldstat; + + if (irq == LITEX_IRQ_MSOFT) + { + /* Read mstatus & set machine software interrupt enable in mie */ + + asm volatile ("csrrs %0, mie, %1": "=r" (oldstat) : "r"(MIE_MSIE)); + } + else if (irq == LITEX_IRQ_MTIMER) + { + /* Read mstatus & set machine timer interrupt enable in mie */ + + asm volatile ("csrrs %0, mie, %1": "=r" (oldstat) : "r"(MIE_MTIE)); + } + else if (irq > LITEX_IRQ_MEXT) + { + extirq = irq - LITEX_IRQ_MEXT; + extirq--; + + /* Set enable bit for the irq */ + + if (0 <= extirq && extirq <= 31) + { + asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(LITEX_MMASK_CSR)); + mask |= (1 << extirq); + asm volatile ("csrw %0, %1" :: "i"(LITEX_MMASK_CSR), "r"(mask)); + } + else + { + ASSERT(false); + } + } +} + +/**************************************************************************** + * Name: up_get_newintctx + * + * Description: + * Return initial mstatus when a task is created. + * + ****************************************************************************/ + +uint32_t up_get_newintctx(void) +{ + /* Set machine previous privilege mode to machine mode. + * Also set machine previous interrupt enable + */ + + return (MSTATUS_MPPM | MSTATUS_MPIE); +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ +} + +/**************************************************************************** + * Name: up_irq_save + * + * Description: + * Return the current interrupt state and disable interrupts + * + ****************************************************************************/ + +irqstate_t up_irq_save(void) +{ + uint32_t oldstat; + + /* Read mstatus & clear machine interrupt enable (MIE) in mstatus */ + + asm volatile ("csrrc %0, mstatus, %1": "=r" (oldstat) : "r"(MSTATUS_MIE)); + return oldstat; +} + +/**************************************************************************** + * Name: up_irq_restore + * + * Description: + * Restore previous IRQ mask state + * + ****************************************************************************/ + +void up_irq_restore(irqstate_t flags) +{ + /* Write flags to mstatus */ + + asm volatile("csrw mstatus, %0" : /* no output */ : "r" (flags)); +} + +/**************************************************************************** + * Name: up_irq_enable + * + * Description: + * Return the current interrupt state and enable interrupts + * + ****************************************************************************/ + +irqstate_t up_irq_enable(void) +{ + uint32_t oldstat; + +#if 1 + /* Enable MEIE (machine external interrupt enable) */ + + /* TODO: should move to up_enable_irq() */ + + asm volatile ("csrrs %0, mie, %1": "=r" (oldstat) : "r"(MIE_MEIE)); +#endif + + /* Read mstatus & set machine interrupt enable (MIE) in mstatus */ + + asm volatile ("csrrs %0, mstatus, %1": "=r" (oldstat) : "r"(MSTATUS_MIE)); + return oldstat; +} diff --git a/arch/risc-v/src/litex/litex_irq_dispatch.c b/arch/risc-v/src/litex/litex_irq_dispatch.c new file mode 100644 index 0000000000..9381076d87 --- /dev/null +++ b/arch/risc-v/src/litex/litex_irq_dispatch.c @@ -0,0 +1,126 @@ +/**************************************************************************** + * arch/risc-v/src/litex/litex_irq_dispatch.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "litex.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +volatile uint32_t * g_current_regs; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * litex_dispatch_irq + ****************************************************************************/ + +void *litex_dispatch_irq(uint32_t vector, uint32_t *regs) +{ + uint32_t irq = (vector >> 27) | (vector & 0xf); + uint32_t *mepc = regs; + int i; + + /* Firstly, check if the irq is machine external interrupt */ + + if (LITEX_IRQ_MEXT == irq) + { + /* litex vexriscv dont follow riscv plic standard */ + + unsigned int pending; + unsigned int mask; + asm volatile ("csrr %0, %1" : "=r"(pending) : "i"(LITEX_MPENDING_CSR)); + asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(LITEX_MMASK_CSR)); + + uint32_t val = (pending & mask); + for (i = 0; i < 32; i++) + { + if (val & (1 << i)) + { + val = i; + val++; + break; + } + } + + /* Add the value to nuttx irq which is offset to the mext */ + + irq += val; + } + + /* NOTE: In case of ecall, we need to adjust mepc in the context */ + + if (LITEX_IRQ_ECALLM == irq) + { + *mepc += 4; + } + + /* Acknowledge the interrupt */ + + up_ack_irq(irq); + +#ifdef CONFIG_SUPPRESS_INTERRUPTS + PANIC(); +#else + /* 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; + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + +#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; + g_current_regs = NULL; + + return regs; +} diff --git a/arch/risc-v/src/litex/litex_lowputc.c b/arch/risc-v/src/litex/litex_lowputc.c new file mode 100644 index 0000000000..20054eef34 --- /dev/null +++ b/arch/risc-v/src/litex/litex_lowputc.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * arch/risc-v/src/litex/litex_lowputc.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "litex_config.h" +#include "hardware/litex_memorymap.h" +#include "hardware/litex_uart.h" +#include "litex_clockconfig.h" +#include "litex.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select UART parameters for the selected console */ + +#ifdef HAVE_SERIAL_CONSOLE +# if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define LITEX_CONSOLE_BASE LITEX_UART0_BASE +# define LITEX_CONSOLE_BAUD CONFIG_UART0_BAUD +# define LITEX_CONSOLE_BITS CONFIG_UART0_BITS +# define LITEX_CONSOLE_PARITY CONFIG_UART0_PARITY +# define LITEX_CONSOLE_2STOP CONFIG_UART0_2STOP +# define LITEX_CONSOLE_TX GPIO_UART0_TX +# define LITEX_CONSOLE_RX GPIO_UART0_RX +# define HAVE_UART +# elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define LITEX_CONSOLE_BASE LITEX_UART1_BASE +# define LITEX_CONSOLE_BAUD CONFIG_UART1_BAUD +# define LITEX_CONSOLE_BITS CONFIG_UART1_BITS +# define LITEX_CONSOLE_PARITY CONFIG_UART1_PARITY +# define LITEX_CONSOLE_2STOP CONFIG_UART1_2STOP +# define LITEX_CONSOLE_TX GPIO_UART1_TX +# define LITEX_CONSOLE_RX GPIO_UART1_RX +# define HAVE_UART +# endif +#endif /* HAVE_CONSOLE */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Wait until the TX data register is empty */ + + while (getreg8(LITEX_CONSOLE_BASE + UART_TXFULL_OFFSET)) + ; + + /* Then send the character */ + + putreg8(ch, LITEX_CONSOLE_BASE + UART_RXTX_OFFSET); + putreg8(UART_EV_TX, LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET); + +#endif /* HAVE_CONSOLE */ +} + +/**************************************************************************** + * Name: litex_lowsetup + * + * Description: + * This performs basic initialization of the UART used for the serial + * console. Its purpose is to get the console output available as soon + * as possible. + * + ****************************************************************************/ + +void litex_lowsetup(void) +{ +#if defined(HAVE_UART) + + /* Enable and configure the selected console device */ + +#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + + /* defualt baudrate set by fpga fabric is 1e6 */ + + /* Enable TX */ + + putreg8(getreg8(LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET), \ + LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET); + putreg8(UART_EV_TX, LITEX_CONSOLE_BASE + UART_EV_ENABLE_OFFSET); + +#endif /* HAVE_SERIAL_CONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */ +#endif /* HAVE_UART */ +} diff --git a/arch/risc-v/src/litex/litex_lowputc.h b/arch/risc-v/src/litex/litex_lowputc.h new file mode 100644 index 0000000000..105c8148de --- /dev/null +++ b/arch/risc-v/src/litex/litex_lowputc.h @@ -0,0 +1,59 @@ +/**************************************************************************** + * arch/risc-v/src/litex/litex_lowputc.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_LITEX_LITEX_LOWPUTC_H +#define __ARCH_RISCV_SRC_LITEX_LITEX_LOWPUTC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: litex_lowsetup + ****************************************************************************/ + +EXTERN void litex_lowsetup(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_LITEX_LITEX_LOWPUTC_H */ diff --git a/arch/risc-v/src/litex/litex_memorymap.h b/arch/risc-v/src/litex/litex_memorymap.h new file mode 100644 index 0000000000..506c32780e --- /dev/null +++ b/arch/risc-v/src/litex/litex_memorymap.h @@ -0,0 +1,48 @@ +/**************************************************************************** + * arch/risc-v/src/litex/litex_memorymap.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef _ARCH_RISCV_SRC_LITEX_LITEX_MEMORYMAP_H +#define _ARCH_RISCV_SRC_LITEX_LITEX_MEMORYMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "hardware/litex_memorymap.h" +#include "hardware/litex_uart.h" +#include "hardware/litex_clint.h" +#include "hardware/litex_plic.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Idle thread stack starts from _ebss */ + +#ifndef __ASSEMBLY__ +#define LITEX_IDLESTACK_BASE (uint32_t)&_ebss +#else +#define LITEX_IDLESTACK_BASE _ebss +#endif + +#define LITEX_IDLESTACK_SIZE (CONFIG_IDLETHREAD_STACKSIZE & ~3) +#define LITEX_IDLESTACK_TOP (LITEX_IDLESTACK_BASE + LITEX_IDLESTACK_SIZE) + +#endif /* _ARCH_RISCV_SRC_LITEX_LITEX_MEMORYMAP_H */ diff --git a/arch/risc-v/src/litex/litex_serial.c b/arch/risc-v/src/litex/litex_serial.c new file mode 100644 index 0000000000..02b5235c46 --- /dev/null +++ b/arch/risc-v/src/litex/litex_serial.c @@ -0,0 +1,764 @@ +/**************************************************************************** + * arch/risc-v/src/litex/litex_serial.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "litex_config.h" +#include "chip.h" +#include "litex.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select UART parameters for the selected console */ + +#ifdef HAVE_SERIAL_CONSOLE +# if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define LITEX_CONSOLE_BASE LITEX_UART0_BASE +# define LITEX_CONSOLE_BAUD CONFIG_UART0_BAUD +# define LITEX_CONSOLE_BITS CONFIG_UART0_BITS +# define LITEX_CONSOLE_PARITY CONFIG_UART0_PARITY +# define LITEX_CONSOLE_2STOP CONFIG_UART0_2STOP +# define LITEX_CONSOLE_TX GPIO_UART0_TX +# define LITEX_CONSOLE_RX GPIO_UART0_RX +# define HAVE_UART +# elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define LITEX_CONSOLE_BASE LITEX_UART1_BASE +# define LITEX_CONSOLE_BAUD CONFIG_UART1_BAUD +# define LITEX_CONSOLE_BITS CONFIG_UART1_BITS +# define LITEX_CONSOLE_PARITY CONFIG_UART1_PARITY +# define LITEX_CONSOLE_2STOP CONFIG_UART1_2STOP +# define LITEX_CONSOLE_TX GPIO_UART1_TX +# define LITEX_CONSOLE_RX GPIO_UART1_RX +# define HAVE_UART +# endif +#endif /* HAVE_CONSOLE */ + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +/* Which UART with be tty0/console and which tty1? The console will always + * be ttyS0. If there is no console then will use the lowest numbered UART. + */ + +#ifdef HAVE_SERIAL_CONSOLE +# if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# undef TTYS1_DEV /* No ttyS1 */ +# define SERIAL_CONSOLE 1 +# else +# error "I'm confused... Do we have a serial console or not?" +# endif +#else +# undef CONSOLE_DEV /* No console */ +# undef CONFIG_UART0_SERIAL_CONSOLE +# if defined(CONFIG_LITEX_UART0) +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# undef TTYS1_DEV /* No ttyS1 */ +# define SERIAL_CONSOLE 1 +# else +# undef TTYS0_DEV +# undef TTYS1_DEV +# endif +#endif + +/* Common initialization logic will not not know that the all of the UARTs + * have been disabled. So, as a result, we may still have to provide + * stub implementations of up_earlyserialinit(), up_serialinit(), and + * up_putc(). + */ + +#ifdef HAVE_UART_DEVICE + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uintptr_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t im; /* Interrupt mask state */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers */ + +static uint32_t up_serialin(struct up_dev_s *priv, int offset); +static void up_serialout(struct up_dev_s *priv, int offset, uint32_t value); +static void up_restoreuartint(struct up_dev_s *priv, uint8_t im); +static void up_disableuartint(struct up_dev_s *priv, uint8_t *im); + +/* Serial driver methods */ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context, FAR void *arg); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_LITEX_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif + +#ifdef CONFIG_LITEX_UART0 +static struct up_dev_s g_uart0priv = +{ + .uartbase = LITEX_UART0_BASE, + .baud = CONFIG_UART0_BAUD, + .irq = LITEX_IRQ_UART0, +}; + +static uart_dev_t g_uart0port = +{ +#if SERIAL_CONSOLE == 1 + .isconsole = 1, +#endif + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static void up_restoreuartint(struct up_dev_s *priv, uint8_t im) +{ + irqstate_t flags = enter_critical_section(); + + priv->im = im; + + putreg8(getreg8(LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET), \ + LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET); + up_serialout(priv, UART_EV_ENABLE_OFFSET, im); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static void up_disableuartint(struct up_dev_s *priv, uint8_t *im) +{ + irqstate_t flags = enter_critical_section(); + + /* Return the current interrupt mask value */ + + if (im) + { + *im = priv->im; + } + + /* Disable all interrupts */ + + priv->im = 0; + + putreg8(getreg8(LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET), \ + LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET); + up_serialout(priv, UART_EV_ENABLE_OFFSET, 0); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#if 0 /* TODO: Setup divisor */ +#endif + + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method + * is called when the serial port is opened. Normally, this is just after + * the the setup() method is called, however, the serial console may + * operate in a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Initialize interrupt generation on the peripheral */ + + putreg8(getreg8(LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET), \ + LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET); + up_serialout(priv, UART_EV_ENABLE_OFFSET, UART_EV_TX | UART_EV_RX); + + ret = irq_attach(priv->irq, up_interrupt, dev); + + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The + * exception is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_disable_irq(priv->irq); + + /* Detach from the interrupt */ + + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context, FAR void *arg) +{ + struct uart_dev_s *dev = (struct uart_dev_s *)arg; + struct up_dev_s *priv; + uint32_t status; + int passes; + + DEBUGASSERT(dev != NULL && dev->priv != NULL); + priv = (struct up_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + for (passes = 0; passes < 256; passes++) + { + /* Retrieve interrupt pending status */ + + status = up_serialin(priv, UART_EV_PENDING_OFFSET); + + if (status == 0) + { + break; + } + + if (status & UART_EV_RX) + { + /* Process incoming bytes */ + + uart_recvchars(dev); + } + + if (status & UART_EV_TX) + { + /* Process outgoing bytes */ + + putreg8(UART_EV_TX, LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET); + uart_xmitchars(dev); + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int rxdata; + + /* Return status information */ + + if (status) + { + *status = 0; /* We are not yet tracking serial errors */ + } + + rxdata = (int)(up_serialin(priv, UART_RXTX_OFFSET)); + putreg8(UART_EV_RX, LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET); + + return rxdata; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags = enter_critical_section(); + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->im |= UART_EV_RX; +#endif + } + else + { + priv->im &= ~UART_EV_RX; + } + + putreg8(getreg8(LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET), \ + LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET); + up_serialout(priv, UART_EV_ENABLE_OFFSET, priv->im); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return true is data is available in the receive data buffer */ + + uint32_t rxempty = up_serialin(priv, UART_RXEMPTY_OFFSET); + + return rxempty == 0; +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART. + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, UART_RXTX_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Enable the TX interrupt */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->im |= UART_EV_TX; + + putreg8(getreg8(LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET), \ + LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET); + up_serialout(priv, UART_EV_ENABLE_OFFSET, priv->im); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + priv->im &= ~UART_EV_TX; + + putreg8(getreg8(LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET), \ + LITEX_CONSOLE_BASE + UART_EV_PENDING_OFFSET); + up_serialout(priv, UART_EV_ENABLE_OFFSET, priv->im); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit data register is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return TRUE if the TX FIFO is not full */ + + return (up_serialin(priv, UART_TXFULL_OFFSET)) == 0; +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return TRUE if the TX is pending */ + + return (up_serialin(priv, UART_EV_PENDING_OFFSET) & UART_EV_TX) == 1; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. NOTE: This function depends on GPIO pin + * configuration performed in up_consoleinit() and main clock iniialization + * performed in up_clkinitialize(). + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Disable interrupts from all UARTS. The console is enabled in + * litex_consoleinit(). + */ + + up_disableuartint(TTYS0_DEV.priv, NULL); +#ifdef TTYS1_DEV + up_disableuartint(TTYS1_DEV.priv, NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_SERIAL_CONSOLE + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} +#endif + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_SERIAL_CONSOLE + uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs */ + + uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint8_t imr; + + up_disableuartint(priv, &imr); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); + up_restoreuartint(priv, imr); +#endif + return ch; +} + +/**************************************************************************** + * Name: up_earlyserialinit, up_serialinit, and up_putc + * + * Description: + * stubs that may be needed. These stubs would be used if all UARTs are + * disabled. In that case, the logic in common/up_initialize() is not + * smart enough to know that there are not UARTs and will still expect + * these interfaces to be provided. + * + ****************************************************************************/ + +#else /* HAVE_UART_DEVICE */ +void up_earlyserialinit(void) +{ +} + +void up_serialinit(void) +{ +} + +int up_putc(int ch) +{ + return ch; +} + +#endif /* HAVE_UART_DEVICE */ +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/risc-v/src/litex/litex_start.c b/arch/risc-v/src/litex/litex_start.c new file mode 100644 index 0000000000..c3022b4c09 --- /dev/null +++ b/arch/risc-v/src/litex/litex_start.c @@ -0,0 +1,125 @@ +/**************************************************************************** + * arch/risc-v/src/litex/litex_init.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "litex_clockconfig.h" +#include "litex.h" +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +# define showprogress(c) up_lowputc(c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_idle_topstack: _sbss is the start of the BSS region as defined by the + * linker script. _ebss lies at the end of the BSS region. The idle task + * stack starts at the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. + * The IDLE thread is the thread that the system boots on and, eventually, + * becomes the IDLE, do nothing task that runs only when there is nothing + * else to run. The heap continues from there until the end of memory. + * g_idle_topstack is a read-only variable the provides this computed + * address. + */ + +uint32_t g_idle_topstack = LITEX_IDLESTACK_TOP; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: litex_start + ****************************************************************************/ + +void __litex_start(void) +{ + const uint32_t *src; + uint32_t *dest; + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + /* for vexriscv the full image is loaded in ddr ram */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + /* Setup PLL */ + + litex_clockconfig(); + + /* Configure the UART so we can get debug output */ + + litex_lowsetup(); + + showprogress('A'); + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + + showprogress('B'); + + /* Do board initialization */ + + litex_boardinitialize(); + + showprogress('C'); + + /* Call nx_start() */ + + nx_start(); + + /* Shouldn't get here */ + + for (; ; ); +} diff --git a/arch/risc-v/src/litex/litex_timerisr.c b/arch/risc-v/src/litex/litex_timerisr.c new file mode 100644 index 0000000000..48449a47a7 --- /dev/null +++ b/arch/risc-v/src/litex/litex_timerisr.c @@ -0,0 +1,202 @@ +/**************************************************************************** + * arch/risc-v/src/litex/litex_timerisr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" + +#include "litex.h" +#include "litex_clockconfig.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define TICK_COUNT (litex_get_hfclk() / TICK_PER_SEC) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static bool _b_tick_started = false; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* litex mmio registers are a bit odd, by default they are byte-wide + * registers that are on 32-bit word boundaries. So a "32-bit" registers + * is actually broken into four bytes spanning a total address space of + * 16 bytes. + */ + +static inline uint64_t litex_clint_time_read(void) +{ + uint64_t r = getreg8(LITEX_CLINT_MTIME); + r <<= 8; + r |= getreg8(LITEX_CLINT_MTIME + 0x04); + r <<= 8; + r |= getreg8(LITEX_CLINT_MTIME + 0x08); + r <<= 8; + r |= getreg8(LITEX_CLINT_MTIME + 0x0c); + r <<= 8; + r |= getreg8(LITEX_CLINT_MTIME + 0x10); + r <<= 8; + r |= getreg8(LITEX_CLINT_MTIME + 0x14); + r <<= 8; + r |= getreg8(LITEX_CLINT_MTIME + 0x18); + r <<= 8; + r |= getreg8(LITEX_CLINT_MTIME + 0x1c); + return r; +} + +static inline uint64_t litex_clint_time_cmp_read(void) +{ + uint64_t r = getreg8(LITEX_CLINT_MTIMECMP); + r <<= 8; + r |= getreg8(LITEX_CLINT_MTIMECMP + 0x04); + r <<= 8; + r |= getreg8(LITEX_CLINT_MTIMECMP + 0x08); + r <<= 8; + r |= getreg8(LITEX_CLINT_MTIMECMP + 0x0c); + r <<= 8; + r |= getreg8(LITEX_CLINT_MTIMECMP + 0x10); + r <<= 8; + r |= getreg8(LITEX_CLINT_MTIMECMP + 0x14); + r <<= 8; + r |= getreg8(LITEX_CLINT_MTIMECMP + 0x18); + r <<= 8; + r |= getreg8(LITEX_CLINT_MTIMECMP + 0x1c); + return r; +} + +static inline void litex_clint_time_cmp_write(uint64_t v) +{ + putreg8(v >> 56, LITEX_CLINT_MTIMECMP); + putreg8(v >> 48, LITEX_CLINT_MTIMECMP + 0x04); + putreg8(v >> 40, LITEX_CLINT_MTIMECMP + 0x08); + putreg8(v >> 32, LITEX_CLINT_MTIMECMP + 0x0c); + putreg8(v >> 24, LITEX_CLINT_MTIMECMP + 0x10); + putreg8(v >> 16, LITEX_CLINT_MTIMECMP + 0x14); + putreg8(v >> 8, LITEX_CLINT_MTIMECMP + 0x18); + putreg8(v, LITEX_CLINT_MTIMECMP + 0x1c); +} + +/* helper function to set/clear csr */ + +#define csr_clear(csr, val) \ +({ \ + unsigned long __v = (unsigned long)(val); \ + __asm__ __volatile__ ("csrc " #csr ", %0" \ + : : "rK" (__v)); \ +}) + +#define csr_set(csr, val) \ +({ \ + unsigned long __v = (unsigned long)(val); \ + __asm__ __volatile__ ("csrs " #csr ", %0" \ + : : "rK" (__v)); \ +}) + +/**************************************************************************** + * Name: litex_reload_mtimecmp + ****************************************************************************/ + +static void litex_reload_mtimecmp(void) +{ + irqstate_t flags = spin_lock_irqsave(); + + uint64_t current; + uint64_t next; + + if (!_b_tick_started) + { + _b_tick_started = true; + putreg8(1, LITEX_CLINT_LATCH); + current = litex_clint_time_read(); + } + else + { + current = litex_clint_time_cmp_read(); + } + + next = current + TICK_COUNT; + + litex_clint_time_cmp_write(next); + putreg8(1, LITEX_CLINT_LATCH); + csr_set(mie, MIE_MTIE); + csr_clear(mip, MIP_MTIP); + + spin_unlock_irqrestore(flags); +} + +/**************************************************************************** + * Name: litex_timerisr + ****************************************************************************/ + +static int litex_timerisr(int irq, void *context, FAR void *arg) +{ + litex_reload_mtimecmp(); + + /* Process timer interrupt */ + + nxsched_process_timer(); + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + /* Attach timer interrupt handler */ + + irq_attach(LITEX_IRQ_MTIMER, litex_timerisr, NULL); + + /* Reload CLINT mtimecmp */ + + litex_reload_mtimecmp(); + + /* And enable the timer interrupt */ + + up_enable_irq(LITEX_IRQ_MTIMER); +} diff --git a/arch/risc-v/src/litex/litex_vectors.S b/arch/risc-v/src/litex/litex_vectors.S new file mode 100644 index 0000000000..da77137632 --- /dev/null +++ b/arch/risc-v/src/litex/litex_vectors.S @@ -0,0 +1,42 @@ +/**************************************************************************** + * arch/risc-v/src/litex/litex_vectors.S + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + + .section .text.vec + .global __reset_vec + .global __trap_vec + +/**************************************************************************** + * Name: __reset_vec + ****************************************************************************/ + +__reset_vec: + jal __start + +/**************************************************************************** + * Name: exception_common + ****************************************************************************/ + +__trap_vec: + j exception_common + nop diff --git a/arch/risc-v/src/litex/up_schedulesigaction.c b/arch/risc-v/src/litex/up_schedulesigaction.c new file mode 100644 index 0000000000..1becce5dd6 --- /dev/null +++ b/arch/risc-v/src/litex/up_schedulesigaction.c @@ -0,0 +1,192 @@ +/**************************************************************************** + * arch/risc-v/src/litex/up_schedulesigaction.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'igdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + uint32_t int_ctx; + + sinfo("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (!tcb->xcp.sigdeliver) + { + /* First, handle some special cases when the signal is + * being delivered to the currently executing task. + */ + + sinfo("rtcb=0x%p g_current_regs=0x%p\n", + this_task(), g_current_regs); + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and + * a task is signalling itself for some reason. + */ + + if (!g_current_regs) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the + * interrupted task is the same as the one that + * must receive the signal, then we will have to modify + * the return state as well as the state in the TCB. + * + * Hmmm... there looks like a latent bug here: The following + * logic would fail in the strange case where we are in an + * interrupt handler, the thread is signalling itself, but + * a context switch to another task has occurred so that + * g_current_regs does not refer to the thread of this_task()! + */ + + else + { + /* Save the return EPC and STATUS registers. These will be + * restored by the signal trampoline after the signals have + * been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_epc = g_current_regs[REG_EPC]; + tcb->xcp.saved_int_ctx = g_current_regs[REG_INT_CTX]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + g_current_regs[REG_EPC] = (uint32_t)up_sigdeliver; + + int_ctx = g_current_regs[REG_INT_CTX]; + int_ctx &= ~MSTATUS_MIE; + + g_current_regs[REG_INT_CTX] = int_ctx; + + /* And make sure that the saved context in the TCB + * is the same as the interrupt return context. + */ + + up_savestate(tcb->xcp.regs); + + sinfo("PC/STATUS Saved: %08x/%08x New: %08x/%08x\n", + tcb->xcp.saved_epc, tcb->xcp.saved_int_ctx, + g_current_regs[REG_EPC], g_current_regs[REG_INT_CTX]); + } + } + + /* Otherwise, we are (1) signaling a task is not running + * from an interrupt handler or (2) we are not in an + * interrupt handler and the running task is signalling + * some non-running task. + */ + + else + { + /* Save the return EPC and STATUS registers. These will be + * restored by the signal trampoline after the signals have + * been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_epc = tcb->xcp.regs[REG_EPC]; + tcb->xcp.saved_int_ctx = tcb->xcp.regs[REG_INT_CTX]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + tcb->xcp.regs[REG_EPC] = (uint32_t)up_sigdeliver; + + int_ctx = tcb->xcp.regs[REG_INT_CTX]; + int_ctx &= ~MSTATUS_MIE; + + tcb->xcp.regs[REG_INT_CTX] = int_ctx; + + sinfo("PC/STATUS Saved: %08x/%08x New: %08x/%08x\n", + tcb->xcp.saved_epc, tcb->xcp.saved_int_ctx, + tcb->xcp.regs[REG_EPC], tcb->xcp.regs[REG_INT_CTX]); + } + } + + leave_critical_section(flags); +} diff --git a/boards/Kconfig b/boards/Kconfig index 8a33c2c417..f241372499 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -43,6 +43,13 @@ config ARCH_BOARD_ARDUINO_M0 This options selects the Arduino M0 board featuring the Atmel ATSAMD21 MCU. +config ARCH_BOARD_ARTY_A7 + bool "DIGILENT ARTY_A7 board" + depends on ARCH_CHIP_LITEX + ---help--- + This is the board configuration for the port of NuttX to the Digilent ARTY A7 + board. This board features the RISC-V litex vexriscv softcore + config ARCH_BOARD_AVR32DEV1 bool "Atmel AVR32DEV1 board" depends on ARCH_CHIP_AT32UC3B0256 @@ -2058,6 +2065,7 @@ config ARCH_BOARD default "arduino-mega2560" if ARCH_BOARD_ARDUINO_MEGA2560 default "arduino-due" if ARCH_BOARD_ARDUINO_DUE default "arduino-m0" if ARCH_BOARD_ARDUINO_M0 + default "arty_a7" if ARCH_BOARD_ARTY_A7 default "avr32dev1" if ARCH_BOARD_AVR32DEV1 default "axoloti" if ARCH_BOARD_AXOLOTI default "bambino-200e" if ARCH_BOARD_BAMBINO_200E @@ -2819,6 +2827,9 @@ endif if ARCH_BOARD_US7032EVB1 source "boards/renesas/sh1/us7032evb1/Kconfig" endif +if ARCH_BOARD_ARTY_A7 +source "boards/risc-v/litex/arty_a7/Kconfig" +endif if ARCH_BOARD_GAPUINO source "boards/risc-v/gap8/gapuino/Kconfig" endif diff --git a/boards/risc-v/litex/arty_a7/Kconfig b/boards/risc-v/litex/arty_a7/Kconfig new file mode 100644 index 0000000000..cedc8e45a4 --- /dev/null +++ b/boards/risc-v/litex/arty_a7/Kconfig @@ -0,0 +1,8 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# + +if ARCH_BOARD_ARTY_A7 + +endif diff --git a/boards/risc-v/litex/arty_a7/README.txt b/boards/risc-v/litex/arty_a7/README.txt new file mode 100644 index 0000000000..e7bd857d01 --- /dev/null +++ b/boards/risc-v/litex/arty_a7/README.txt @@ -0,0 +1,28 @@ +1. Download and install toolchain + + $ curl https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14.tar.gz + +2. Follow instruction on https://github.com/enjoy-digital/litex to build the vexriscv softcore fpga gateware + and flash to arty_a7 board + +3. Configure and build NuttX + + $ mkdir ./nuttx; cd ./nuttx + $ git clone https://bitbucket.org/nuttx/nuttx.git + $ git clone https://bitbucket.org/nuttx/apps.git + $ cd nuttx + $ make distclean + $ ./tools/configure.sh arty_a7:nsh + $ make V=1 + +4. Setup tftp server on your laptop, copy nuttx.bin to your tftpboot directory and change its name to boot.bin + +5. Setup the wire connection(uart and tftp) between your board and laptop + +6. Run $ minicom -b 1000000 /dev/ttyUSB1 (the default baudrate on litex vexriscv is 1e6) + when you see the bios prompt "litex>", type "netboot" and enter soon comes the nsh prompt + +7. TODO + + Support GPIO/SPI/I2C/RTC/WDT/PWM + Support RISC-V User mode diff --git a/boards/risc-v/litex/arty_a7/configs/nsh/defconfig b/boards/risc-v/litex/arty_a7/configs/nsh/defconfig new file mode 100644 index 0000000000..09fd4f171c --- /dev/null +++ b/boards/risc-v/litex/arty_a7/configs/nsh/defconfig @@ -0,0 +1,74 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLE_LOSMART is not set +# CONFIG_NSH_DISABLE_UNAME is not set +# CONFIG_STANDARD_SERIAL is not set +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="arty_a7" +CONFIG_ARCH_BOARD_ARTY_A7=y +CONFIG_ARCH_CHIP="litex" +CONFIG_ARCH_CHIP_LITEX=y +CONFIG_ARCH_INTERRUPTSTACK=8192 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BINFMT_DISABLE=y +CONFIG_BOARD_LOOPSPERMSEC=10000 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DEV_ZERO=y +CONFIG_DISABLE_MQUEUE=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_EXAMPLES_HELLO_STACKSIZE=8192 +CONFIG_FS_PROCFS=y +CONFIG_FS_WRITABLE=y +CONFIG_IDLETHREAD_STACKSIZE=8192 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_MAX_TASKS=8 +CONFIG_MAX_WDOGPARMS=2 +CONFIG_NFILE_DESCRIPTORS=6 +CONFIG_NFILE_STREAMS=6 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_CD=y +CONFIG_NSH_DISABLE_CP=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_DISABLE_MKDIR=y +CONFIG_NSH_DISABLE_RM=y +CONFIG_NSH_DISABLE_RMDIR=y +CONFIG_NSH_DISABLE_UMOUNT=y +CONFIG_NSH_FILEIOSIZE=64 +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=0 +CONFIG_PREALLOC_WDOGS=4 +CONFIG_PTHREAD_STACK_DEFAULT=8192 +CONFIG_RAM_SIZE=134217728 +CONFIG_RAM_START=0xc0800000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_RV32IM_CUSTOM_IRQ_SUPPORT=y +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=20 +CONFIG_START_MONTH=3 +CONFIG_START_YEAR=2020 +CONFIG_STDIO_DISABLE_BUFFERING=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=12 +CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=8192 +CONFIG_TESTING_GETPRIME=y +CONFIG_UART0_RXBUFSIZE=128 +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_UART0_TXBUFSIZE=128 +CONFIG_USERMAIN_STACKSIZE=8192 +CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_WDOG_INTRESERVE=0 diff --git a/boards/risc-v/litex/arty_a7/include/board.h b/boards/risc-v/litex/arty_a7/include/board.h new file mode 100644 index 0000000000..f9b5e649c3 --- /dev/null +++ b/boards/risc-v/litex/arty_a7/include/board.h @@ -0,0 +1,68 @@ +/**************************************************************************** + * boards/risc-v/litex/arty_a7/include/board.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_RISCV_LITEX_ARTY_A7_INCLUDE_BOARD_H +#define __BOARDS_RISCV_LITEX_ARTY_A7_INCLUDE_BOARD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: litex_boardinitialize + ****************************************************************************/ + +void litex_boardinitialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_RISC-V_LITEX_ARTY_A7_INCLUDE_BOARD_H */ diff --git a/boards/risc-v/litex/arty_a7/scripts/Make.defs b/boards/risc-v/litex/arty_a7/scripts/Make.defs new file mode 100644 index 0000000000..960dda1d3d --- /dev/null +++ b/boards/risc-v/litex/arty_a7/scripts/Make.defs @@ -0,0 +1,96 @@ +############################################################################ +# boards/risc-v/litex/arty_a7/scripts/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include ${TOPDIR}/.config +include ${TOPDIR}/tools/Config.mk +include ${TOPDIR}/arch/risc-v/src/rv32im/Toolchain.defs + +LDSCRIPT = ld.script + +ifeq ($(WINTOOL),y) + # Windows-native toolchains + DIRLINK = $(TOPDIR)/tools/copydir.sh + DIRUNLINK = $(TOPDIR)/tools/unlink.sh + MKDEP = $(TOPDIR)/tools/mkwindeps.sh + ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" + ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}" + ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/boards/$(CONFIG_ARCH)/$(CONFIG_ARCH_CHIP)/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}" +else + # Linux/Cygwin-native toolchain + MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT) + ARCHINCLUDES = -I. -isystem $(TOPDIR)/include + ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx + ARCHSCRIPT = -T$(TOPDIR)/boards/$(CONFIG_ARCH)/$(CONFIG_ARCH_CHIP)/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT) +endif + +CC = $(CROSSDEV)gcc +CXX = $(CROSSDEV)g++ +CPP = $(CROSSDEV)gcc -E +LD = $(CROSSDEV)ld +STRIP = $(CROSSDEV)strip --strip-unneeded +AR = $(ARCROSSDEV)ar rcs +NM = $(ARCROSSDEV)nm +OBJCOPY = $(CROSSDEV)objcopy +OBJDUMP = $(CROSSDEV)objdump + +ARCHCCVERSION = ${shell $(CC) -v 2>&1 | sed -n '/^gcc version/p' | sed -e 's/^gcc version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g' -e '1q'} +ARCHCCMAJOR = ${shell echo $(ARCHCCVERSION) | cut -d'.' -f1} + +ifeq ($(CONFIG_DEBUG_SYMBOLS),y) + ARCHOPTIMIZATION = -g + ASARCHCPUFLAGS += -Wa,-g +endif + +MAXOPTIMIZATION = -Os + +ifneq ($(CONFIG_DEBUG_NOOPT),y) + ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer +endif + +ARCHCPUFLAGS = -march=rv32ima -mabi=ilp32 +ARCHCFLAGS = -fno-builtin -ffunction-sections -fdata-sections +ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti +ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef +ARCHWARNINGSXX = -Wall -Wshadow -Wundef +ARCHDEFINES = +ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10 + +CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe +CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS) +CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) +AFLAGS += $(CFLAGS) -D__ASSEMBLY__ $(ASARCHCPUFLAGS) + +NXFLATLDFLAGS1 = -r -d -warn-common +NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections +LDNXFLATFLAGS = -e main -s 2048 + +ASMEXT = .S +OBJEXT = .o +LIBEXT = .a +EXEEXT = + +LDFLAGS += --gc-sections -melf32lriscv + +HOSTCC = gcc +HOSTINCLUDES = -I. +HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -g -pipe +HOSTLDFLAGS = diff --git a/boards/risc-v/litex/arty_a7/scripts/ld.script b/boards/risc-v/litex/arty_a7/scripts/ld.script new file mode 100644 index 0000000000..83ba9953c5 --- /dev/null +++ b/boards/risc-v/litex/arty_a7/scripts/ld.script @@ -0,0 +1,93 @@ +/**************************************************************************** + * boards/risc-v/litex/arty_a7/scripts/ld.script + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +MEMORY +{ + progmem (rx) : ORIGIN = 0xc0000000, LENGTH = 8M + sram (rwx) : ORIGIN = 0xc0800000, LENGTH = 256M - 8M +} + +OUTPUT_ARCH("riscv") + +ENTRY(_stext) +EXTERN(_vectors) +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.* .srodata .srodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > progmem + + .init_section : ALIGN(4) { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > progmem + + _eronly = ABSOLUTE(.); + + .data : ALIGN(4) { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.d.*) + *(.gnu.linkonce.s.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > sram AT > progmem + + .bss : ALIGN(4) { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.sbss .sbss.*) + *(.gnu.linkonce.b.*) + *(.gnu.linkonce.sb.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* 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) } +} diff --git a/boards/risc-v/litex/arty_a7/src/Makefile b/boards/risc-v/litex/arty_a7/src/Makefile new file mode 100644 index 0000000000..bc9d43f594 --- /dev/null +++ b/boards/risc-v/litex/arty_a7/src/Makefile @@ -0,0 +1,29 @@ +############################################################################ +# boards/risc-v/litex/arty_a7/src/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +-include $(TOPDIR)/Make.defs + +CSRCS = litex_bringup.c litex_boot.c + +ifeq ($(CONFIG_LIB_BOARDCTL),y) +CSRCS += litex_appinit.c +endif + +include $(TOPDIR)/boards/Board.mk diff --git a/boards/risc-v/litex/arty_a7/src/arty_a7.h b/boards/risc-v/litex/arty_a7/src/arty_a7.h new file mode 100644 index 0000000000..00e564bbcd --- /dev/null +++ b/boards/risc-v/litex/arty_a7/src/arty_a7.h @@ -0,0 +1,32 @@ +/**************************************************************************** + * boards/risc-v/litex/arty_a7/src/arty_a7.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_RISCV_LITEX_ARTY_A7_SRC_ARTY_A7_H +#define __BOARDS_RISCV_LITEX_ARTY_A7_SRC_ARTY_A7_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +int litex_bringup(void); + +#endif /* __BOARDS_RISCV_LITEX_ARTY_A7_SRC_ARTY_A7_H */ diff --git a/boards/risc-v/litex/arty_a7/src/litex_appinit.c b/boards/risc-v/litex/arty_a7/src/litex_appinit.c new file mode 100644 index 0000000000..c2d92e8382 --- /dev/null +++ b/boards/risc-v/litex/arty_a7/src/litex_appinit.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * boards/risc-v/litex/arty_a7/src/litex_appinit.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "litex.h" +#include "arty_a7.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform architecture specific initialization + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; the meaning of the argument is a contract + * between the board-specific initialization logic and the + * matching application logic. The value cold be such things as a + * mode enumeration value, a set of DIP switch switch settings, a + * pointer to configuration data read from a file or serial FLASH, + * or whatever you would like to do with it. Every implementation + * should accept zero/NULL as a default configuration. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ + +int board_app_initialize(uintptr_t arg) +{ +#ifdef CONFIG_BOARD_LATE_INITIALIZE + /* Board initialization already performed by board_late_initialize() */ + + return OK; +#else + /* Perform board-specific initialization */ + + return litex_bringup(); +#endif +} diff --git a/boards/risc-v/litex/arty_a7/src/litex_boot.c b/boards/risc-v/litex/arty_a7/src/litex_boot.c new file mode 100644 index 0000000000..43a3c7a0df --- /dev/null +++ b/boards/risc-v/litex/arty_a7/src/litex_boot.c @@ -0,0 +1,57 @@ +/**************************************************************************** + * boards/risc-v/litex/arty_a7/src/litex_boot.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: litex_boardinitialize + * + * Description: + * All LITEX architectures must provide the following entry point. + * This entry point is called early in the initialization -- after all + * memory has been configured and mapped but before any devices have been + * initialized. + * + ****************************************************************************/ + +void litex_boardinitialize(void) +{ +} diff --git a/boards/risc-v/litex/arty_a7/src/litex_bringup.c b/boards/risc-v/litex/arty_a7/src/litex_bringup.c new file mode 100644 index 0000000000..9b8e14fe20 --- /dev/null +++ b/boards/risc-v/litex/arty_a7/src/litex_bringup.c @@ -0,0 +1,61 @@ +/**************************************************************************** + * boards/risc-v/litex/arty_a7/src/litex_bringup.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "litex.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: litex_bringup + ****************************************************************************/ + +int litex_bringup(void) +{ + int ret = OK; + +#ifdef CONFIG_FS_PROCFS + /* Mount the procfs file system */ + + ret = mount(NULL, "/proc", "procfs", 0, NULL); + if (ret < 0) + { + serr("ERROR: Failed to mount procfs at %s: %d\n", "/proc", ret); + } +#endif + + return ret; +} diff --git a/boards/risc-v/litex/drivers/Kconfig b/boards/risc-v/litex/drivers/Kconfig new file mode 100644 index 0000000000..f72f3c094c --- /dev/null +++ b/boards/risc-v/litex/drivers/Kconfig @@ -0,0 +1,4 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +#