diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index 3e4eec577da..8b769e9b059 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -264,6 +264,23 @@ config ARCH_CHIP_C906 ---help--- THEAD C906 processor (RISC-V 64bit core with GCVX extensions). +config ARCH_CHIP_ERBIUM + bool "AIFoundry Erbium" + select ARCH_RV64 + select ARCH_RV_ISA_M + select ARCH_RV_ISA_C + select ARCH_HAVE_FPU + select ONESHOT + select ONESHOT_COUNT + select ONESHOT_FAST_DIVISION + select ALARM_ARCH + select LIBC_ATOMIC_IRQ + select OTHER_UART_SERIALDRIVER + select UART0_SERIALDRIVER + ---help--- + AIFoundry Erbium minion hart: RV64IMFC, machine timer, + and SiFive-style PLIC. + config ARCH_CHIP_MPFS bool "MicroChip Polarfire (MPFS)" select ARCH_RV64 @@ -672,6 +689,7 @@ config ARCH_CHIP default "esp32h2" if ARCH_CHIP_ESP32H2 default "esp32p4" if ARCH_CHIP_ESP32P4 default "c906" if ARCH_CHIP_C906 + default "erbium" if ARCH_CHIP_ERBIUM default "mpfs" if ARCH_CHIP_MPFS default "rv32m1" if ARCH_CHIP_RV32M1 default "qemu-rv" if ARCH_CHIP_QEMU_RV @@ -930,6 +948,9 @@ endif if ARCH_CHIP_C906 source "arch/risc-v/src/c906/Kconfig" endif +if ARCH_CHIP_ERBIUM +source "arch/risc-v/src/erbium/Kconfig" +endif if ARCH_CHIP_MPFS source "arch/risc-v/src/mpfs/Kconfig" endif diff --git a/arch/risc-v/include/erbium/chip.h b/arch/risc-v/include/erbium/chip.h new file mode 100644 index 00000000000..a2f0fd8419e --- /dev/null +++ b/arch/risc-v/include/erbium/chip.h @@ -0,0 +1,26 @@ +/**************************************************************************** + * arch/risc-v/include/erbium/chip.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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_ERBIUM_CHIP_H +#define __ARCH_RISCV_INCLUDE_ERBIUM_CHIP_H + +#endif /* __ARCH_RISCV_INCLUDE_ERBIUM_CHIP_H */ diff --git a/arch/risc-v/include/erbium/irq.h b/arch/risc-v/include/erbium/irq.h new file mode 100644 index 00000000000..50c13cc3b46 --- /dev/null +++ b/arch/risc-v/include/erbium/irq.h @@ -0,0 +1,35 @@ +/**************************************************************************** + * arch/risc-v/include/erbium/irq.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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_ERBIUM_IRQ_H +#define __ARCH_RISCV_INCLUDE_ERBIUM_IRQ_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ERBIUM_IRQ_UART0 (RISCV_IRQ_MEXT + 3) +#define ERBIUM_IRQ_EXT_MAX (RISCV_IRQ_MEXT + 6) + +#define NR_IRQS (ERBIUM_IRQ_EXT_MAX + 1) + +#endif /* __ARCH_RISCV_INCLUDE_ERBIUM_IRQ_H */ diff --git a/arch/risc-v/src/erbium/CMakeLists.txt b/arch/risc-v/src/erbium/CMakeLists.txt new file mode 100644 index 00000000000..492a1c1d988 --- /dev/null +++ b/arch/risc-v/src/erbium/CMakeLists.txt @@ -0,0 +1,26 @@ +# ############################################################################## +# arch/risc-v/src/erbium/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +# ############################################################################## + +set(SRCS erbium_head.S erbium_start.c erbium_irq.c erbium_irq_dispatch.c + erbium_timerisr.c erbium_serial.c) + +target_sources(arch PRIVATE ${SRCS}) diff --git a/arch/risc-v/src/erbium/Kconfig b/arch/risc-v/src/erbium/Kconfig new file mode 100644 index 00000000000..de2f898d1c7 --- /dev/null +++ b/arch/risc-v/src/erbium/Kconfig @@ -0,0 +1,22 @@ +# +# SPDX-License-Identifier: Apache-2.0 +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config ERBIUM_UART_CLOCK + int "UART input clock (Hz)" + default 6666667 + range 1 2147483647 + ---help--- + UART peripheral clock after the Erbium divide-by-30 prescaler, + with a 200 MHz system clock. + +config ERBIUM_MTIMER_FREQ + int "Machine timer frequency (Hz)" + default 2000000 + range 1 2147483647 + ---help--- + Machine timer frequency after the reference clock divider and + timer prescaler. The ET-platform emulator defaults to 2 MHz. diff --git a/arch/risc-v/src/erbium/Make.defs b/arch/risc-v/src/erbium/Make.defs new file mode 100644 index 00000000000..b4657dfee5a --- /dev/null +++ b/arch/risc-v/src/erbium/Make.defs @@ -0,0 +1,28 @@ +############################################################################ +# arch/risc-v/src/erbium/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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 common/Make.defs + +HEAD_ASRC = erbium_head.S + +CHIP_CSRCS = erbium_start.c erbium_irq_dispatch.c erbium_irq.c +CHIP_CSRCS += erbium_timerisr.c erbium_serial.c diff --git a/arch/risc-v/src/erbium/chip.h b/arch/risc-v/src/erbium/chip.h new file mode 100644 index 00000000000..f90405b10c6 --- /dev/null +++ b/arch/risc-v/src/erbium/chip.h @@ -0,0 +1,42 @@ +/**************************************************************************** + * arch/risc-v/src/erbium/chip.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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_ERBIUM_CHIP_H +#define __ARCH_RISCV_SRC_ERBIUM_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "erbium_memorymap.h" +#include "hardware/erbium_memorymap.h" +#include "hardware/erbium_mtimer.h" +#include "hardware/erbium_plic.h" +#include "hardware/erbium_sysreg.h" +#include "riscv_internal.h" +#include "riscv_percpu.h" + +#endif /* __ARCH_RISCV_SRC_ERBIUM_CHIP_H */ diff --git a/arch/risc-v/src/erbium/erbium_head.S b/arch/risc-v/src/erbium/erbium_head.S new file mode 100644 index 00000000000..faf674ce562 --- /dev/null +++ b/arch/risc-v/src/erbium/erbium_head.S @@ -0,0 +1,97 @@ +/**************************************************************************** + * arch/risc-v/src/erbium/erbium_head.S + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 "chip.h" +#include "riscv_macros.S" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: __start + * + * Description: + * Initialize the stack, global pointer and trap vector on hart 0 before + * entering C startup. Park other harts with their interrupts disabled. + * + * Input Parameters: + * None. + * + * Returned Value: + * Does not return. + * + ****************************************************************************/ + + .section .text.__start, "ax", @progbits + .global __start + .type __start, function + +__start: + csrw CSR_MIE, zero + csrr a0, CSR_MHARTID + bnez a0, 2f + + /* Only hart 0 owns the NuttX image and its stack. */ + + .option push + .option norelax + la gp, __global_pointer$ + .option pop + + riscv_set_inital_sp ERBIUM_IDLESTACK_BASE, SMP_STACK_SIZE, a0 + la t0, __erbium_trap_vec + csrw CSR_MTVEC, t0 + j erbium_start + +2: + wfi + j 2b + +/**************************************************************************** + * Name: __erbium_trap_vec + * + * Description: + * Transfer control to the common RISC-V exception entry point. + * + * Input Parameters: + * None. Hardware supplies the trap state in the machine CSRs. + * + * Returned Value: + * Returns through the common exception handler. + * + ****************************************************************************/ + + .section .text.exceptions, "ax", @progbits + .balign 4 + .global __erbium_trap_vec + +__erbium_trap_vec: + j exception_common diff --git a/arch/risc-v/src/erbium/erbium_irq.c b/arch/risc-v/src/erbium/erbium_irq.c new file mode 100644 index 00000000000..da82ccba70a --- /dev/null +++ b/arch/risc-v/src/erbium/erbium_irq.c @@ -0,0 +1,166 @@ +/**************************************************************************** + * arch/risc-v/src/erbium/erbium_irq.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 "chip.h" +#include "riscv_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + * + * Description: + * Initialize hart 0 interrupt state and PLIC priorities, attach the + * common exception handlers, and enable interrupts unless suppressed. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_irqinitialize(void) +{ + int id; + + up_irq_save(); + WRITE_CSR(CSR_IE, 0); + putreg32(0, ERBIUM_PLIC_ENABLE1); + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 15 + riscv_stack_color(g_intstackalloc, CONFIG_ARCH_INTERRUPTSTACK & ~15); +#endif + + for (id = 1; id <= ERBIUM_PLIC_NDEV; id++) + { + putreg32(1, ERBIUM_PLIC_PRIORITY + 4 * id); + } + + putreg32(0, ERBIUM_PLIC_THRESHOLD); + riscv_exception_attach(); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Mask a supported hart-local interrupt or PLIC source. Ignore numbers + * that do not identify a supported interrupt. + * + * Input Parameters: + * irq - NuttX interrupt number to disable. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + if (irq == RISCV_IRQ_SOFT) + { + CLEAR_CSR(CSR_IE, IE_SIE); + } + else if (irq == RISCV_IRQ_TIMER) + { + CLEAR_CSR(CSR_IE, IE_TIE); + } + else if (irq == RISCV_IRQ_EXT) + { + CLEAR_CSR(CSR_IE, IE_EIE); + } + else if (irq > RISCV_IRQ_EXT && irq < NR_IRQS) + { + modifyreg32(ERBIUM_PLIC_ENABLE1, 1u << (irq - RISCV_IRQ_EXT), 0); + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Unmask a supported hart-local interrupt or PLIC source. Ignore numbers + * that do not identify a supported interrupt. + * + * Input Parameters: + * irq - NuttX interrupt number to enable. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + if (irq == RISCV_IRQ_SOFT) + { + SET_CSR(CSR_IE, IE_SIE); + } + else if (irq == RISCV_IRQ_TIMER) + { + SET_CSR(CSR_IE, IE_TIE); + } + else if (irq == RISCV_IRQ_EXT) + { + SET_CSR(CSR_IE, IE_EIE); + } + else if (irq > RISCV_IRQ_EXT && irq < NR_IRQS) + { + modifyreg32(ERBIUM_PLIC_ENABLE1, 0, 1u << (irq - RISCV_IRQ_EXT)); + } +} + +/**************************************************************************** + * Name: up_irq_enable + * + * Description: + * Enable machine external interrupt delivery and global interrupts. + * + * Input Parameters: + * None. + * + * Returned Value: + * The previous status register value, for restoring interrupt state. + * + ****************************************************************************/ + +irqstate_t up_irq_enable(void) +{ + up_enable_irq(RISCV_IRQ_EXT); + return READ_AND_SET_CSR(CSR_STATUS, STATUS_IE); +} diff --git a/arch/risc-v/src/erbium/erbium_irq_dispatch.c b/arch/risc-v/src/erbium/erbium_irq_dispatch.c new file mode 100644 index 00000000000..ecc6369cddf --- /dev/null +++ b/arch/risc-v/src/erbium/erbium_irq_dispatch.c @@ -0,0 +1,83 @@ +/**************************************************************************** + * arch/risc-v/src/erbium/erbium_irq_dispatch.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 "hardware/erbium_plic.h" +#include "riscv_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: riscv_dispatch_irq + * + * Description: + * Dispatch hart-local traps or claim, dispatch and complete a PLIC + * interrupt. Complete nonzero claims even if their source is unsupported. + * + * Input Parameters: + * vector - Trap cause register value. + * regs - Saved registers for the interrupted task. + * + * Returned Value: + * The register context to restore, possibly belonging to another task. + * + ****************************************************************************/ + +void *riscv_dispatch_irq(uintreg_t vector, uintreg_t *regs) +{ + int irq = vector & RISCV_IRQ_MASK; + uint32_t claim; + + if ((vector & RISCV_IRQ_BIT) != 0) + { + irq += RISCV_IRQ_ASYNC; + } + + if (irq == RISCV_IRQ_EXT) + { + claim = getreg32(ERBIUM_PLIC_CLAIM); + if (claim != 0) + { + if (claim <= ERBIUM_PLIC_NDEV) + { + regs = riscv_doirq(RISCV_IRQ_EXT + claim, regs); + } + + putreg32(claim, ERBIUM_PLIC_CLAIM); + } + } + else + { + regs = riscv_doirq(irq, regs); + } + + return regs; +} diff --git a/arch/risc-v/src/erbium/erbium_memorymap.h b/arch/risc-v/src/erbium/erbium_memorymap.h new file mode 100644 index 00000000000..82f03018014 --- /dev/null +++ b/arch/risc-v/src/erbium/erbium_memorymap.h @@ -0,0 +1,45 @@ +/**************************************************************************** + * arch/risc-v/src/erbium/erbium_memorymap.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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_ERBIUM_ERBIUM_MEMORYMAP_H +#define __ARCH_RISCV_SRC_ERBIUM_ERBIUM_MEMORYMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "riscv_common_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# define ERBIUM_IDLESTACK_BASE (uintptr_t)_ebss +#else +# define ERBIUM_IDLESTACK_BASE _ebss +#endif + +#define ERBIUM_IDLESTACK_SIZE SMP_STACK_SIZE +#define ERBIUM_IDLESTACK_TOP (ERBIUM_IDLESTACK_BASE + ERBIUM_IDLESTACK_SIZE) + +#endif /* __ARCH_RISCV_SRC_ERBIUM_ERBIUM_MEMORYMAP_H */ diff --git a/arch/risc-v/src/erbium/erbium_serial.c b/arch/risc-v/src/erbium/erbium_serial.c new file mode 100644 index 00000000000..11ec3c877ca --- /dev/null +++ b/arch/risc-v/src/erbium/erbium_serial.c @@ -0,0 +1,755 @@ +/**************************************************************************** + * arch/risc-v/src/erbium/erbium_serial.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 "chip.h" +#include "hardware/erbium_memorymap.h" +#include "hardware/erbium_sysreg.h" +#include "hardware/erbium_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ERBIUM_UART_BAUD_DIV \ + (CONFIG_ERBIUM_UART_CLOCK / (16 * CONFIG_UART0_BAUD)) + +#if CONFIG_UART0_BITS != 8 || CONFIG_UART0_PARITY != 0 || \ + CONFIG_UART0_2STOP != 0 +# error "The Erbium UART driver supports only 8N1" +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct erbium_uart_s +{ + uintptr_t base; + uint8_t irq; + uint32_t ien; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int erbium_setup(struct uart_dev_s *dev); +static void erbium_shutdown(struct uart_dev_s *dev); +static int erbium_attach(struct uart_dev_s *dev); +static void erbium_detach(struct uart_dev_s *dev); +static int erbium_interrupt(int irq, void *context, void *arg); +static int erbium_ioctl(struct file *filep, int cmd, unsigned long arg); +static int erbium_receive(struct uart_dev_s *dev, unsigned int *status); +static void erbium_rxint(struct uart_dev_s *dev, bool enable); +static bool erbium_rxavailable(struct uart_dev_s *dev); +static void erbium_send(struct uart_dev_s *dev, int ch); +static void erbium_txint(struct uart_dev_s *dev, bool enable); +static bool erbium_txready(struct uart_dev_s *dev); +static bool erbium_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; + +static struct erbium_uart_s g_uart0priv = +{ + .base = ERBIUM_UART0_BASE, + .irq = ERBIUM_IRQ_UART0, +}; + +static const struct uart_ops_s g_uart_ops = +{ + .setup = erbium_setup, + .shutdown = erbium_shutdown, + .attach = erbium_attach, + .detach = erbium_detach, + .ioctl = erbium_ioctl, + .receive = erbium_receive, + .rxint = erbium_rxint, + .rxavailable = erbium_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = erbium_send, + .txint = erbium_txint, + .txready = erbium_txready, + .txempty = erbium_txempty, +}; + +static uart_dev_t g_uart0port = +{ +#ifdef CONFIG_UART0_SERIAL_CONSOLE + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: erbium_serialin + * + * Description: + * Read a 32-bit UART register. + * + * Input Parameters: + * priv - UART register base and cached interrupt mask. + * offset - Register offset from the UART base address. + * + * Returned Value: + * The register value. + * + ****************************************************************************/ + +static uint32_t erbium_serialin(struct erbium_uart_s *priv, uintptr_t offset) +{ + return getreg32(priv->base + offset); +} + +/**************************************************************************** + * Name: erbium_serialout + * + * Description: + * Write a 32-bit UART register. + * + * Input Parameters: + * priv - UART register base and cached interrupt mask. + * offset - Register offset from the UART base address. + * value - Value to write. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void erbium_serialout(struct erbium_uart_s *priv, uintptr_t offset, + uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +/**************************************************************************** + * Name: erbium_setuartint + * + * Description: + * Update the cached UART interrupt mask and the hardware enable register. + * + * Input Parameters: + * priv - UART register base and cached interrupt mask. + * ien - UART interrupt sources to enable. + * + * Returned Value: + * None. + * + * Assumptions/Limitations: + * The caller must serialize access to the cached interrupt mask. + * + ****************************************************************************/ + +static void erbium_setuartint(struct erbium_uart_s *priv, uint32_t ien) +{ + priv->ien = ien; + erbium_serialout(priv, ERBIUM_UART_IEN_OFFSET, ien); +} + +#ifndef CONFIG_SUPPRESS_UART_CONFIG + +/**************************************************************************** + * Name: erbium_enable_uart + * + * Description: + * Enable the UART peripheral through the system configuration register. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void erbium_enable_uart(void) +{ + modifyreg32(ERBIUM_SYSREG_SYSTEM_CONFIG, 0, + ERBIUM_SYSREG_UART_ENABLE); +} +#endif + +/**************************************************************************** + * Name: erbium_disableuartint + * + * Description: + * Disable all UART interrupt sources, optionally saving the old mask. + * + * Input Parameters: + * priv - UART register base and cached interrupt mask. + * ien - Optional location to save the previous interrupt mask. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void erbium_disableuartint(struct erbium_uart_s *priv, uint32_t *ien) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + if (ien != NULL) + { + *ien = priv->ien; + } + + erbium_setuartint(priv, 0); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: erbium_restoreuartint + * + * Description: + * Restore a previously saved UART interrupt mask. + * + * Input Parameters: + * priv - UART register base and cached interrupt mask. + * ien - Saved UART interrupt mask. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void erbium_restoreuartint(struct erbium_uart_s *priv, uint32_t ien) +{ + irqstate_t flags; + + flags = enter_critical_section(); + erbium_setuartint(priv, ien); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: erbium_putc + * + * Description: + * Wait for space in the transmit FIFO and write one character. + * + * Input Parameters: + * priv - UART register base and cached interrupt mask. + * ch - Character to transmit; only the low eight bits are used. + * + * Returned Value: + * None. + * + * Assumptions/Limitations: + * The caller must serialize access to the transmit FIFO. + * + ****************************************************************************/ + +static void erbium_putc(struct erbium_uart_s *priv, int ch) +{ + while ((erbium_serialin(priv, ERBIUM_UART_STATUS_OFFSET) & + ERBIUM_UART_STATUS_TX_FULL) != 0) + { + } + + erbium_serialout(priv, ERBIUM_UART_TX_OFFSET, (uint32_t)ch & 0xffu); +} + +/**************************************************************************** + * Name: erbium_setup + * + * Description: + * Configure the UART for 8N1 operation and apply its interrupt mask. + * Preserve the existing line configuration when UART setup is suppressed. + * + * Input Parameters: + * dev - Serial lower-half device. + * + * Returned Value: + * OK. + * + ****************************************************************************/ + +static int erbium_setup(struct uart_dev_s *dev) +{ + struct erbium_uart_s *priv = (struct erbium_uart_s *)dev->priv; + +#ifndef CONFIG_SUPPRESS_UART_CONFIG + erbium_enable_uart(); + erbium_serialout(priv, ERBIUM_UART_BAUD_OFFSET, ERBIUM_UART_BAUD_DIV); + erbium_serialout(priv, ERBIUM_UART_CONTROL_OFFSET, + ERBIUM_UART_CONTROL_8N1); + erbium_serialout(priv, ERBIUM_UART_RX_THRESHOLD_OFFSET, 0); +#endif + erbium_setuartint(priv, priv->ien); + + return OK; +} + +/**************************************************************************** + * Name: erbium_shutdown + * + * Description: + * Disable UART interrupts when the serial device is closed. + * + * Input Parameters: + * dev - Serial lower-half device. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void erbium_shutdown(struct uart_dev_s *dev) +{ + struct erbium_uart_s *priv = (struct erbium_uart_s *)dev->priv; + + erbium_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: erbium_attach + * + * Description: + * Attach the UART interrupt handler and enable its PLIC source. + * + * Input Parameters: + * dev - Serial lower-half device. + * + * Returned Value: + * OK on success; a negated errno value from irq_attach() on failure. + * + ****************************************************************************/ + +static int erbium_attach(struct uart_dev_s *dev) +{ + struct erbium_uart_s *priv = (struct erbium_uart_s *)dev->priv; + int ret; + + ret = irq_attach(priv->irq, erbium_interrupt, dev); + + if (ret == OK) + { + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: erbium_detach + * + * Description: + * Disable the UART PLIC source and detach its interrupt handler. + * + * Input Parameters: + * dev - Serial lower-half device. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void erbium_detach(struct uart_dev_s *dev) +{ + struct erbium_uart_s *priv = (struct erbium_uart_s *)dev->priv; + + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: erbium_interrupt + * + * Description: + * Service enabled receive and transmit events through the serial upper + * half. Limit the number of passes so a persistent event cannot trap the + * CPU in this handler indefinitely. + * + * Input Parameters: + * irq - NuttX interrupt number. + * context - Saved interrupt context. + * arg - Serial device supplied when the handler was attached. + * + * Returned Value: + * OK. + * + ****************************************************************************/ + +static int erbium_interrupt(int irq, void *context, void *arg) +{ + struct uart_dev_s *dev = (struct uart_dev_s *)arg; + struct erbium_uart_s *priv; + uint32_t pending; + int passes; + + DEBUGASSERT(dev != NULL && dev->priv != NULL); + priv = (struct erbium_uart_s *)dev->priv; + + for (passes = 0; passes < 256; passes++) + { + pending = erbium_serialin(priv, ERBIUM_UART_STATUS_OFFSET) & priv->ien; + + if (pending == 0) + { + break; + } + + if ((pending & ERBIUM_UART_IEN_RX_NOT_EMPTY) != 0) + { + uart_recvchars(dev); + } + + if ((pending & ERBIUM_UART_IEN_TX_EMPTY) != 0) + { + uart_xmitchars(dev); + } + } + + return OK; +} + +/**************************************************************************** + * Name: erbium_ioctl + * + * Description: + * Reject unsupported device-specific control requests. + * + * Input Parameters: + * filep - Open serial device file. + * cmd - Requested control operation. + * arg - Operation-specific argument. + * + * Returned Value: + * -ENOTTY; this driver implements no device-specific ioctl commands. + * + ****************************************************************************/ + +static int erbium_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: erbium_receive + * + * Description: + * Read one character from the receive FIFO and optionally report status. + * + * Input Parameters: + * dev - Serial lower-half device. + * status - Optional location to save the UART status register. + * + * Returned Value: + * The received byte, in the range 0 through 255. + * + * Assumptions/Limitations: + * The serial upper half has established that receive data is available. + * + ****************************************************************************/ + +static int erbium_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct erbium_uart_s *priv = (struct erbium_uart_s *)dev->priv; + + if (status != NULL) + { + *status = erbium_serialin(priv, ERBIUM_UART_STATUS_OFFSET); + } + + return (int)(erbium_serialin(priv, ERBIUM_UART_RX_OFFSET) & 0xffu); +} + +/**************************************************************************** + * Name: erbium_rxint + * + * Description: + * Enable or disable receive interrupts. Honor suppression of serial + * interrupts during bring-up. + * + * Input Parameters: + * dev - Serial lower-half device. + * enable - True to enable reception interrupts; false to disable them. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void erbium_rxint(struct uart_dev_s *dev, bool enable) +{ + struct erbium_uart_s *priv = (struct erbium_uart_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + erbium_setuartint(priv, priv->ien | ERBIUM_UART_IEN_RX_NOT_EMPTY); +#endif + } + else + { + erbium_setuartint(priv, priv->ien & ~ERBIUM_UART_IEN_RX_NOT_EMPTY); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: erbium_rxavailable + * + * Description: + * Check whether the UART receive FIFO contains data. + * + * Input Parameters: + * dev - Serial lower-half device. + * + * Returned Value: + * True if at least one character is available; otherwise false. + * + ****************************************************************************/ + +static bool erbium_rxavailable(struct uart_dev_s *dev) +{ + struct erbium_uart_s *priv = (struct erbium_uart_s *)dev->priv; + + return (erbium_serialin(priv, ERBIUM_UART_STATUS_OFFSET) & + ERBIUM_UART_STATUS_RX_NOT_EMPTY) != 0; +} + +/**************************************************************************** + * Name: erbium_send + * + * Description: + * Transmit one character from the serial upper half. + * + * Input Parameters: + * dev - Serial lower-half device. + * ch - Character to transmit. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void erbium_send(struct uart_dev_s *dev, int ch) +{ + struct erbium_uart_s *priv = (struct erbium_uart_s *)dev->priv; + + erbium_putc(priv, ch); +} + +/**************************************************************************** + * Name: erbium_txint + * + * Description: + * Enable or disable transmit interrupts. Prime the transmit FIFO when + * enabling interrupts, unless serial interrupts are suppressed. + * + * Input Parameters: + * dev - Serial lower-half device. + * enable - True to enable transmission interrupts; false to disable. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void erbium_txint(struct uart_dev_s *dev, bool enable) +{ + struct erbium_uart_s *priv = (struct erbium_uart_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + erbium_setuartint(priv, priv->ien | ERBIUM_UART_IEN_TX_EMPTY); + uart_xmitchars(dev); +#endif + } + else + { + erbium_setuartint(priv, priv->ien & ~ERBIUM_UART_IEN_TX_EMPTY); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: erbium_txready + * + * Description: + * Check whether the transmit FIFO has room for another character. + * + * Input Parameters: + * dev - Serial lower-half device. + * + * Returned Value: + * True if the transmit FIFO is not full; otherwise false. + * + ****************************************************************************/ + +static bool erbium_txready(struct uart_dev_s *dev) +{ + struct erbium_uart_s *priv = (struct erbium_uart_s *)dev->priv; + + return (erbium_serialin(priv, ERBIUM_UART_STATUS_OFFSET) & + ERBIUM_UART_STATUS_TX_FULL) == 0; +} + +/**************************************************************************** + * Name: erbium_txempty + * + * Description: + * Check whether the UART transmit FIFO is empty. + * + * Input Parameters: + * dev - Serial lower-half device. + * + * Returned Value: + * True if the transmit FIFO is empty; otherwise false. + * + ****************************************************************************/ + +static bool erbium_txempty(struct uart_dev_s *dev) +{ + struct erbium_uart_s *priv = (struct erbium_uart_s *)dev->priv; + + return (erbium_serialin(priv, ERBIUM_UART_STATUS_OFFSET) & + ERBIUM_UART_STATUS_TX_EMPTY) != 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: riscv_earlyserialinit + * + * Description: + * Prepare UART0 for early console output with UART interrupts disabled. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void riscv_earlyserialinit(void) +{ + erbium_disableuartint(&g_uart0priv, NULL); + erbium_setup(&g_uart0port); +} + +/**************************************************************************** + * Name: riscv_serialinit + * + * Description: + * Register UART0 as ttyS0 and, when selected, as the system console. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void riscv_serialinit(void) +{ +#ifdef CONFIG_UART0_SERIAL_CONSOLE + uart_register("/dev/console", &g_uart0port); +#endif + + uart_register("/dev/ttyS0", &g_uart0port); +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Write one low-level console character while preserving the UART + * interrupt mask and the caller's interrupt state. + * + * Input Parameters: + * ch - Character to transmit. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_putc(int ch) +{ + irqstate_t flags; + uint32_t ien; + + flags = enter_critical_section(); + erbium_disableuartint(&g_uart0priv, &ien); + erbium_putc(&g_uart0priv, ch); + erbium_restoreuartint(&g_uart0priv, ien); + leave_critical_section(flags); +} diff --git a/arch/risc-v/src/erbium/erbium_start.c b/arch/risc-v/src/erbium/erbium_start.c new file mode 100644 index 00000000000..c5aac2e734c --- /dev/null +++ b/arch/risc-v/src/erbium/erbium_start.c @@ -0,0 +1,79 @@ +/**************************************************************************** + * arch/risc-v/src/erbium/erbium_start.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 "riscv_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: erbium_start + * + * Description: + * Start NuttX on hart 0. The emulator loads initialized data from the ELF + * directly into MRAM, so no ROM-to-RAM data copy is necessary. + * + * Input Parameters: + * None. + * + * Returned Value: + * Does not return. + * + * Assumptions/Limitations: + * Assembly startup has initialized the stack, global pointer and trap + * vector, with interrupts disabled. + * + ****************************************************************************/ + +void erbium_start(void) +{ + uint32_t *dest; + + for (dest = (uint32_t *)_sbss; dest < (uint32_t *)_ebss; ) + { + *dest++ = 0; + } + +#ifdef CONFIG_ARCH_FPU + /* Erbium traps FENCE.I to microcode. The ELF loader has already installed + * the image, so initialize the FPU without the common FENCE.I sequence. + */ + + SET_CSR(CSR_STATUS, MSTATUS_FS_INIT); + WRITE_CSR(CSR_FCSR, 0); +#endif + +#ifdef USE_EARLYSERIALINIT + riscv_earlyserialinit(); +#endif + + nx_start(); +} diff --git a/arch/risc-v/src/erbium/erbium_timerisr.c b/arch/risc-v/src/erbium/erbium_timerisr.c new file mode 100644 index 00000000000..8463298cc9f --- /dev/null +++ b/arch/risc-v/src/erbium/erbium_timerisr.c @@ -0,0 +1,68 @@ +/**************************************************************************** + * arch/risc-v/src/erbium/erbium_timerisr.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 "hardware/erbium_mtimer.h" +#include "riscv_internal.h" +#include "riscv_mtimer.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_timer_initialize + * + * Description: + * Register the common RISC-V machine timer as the system alarm source. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + struct oneshot_lowerhalf_s *lower; + + lower = riscv_mtimer_initialize(ERBIUM_MTIMER_MTIME, + ERBIUM_MTIMER_MTIMECMP, + RISCV_IRQ_MTIMER, + ERBIUM_MTIMER_FREQ); + + DEBUGASSERT(lower); + + up_alarm_set_lowerhalf(lower); +} diff --git a/arch/risc-v/src/erbium/hardware/erbium_memorymap.h b/arch/risc-v/src/erbium/hardware/erbium_memorymap.h new file mode 100644 index 00000000000..a1edcd3d038 --- /dev/null +++ b/arch/risc-v/src/erbium/hardware/erbium_memorymap.h @@ -0,0 +1,36 @@ +/**************************************************************************** + * arch/risc-v/src/erbium/hardware/erbium_memorymap.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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_ERBIUM_HARDWARE_ERBIUM_MEMORYMAP_H +#define __ARCH_RISCV_SRC_ERBIUM_HARDWARE_ERBIUM_MEMORYMAP_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ERBIUM_SYSREG_BASE 0x02000000ul +#define ERBIUM_UART0_BASE 0x02004000ul +#define ERBIUM_MTIMECMP_BASE 0x80f40208ul +#define ERBIUM_MTIME_BASE 0x80f40200ul +#define ERBIUM_PLIC_BASE 0xa0000000ul + +#endif /* __ARCH_RISCV_SRC_ERBIUM_HARDWARE_ERBIUM_MEMORYMAP_H */ diff --git a/arch/risc-v/src/erbium/hardware/erbium_mtimer.h b/arch/risc-v/src/erbium/hardware/erbium_mtimer.h new file mode 100644 index 00000000000..0f4ba84fb12 --- /dev/null +++ b/arch/risc-v/src/erbium/hardware/erbium_mtimer.h @@ -0,0 +1,40 @@ +/**************************************************************************** + * arch/risc-v/src/erbium/hardware/erbium_mtimer.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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_ERBIUM_HARDWARE_ERBIUM_MTIMER_H +#define __ARCH_RISCV_SRC_ERBIUM_HARDWARE_ERBIUM_MTIMER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "hardware/erbium_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ERBIUM_MTIMER_FREQ CONFIG_ERBIUM_MTIMER_FREQ +#define ERBIUM_MTIMER_MTIME ERBIUM_MTIME_BASE +#define ERBIUM_MTIMER_MTIMECMP ERBIUM_MTIMECMP_BASE + +#endif /* __ARCH_RISCV_SRC_ERBIUM_HARDWARE_ERBIUM_MTIMER_H */ diff --git a/arch/risc-v/src/erbium/hardware/erbium_plic.h b/arch/risc-v/src/erbium/hardware/erbium_plic.h new file mode 100644 index 00000000000..8c4d3e7ce61 --- /dev/null +++ b/arch/risc-v/src/erbium/hardware/erbium_plic.h @@ -0,0 +1,45 @@ +/**************************************************************************** + * arch/risc-v/src/erbium/hardware/erbium_plic.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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_ERBIUM_HARDWARE_ERBIUM_PLIC_H +#define __ARCH_RISCV_SRC_ERBIUM_HARDWARE_ERBIUM_PLIC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "hardware/erbium_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ERBIUM_PLIC_NSOURCE 7 +#define ERBIUM_PLIC_NDEV (ERBIUM_PLIC_NSOURCE - 1) + +#define ERBIUM_PLIC_PRIORITY (ERBIUM_PLIC_BASE + 0x000000) +#define ERBIUM_PLIC_PENDING (ERBIUM_PLIC_BASE + 0x001000) +#define ERBIUM_PLIC_ENABLE1 (ERBIUM_PLIC_BASE + 0x002000) +#define ERBIUM_PLIC_THRESHOLD (ERBIUM_PLIC_BASE + 0x200000) +#define ERBIUM_PLIC_CLAIM (ERBIUM_PLIC_BASE + 0x200004) + +#endif /* __ARCH_RISCV_SRC_ERBIUM_HARDWARE_ERBIUM_PLIC_H */ diff --git a/arch/risc-v/src/erbium/hardware/erbium_sysreg.h b/arch/risc-v/src/erbium/hardware/erbium_sysreg.h new file mode 100644 index 00000000000..0f35ff22d20 --- /dev/null +++ b/arch/risc-v/src/erbium/hardware/erbium_sysreg.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * arch/risc-v/src/erbium/hardware/erbium_sysreg.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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_ERBIUM_HARDWARE_ERBIUM_SYSREG_H +#define __ARCH_RISCV_SRC_ERBIUM_HARDWARE_ERBIUM_SYSREG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "hardware/erbium_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ERBIUM_SYSREG_SYSTEM_CONFIG (ERBIUM_SYSREG_BASE + 0x08) +#define ERBIUM_SYSREG_UART_ENABLE (1u << 6) + +#endif /* __ARCH_RISCV_SRC_ERBIUM_HARDWARE_ERBIUM_SYSREG_H */ diff --git a/arch/risc-v/src/erbium/hardware/erbium_uart.h b/arch/risc-v/src/erbium/hardware/erbium_uart.h new file mode 100644 index 00000000000..031d2e5562a --- /dev/null +++ b/arch/risc-v/src/erbium/hardware/erbium_uart.h @@ -0,0 +1,48 @@ +/**************************************************************************** + * arch/risc-v/src/erbium/hardware/erbium_uart.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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_ERBIUM_HARDWARE_ERBIUM_UART_H +#define __ARCH_RISCV_SRC_ERBIUM_HARDWARE_ERBIUM_UART_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Shakti UART registers on the Erbium peripheral bus. */ + +#define ERBIUM_UART_BAUD_OFFSET 0x00 +#define ERBIUM_UART_TX_OFFSET 0x08 +#define ERBIUM_UART_RX_OFFSET 0x10 +#define ERBIUM_UART_STATUS_OFFSET 0x18 +#define ERBIUM_UART_CONTROL_OFFSET 0x28 +#define ERBIUM_UART_IEN_OFFSET 0x30 +#define ERBIUM_UART_RX_THRESHOLD_OFFSET 0x40 + +#define ERBIUM_UART_STATUS_TX_EMPTY (1u << 0) +#define ERBIUM_UART_STATUS_TX_FULL (1u << 1) +#define ERBIUM_UART_STATUS_RX_NOT_EMPTY (1u << 2) + +#define ERBIUM_UART_IEN_TX_EMPTY (1u << 0) +#define ERBIUM_UART_IEN_RX_NOT_EMPTY (1u << 2) +#define ERBIUM_UART_CONTROL_8N1 (8u << 5) + +#endif /* __ARCH_RISCV_SRC_ERBIUM_HARDWARE_ERBIUM_UART_H */ diff --git a/boards/Kconfig b/boards/Kconfig index bbbfa45b553..388f19bbd1a 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -1239,6 +1239,13 @@ config ARCH_BOARD_MAIX_BIT This is the board configuration for the port of NuttX to the Sipeed Maix Bit board. This board features the RISC-V K210 +config ARCH_BOARD_ERBIUM_MINION + bool "AIFoundry Erbium Minion" + depends on ARCH_CHIP_ERBIUM + ---help--- + This is the board configuration for the AIFoundry Erbium simulator + minion target. This board features an RV64IMFC Erbium hart. + config ARCH_BOARD_SMARTL_C906 bool "smartl evaluation board for C906" depends on ARCH_CHIP_C906 @@ -4032,6 +4039,7 @@ config ARCH_BOARD default "lpcxpresso-lpc54628" if ARCH_BOARD_LPCXPRESSO_LPC54628 default "lx_cpu" if ARCH_BOARD_LX_CPU default "maix-bit" if ARCH_BOARD_MAIX_BIT + default "minion" if ARCH_BOARD_ERBIUM_MINION default "smartl-c906" if ARCH_BOARD_SMARTL_C906 default "icicle" if ARCH_BOARD_ICICLE_MPFS default "m100pfsevp" if ARCH_BOARD_M100PFSEVP_MPFS @@ -5281,6 +5289,9 @@ endif if ARCH_BOARD_MAIX_BIT source "boards/risc-v/k210/maix-bit/Kconfig" endif +if ARCH_BOARD_ERBIUM_MINION +source "boards/risc-v/erbium/minion/Kconfig" +endif if ARCH_BOARD_SMARTL_C906 source "boards/risc-v/c906/smartl-c906/Kconfig" endif diff --git a/boards/risc-v/erbium/minion/CMakeLists.txt b/boards/risc-v/erbium/minion/CMakeLists.txt new file mode 100644 index 00000000000..027258fda2b --- /dev/null +++ b/boards/risc-v/erbium/minion/CMakeLists.txt @@ -0,0 +1,23 @@ +# ############################################################################## +# boards/risc-v/erbium/minion/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +# ############################################################################## + +add_subdirectory(src) diff --git a/boards/risc-v/erbium/minion/Kconfig b/boards/risc-v/erbium/minion/Kconfig new file mode 100644 index 00000000000..809c30996ca --- /dev/null +++ b/boards/risc-v/erbium/minion/Kconfig @@ -0,0 +1,10 @@ +# +# SPDX-License-Identifier: Apache-2.0 +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_BOARD_ERBIUM_MINION + +endif diff --git a/boards/risc-v/erbium/minion/cmake/Toolchain.cmake b/boards/risc-v/erbium/minion/cmake/Toolchain.cmake new file mode 100644 index 00000000000..1b1b845af12 --- /dev/null +++ b/boards/risc-v/erbium/minion/cmake/Toolchain.cmake @@ -0,0 +1,28 @@ +# ############################################################################## +# boards/risc-v/erbium/minion/cmake/Toolchain.cmake +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +# ############################################################################## + +# Erbium executes floating-point divide and square root in microcode, which this +# image does not provide. Use software helpers for those operations. + +if(CONFIG_ARCH_FPU) + add_compile_options(-mno-fdiv) +endif() diff --git a/boards/risc-v/erbium/minion/configs/nsh/defconfig b/boards/risc-v/erbium/minion/configs/nsh/defconfig new file mode 100644 index 00000000000..3f09839a999 --- /dev/null +++ b/boards/risc-v/erbium/minion/configs/nsh/defconfig @@ -0,0 +1,48 @@ +# +# 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_DISABLE_OS_API is not set +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="minion" +CONFIG_ARCH_BOARD_ERBIUM_MINION=y +CONFIG_ARCH_CHIP="erbium" +CONFIG_ARCH_CHIP_ERBIUM=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=400000 +CONFIG_BUILTIN=y +CONFIG_DEBUG_ASSERTIONS=y +CONFIG_DEBUG_ASSERTIONS_EXPRESSION=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_FS_PROCFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=4096 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_LIBM=y +CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6 +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=0 +CONFIG_RAM_SIZE=16776704 +CONFIG_RAM_START=0x40000200 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_YEAR=2026 +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_NSH_STACKSIZE=4096 +CONFIG_TESTING_OSTEST=y +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/risc-v/erbium/minion/configs/ostest/defconfig b/boards/risc-v/erbium/minion/configs/ostest/defconfig new file mode 100644 index 00000000000..413834d1be1 --- /dev/null +++ b/boards/risc-v/erbium/minion/configs/ostest/defconfig @@ -0,0 +1,45 @@ +# +# 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_DISABLE_OS_API is not set +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="minion" +CONFIG_ARCH_BOARD_ERBIUM_MINION=y +CONFIG_ARCH_CHIP="erbium" +CONFIG_ARCH_CHIP_ERBIUM=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARDCTL=y +CONFIG_BOARDCTL_MKRD=y +CONFIG_BOARD_LOOPSPERMSEC=400000 +CONFIG_BUILTIN=y +CONFIG_DEBUG_ASSERTIONS=y +CONFIG_DEBUG_ASSERTIONS_EXPRESSION=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_FS_PROCFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INIT_ENTRYPOINT="ostest_main" +CONFIG_INIT_STACKSIZE=3072 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_LIBM=y +CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6 +CONFIG_PREALLOC_TIMERS=0 +CONFIG_RAM_SIZE=16776704 +CONFIG_RAM_START=0x40000200 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_YEAR=2026 +CONFIG_TESTING_OSTEST=y +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/risc-v/erbium/minion/include/board.h b/boards/risc-v/erbium/minion/include/board.h new file mode 100644 index 00000000000..865933cc108 --- /dev/null +++ b/boards/risc-v/erbium/minion/include/board.h @@ -0,0 +1,35 @@ +/**************************************************************************** + * boards/risc-v/erbium/minion/include/board.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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_ERBIUM_MINION_INCLUDE_BOARD_H +#define __BOARDS_RISCV_ERBIUM_MINION_INCLUDE_BOARD_H + +#define LED_STARTED 0 +#define LED_HEAPALLOCATE 1 +#define LED_IRQSENABLED 2 +#define LED_STACKCREATED 3 +#define LED_INIRQ 4 +#define LED_SIGNAL 5 +#define LED_ASSERTION 6 +#define LED_PANIC 7 + +#endif /* __BOARDS_RISCV_ERBIUM_MINION_INCLUDE_BOARD_H */ diff --git a/boards/risc-v/erbium/minion/scripts/Make.defs b/boards/risc-v/erbium/minion/scripts/Make.defs new file mode 100644 index 00000000000..c4d0b779062 --- /dev/null +++ b/boards/risc-v/erbium/minion/scripts/Make.defs @@ -0,0 +1,47 @@ +############################################################################ +# boards/risc-v/erbium/minion/scripts/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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/common/Toolchain.defs + +# Erbium executes floating-point divide and square root in microcode, which +# this image does not provide. Use software helpers for those operations. + +ifeq ($(CONFIG_ARCH_FPU),y) + ARCHCPUFLAGS += -mno-fdiv +endif + +LDSCRIPT = ld.script +ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT) + +CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS) +CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +AFLAGS += $(CFLAGS) -D__ASSEMBLY__ + +CELFFLAGS = $(CFLAGS) +CXXELFFLAGS = $(CXXFLAGS) +LDELFFLAGS = --oformat elf64-littleriscv -r -e main +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/libelf/gnu-elf.ld) diff --git a/boards/risc-v/erbium/minion/scripts/ld.script b/boards/risc-v/erbium/minion/scripts/ld.script new file mode 100644 index 00000000000..907f788527a --- /dev/null +++ b/boards/risc-v/erbium/minion/scripts/ld.script @@ -0,0 +1,126 @@ +/**************************************************************************** + * boards/risc-v/erbium/minion/scripts/ld.script + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + +EXTERN(__start) +ENTRY(__start) + +PHDRS +{ + text PT_LOAD FLAGS(5); + data PT_LOAD FLAGS(6); +} + +SECTIONS +{ + /* The Erbium simulator reserves the first 512 bytes of MRAM. */ + . = CONFIG_RAM_START; + + .rom_start : { + _stext = .; + KEEP(*(.text.__start)) + } :text + + . = ALIGN(4); + + .exceptions : { + KEEP(*(.text.exceptions)) + } :text + + .text : { + *(.text) + *(.text.*) + *(.gnu.warning) + *(.stub) + *(.gnu.linkonce.t.*) + *(.init) + *(.fini) + _etext = .; + } :text + + .rodata : { + _srodata = .; + *(.rodata) + *(.rodata.*) + *(.srodata .srodata.*) + *(.gnu.linkonce.r*) + _erodata = .; + } :text + + .tdata : { + _stdata = ABSOLUTE(.); + *(.tdata .tdata.* .gnu.linkonce.td.*); + _etdata = ABSOLUTE(.); + } :data + + .tbss : { + _stbss = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon); + _etbss = ABSOLUTE(.); + } :data + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = .; + PROVIDE(__global_pointer$ = . + 0x800); + *(.data) + *(.data.*) + *(.sdata .sdata.*) + *(.gnu.linkonce.d*) + . = ALIGN(8); + _edata = .; + } :data + + .init_array : { + . = ALIGN(8); + _sinit = ABSOLUTE(.); + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP(*(.init_array .ctors)) + _einit = ABSOLUTE(.); + } :data + + .bss (NOLOAD) : { + . = ALIGN(8); + _sbss = .; + *(.bss) + *(.bss.*) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.b*) + *(COMMON) + . = ALIGN(16); + _ebss = .; + } :data + + ASSERT(_ebss + ALIGN(CONFIG_IDLETHREAD_STACKSIZE, 16) < CONFIG_RAM_END, + "Erbium image and idle stack exceed MRAM") + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/risc-v/erbium/minion/src/CMakeLists.txt b/boards/risc-v/erbium/minion/src/CMakeLists.txt new file mode 100644 index 00000000000..fe82c479a1d --- /dev/null +++ b/boards/risc-v/erbium/minion/src/CMakeLists.txt @@ -0,0 +1,27 @@ +# ############################################################################## +# boards/risc-v/erbium/minion/src/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +# ############################################################################## + +set(SRCS erbium_bringup.c) + +target_sources(board PRIVATE ${SRCS}) + +set_property(GLOBAL PROPERTY LD_SCRIPT "${NUTTX_BOARD_DIR}/scripts/ld.script") diff --git a/boards/risc-v/erbium/minion/src/Makefile b/boards/risc-v/erbium/minion/src/Makefile new file mode 100644 index 00000000000..c2273b40d94 --- /dev/null +++ b/boards/risc-v/erbium/minion/src/Makefile @@ -0,0 +1,27 @@ +############################################################################ +# boards/risc-v/erbium/minion/src/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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 = erbium_bringup.c + +include $(TOPDIR)/boards/Board.mk diff --git a/boards/risc-v/erbium/minion/src/erbium_bringup.c b/boards/risc-v/erbium/minion/src/erbium_bringup.c new file mode 100644 index 00000000000..8862fdc6a7c --- /dev/null +++ b/boards/risc-v/erbium/minion/src/erbium_bringup.c @@ -0,0 +1,67 @@ +/**************************************************************************** + * boards/risc-v/erbium/minion/src/erbium_bringup.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_late_initialize + * + * Description: + * Mount board filesystems after OS initialization and before the initial + * application starts. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARD_LATE_INITIALIZE +void board_late_initialize(void) +{ +#ifdef CONFIG_FS_PROCFS + int ret; + + ret = nx_mount(NULL, "/proc", "procfs", 0, NULL); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: procfs mount failed: %d\n", ret); + } +#endif +} +#endif diff --git a/boards/risc-v/erbium/minion/tools/test_emu.py b/boards/risc-v/erbium/minion/tools/test_emu.py new file mode 100644 index 00000000000..3befaf42c1c --- /dev/null +++ b/boards/risc-v/erbium/minion/tools/test_emu.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python3 +# boards/risc-v/erbium/minion/tools/test_emu.py +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. + +"""Exercise prebuilt Erbium NuttX images and record reproducible results.""" + +import argparse +import hashlib +import json +import re +import subprocess +import time +from pathlib import Path + +FAILURE = re.compile( + r"\bERROR\b|Assertion failed|ASSERTION|PANIC|riscv_exception:|Unhandled exception" + r"|nsh: .*?(?:failed|not found|invalid)" + r"|ostest_main: Exiting with status -?[1-9]", + re.I, +) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--emu", type=Path, required=True) + parser.add_argument("--elf", type=Path, required=True) + parser.add_argument("--mode", choices=["nsh", "ostest"], required=True) + parser.add_argument("--output", type=Path, required=True) + parser.add_argument("--timeout", type=int, default=14400) + parser.add_argument("--max-cycles", default="100000000000") + parser.add_argument("--extra-harts", action="store_true") + args = parser.parse_args() + if args.timeout <= 0: + parser.error("--timeout must be positive") + for path in (args.emu, args.elf): + if not path.is_file(): + parser.error(f"Input file does not exist: {path}") + args.output.mkdir(parents=True, exist_ok=True) + uart = args.output / "uart.log" + emulator = args.output / "emulator.log" + uart.write_bytes(b"") + command = [ + str(args.emu.resolve()), + "-elf_load", + str(args.elf.resolve()), + "-reset_pc", + "0x40000200", + "-max_cycles", + args.max_cycles, + "-uart_tx_file", + str(uart.resolve()), + "-mem_reset", + "165", + ] + if args.extra_harts: + command += ["-minions", "3"] + else: + command += ["-single_thread"] + start = time.monotonic() + deadline = start + args.timeout + proc = None + checks = [] + failure = None + try: + with emulator.open("wb") as log: + proc = subprocess.Popen( + command, stdin=subprocess.PIPE, stdout=log, stderr=log + ) + + def wait_for(needle, offset=0): + while True: + output = uart.read_text(errors="replace") if uart.exists() else "" + if FAILURE.search(output): + raise RuntimeError("Guest reported a failure; inspect uart.log") + if needle in output[offset:]: + return output + if proc.poll() is not None: + raise RuntimeError( + f"Emulator exited with {proc.returncode} before {needle!r}" + ) + if time.monotonic() >= deadline: + raise TimeoutError(f"Timed out waiting for {needle!r}") + time.sleep(0.1) + + if args.mode == "ostest": + text = wait_for("ostest_main: Exiting with status 0") + if "Final memory usage:" not in text: + raise RuntimeError("Missing final memory report") + for marker in [ + "user_main: Exiting", + "FPU#1: Succeeded", + "FPU#2: Succeeded", + "user_main: semaphore test", + "user_main: signal handler test", + "user_main: pthread_exit() test", + "wqueue_test: teardown done", + ]: + if marker.lower() not in text.lower(): + raise RuntimeError( + f"Missing expected ostest coverage: {marker}" + ) + checks.append("Complete ostest, including FPU context switching") + else: + text = wait_for("nsh> ") + checks.append("NSH boot") + + def run_command(command_text, expected=None): + nonlocal text + offset = len(text) + # The emulator drains host input into a finite RX FIFO. + # Wait for each echoed character to avoid overrunning it. + for i, char in enumerate(command_text): + proc.stdin.write(char.encode()) + proc.stdin.flush() + wait_for(command_text[: i + 1], offset) + proc.stdin.write(b"\n") + proc.stdin.flush() + text = wait_for("nsh> ", offset) + response = text[offset:].split("\n", 1)[-1] + if expected and expected not in response: + raise RuntimeError( + f"Missing {expected!r} in response to {command_text!r}" + ) + checks.append(command_text) + return response + + def uptime(): + response = run_command("cat /proc/uptime") + match = re.search(r"^\s*(\d+\.\d+)\s*$", response, re.M) + if not match: + raise RuntimeError("Missing numeric procfs uptime") + return float(match[1]) + + for command_text, expected in [ + ("uname -a", "risc-v"), + ("help", "uname"), + ("ps", "Idle_Task"), + ]: + run_command(command_text, expected) + + before = uptime() + run_command("sleep 1") + if uptime() - before < 0.99: + raise RuntimeError("Guest uptime did not advance by one second") + checks.append("Timer advances during sleep") + run_command("echo ERBIUM_UART_TIMER_OK", "ERBIUM_UART_TIMER_OK") + run_command("free", "total") + time.sleep(0.5) + run_command("echo ERBIUM_LATE_RX_OK", "ERBIUM_LATE_RX_OK") + checks.append("UART RX after idle") + except (Exception, KeyboardInterrupt) as error: + failure = str(error) or type(error).__name__ + finally: + if proc is not None and proc.poll() is None: + proc.terminate() + try: + proc.wait(timeout=5) + except subprocess.TimeoutExpired: + proc.kill() + proc.wait(timeout=5) + result = { + "passed": failure is None, + "error": failure, + "checks": checks, + "command": command, + "duration_seconds": time.monotonic() - start, + "elf_sha256": hashlib.sha256(args.elf.read_bytes()).hexdigest(), + "emulator_sha256": hashlib.sha256(args.emu.read_bytes()).hexdigest(), + "emulator_returncode": None if proc is None else proc.returncode, + } + if failure is None and re.search( + r": (ERROR|FATAL) ", emulator.read_text(errors="replace") + ): + failure = "Emulator reported an error; inspect emulator.log" + result["passed"] = False + result["error"] = failure + (args.output / "result.json").write_text(json.dumps(result, indent=2) + "\n") + print(json.dumps(result, indent=2), flush=True) + return 1 if failure else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tools/ci/testlist/risc-v-01.dat b/tools/ci/testlist/risc-v-01.dat index b652e87160d..2ea92fae06b 100644 --- a/tools/ci/testlist/risc-v-01.dat +++ b/tools/ci/testlist/risc-v-01.dat @@ -1,3 +1,7 @@ /risc-v/[a-d]* /risc-v/e[0-r]* -bl602evb:elf + +# Erbium also supports the CMake build. +CMake,minion:nsh +CMake,minion:ostest