diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index 1eecc6d55e..68e97d4da8 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -61,6 +61,12 @@ config ARCH_CHIP_ESP32C3 ---help--- Espressif ESP32-C3 (RV32IMC). +config ARCH_CHIP_C906 + bool "THEAD C906" + select ARCH_RV64GC + ---help--- + THEAD C906 processor (RISC-V 64bit core with GCVX extensions). + config ARCH_CHIP_RISCV_CUSTOM bool "Custom RISC-V chip" select ARCH_CHIP_CUSTOM @@ -99,6 +105,7 @@ config ARCH_CHIP default "gap8" if ARCH_CHIP_GAP8 default "bl602" if ARCH_CHIP_BL602 default "esp32c3" if ARCH_CHIP_ESP32C3 + default "c906" if ARCH_CHIP_C906 config NR5_MPU bool "MPU support" @@ -137,4 +144,7 @@ endif if ARCH_CHIP_ESP32C3 source arch/risc-v/src/esp32c3/Kconfig endif +if ARCH_CHIP_C906 +source arch/risc-v/src/c906/Kconfig +endif endif diff --git a/arch/risc-v/include/c906/chip.h b/arch/risc-v/include/c906/chip.h new file mode 100644 index 0000000000..b284b620af --- /dev/null +++ b/arch/risc-v/include/c906/chip.h @@ -0,0 +1,34 @@ +/**************************************************************************** + * arch/risc-v/include/c906/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_C906_CHIP_H +#define __ARCH_RISCV_INCLUDE_C906_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include + +#endif /* __ARCH_RISCV_INCLUDE_C906_CHIP_H */ diff --git a/arch/risc-v/include/c906/irq.h b/arch/risc-v/include/c906/irq.h new file mode 100644 index 0000000000..a670d7c3b1 --- /dev/null +++ b/arch/risc-v/include/c906/irq.h @@ -0,0 +1,107 @@ +/**************************************************************************** + * arch/risc-v/include/c906/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_C906_IRQ_H +#define __ARCH_RISCV_INCLUDE_C906_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Map RISC-V exception code to NuttX IRQ */ + +/* IRQ 0-15 : (exception:interrupt=0) */ + +#define C906_IRQ_IAMISALIGNED (0) /* Instruction Address Misaligned */ +#define C906_IRQ_IAFAULT (1) /* Instruction Address Fault */ +#define C906_IRQ_IINSTRUCTION (2) /* Illegal Instruction */ +#define C906_IRQ_BPOINT (3) /* Break Point */ +#define C906_IRQ_LAMISALIGNED (4) /* Load Address Misaligned */ +#define C906_IRQ_LAFAULT (5) /* Load Access Fault */ +#define C906_IRQ_SAMISALIGNED (6) /* Store/AMO Address Misaligned */ +#define C906_IRQ_SAFAULT (7) /* Store/AMO Access Fault */ +#define C906_IRQ_ECALLU (8) /* Environment Call from U-mode */ + +#define C906_IRQ_ECALLM (11) /* Environment Call from M-mode */ + +/* IRQ 16- : (async event:interrupt=1) */ + +#define C906_IRQ_ASYNC (16) +#define C906_IRQ_SSOFT (C906_IRQ_ASYNC + 1) /* Supervisor Software Int */ +#define C906_IRQ_MSOFT (C906_IRQ_ASYNC + 3) /* Machine Software Int */ +#define C906_IRQ_STIMER (C906_IRQ_ASYNC + 5) /* Supervisor Timer Int */ +#define C906_IRQ_MTIMER (C906_IRQ_ASYNC + 7) /* Machine Timer Int */ +#define C906_IRQ_SEXT (C906_IRQ_ASYNC + 9) /* Supervisor External Int */ +#define C906_IRQ_MEXT (C906_IRQ_ASYNC + 11) /* Machine External Int */ +#define C906_IRQ_HPMOV (C906_IRQ_ASYNC + 17) /* HPM Overflow Int */ + +/* Machine Global External Interrupt */ + +#define C906_IRQ_PERI_START (C906_IRQ_ASYNC + 18) + +#ifdef CONFIG_C906_WITH_QEMU +#define C906_IRQ_UART0 (C906_IRQ_PERI_START + 32) +#else +#define C906_IRQ_UART0 (C906_IRQ_PERI_START + 32) +#endif + +/* Total number of IRQs */ + +#define NR_IRQS (C906_IRQ_UART0 + 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_C906_IRQ_H */ diff --git a/arch/risc-v/src/c906/Kconfig b/arch/risc-v/src/c906/Kconfig new file mode 100644 index 0000000000..412f80957a --- /dev/null +++ b/arch/risc-v/src/c906/Kconfig @@ -0,0 +1,36 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "C906 Configuration Options" + +menu "C906 Peripheral Support" + +# These "hidden" settings determine whether a peripheral option is available +# for the selected MCU + +config C906_HAVE_UART0 + bool + default y + select UART0_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS + +# These are the peripheral selections proper + +config C906_UART0 + bool "UART0" + default y + select ARCH_HAVE_UART0 + select ARCH_HAVE_SERIAL_TERMIOS + select C906_UART + +endmenu + +menu "C906 Others" + +config C906_WITH_QEMU + bool "qemu support" + default n + +endmenu diff --git a/arch/risc-v/src/c906/Make.defs b/arch/risc-v/src/c906/Make.defs new file mode 100644 index 0000000000..44b193dcd5 --- /dev/null +++ b/arch/risc-v/src/c906/Make.defs @@ -0,0 +1,58 @@ +############################################################################ +# arch/risc-v/src/c906/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 = c906_vectors.S + +# Specify our general Assembly files +CHIP_ASRCS = c906_head.S + +# Specify C code within the common directory to be included +CMN_CSRCS += riscv_initialize.c riscv_swint.c +CMN_CSRCS += riscv_allocateheap.c riscv_createstack.c riscv_exit.c riscv_fault.c +CMN_CSRCS += riscv_assert.c riscv_blocktask.c riscv_copystate.c riscv_initialstate.c +CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c +CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c +CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c +CMN_CSRCS += riscv_sigdeliver.c riscv_unblocktask.c riscv_usestack.c +CMN_CSRCS += riscv_mdelay.c riscv_copyfullstate.c + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += riscv_checkstack.c +endif + +ifeq ($(CONFIG_ARCH_HAVE_VFORK),y) +CMN_CSRCS += riscv_vfork.c +endif + +# Specify our C code within this directory to be included +CHIP_CSRCS = c906_allocateheap.c c906_clockconfig.c +CHIP_CSRCS += c906_idle.c c906_irq.c c906_irq_dispatch.c +CHIP_CSRCS += c906_lowputc.c c906_serial.c +CHIP_CSRCS += c906_start.c c906_timerisr.c + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += riscv_task_start.c riscv_pthread_start.c +CMN_CSRCS += riscv_signal_dispatch.c +CMN_UASRCS += riscv_signal_handler.S + +CHIP_CSRCS += c906_userspace.c +endif diff --git a/arch/risc-v/src/c906/c906.h b/arch/risc-v/src/c906/c906.h new file mode 100644 index 0000000000..4984e8aedb --- /dev/null +++ b/arch/risc-v/src/c906/c906.h @@ -0,0 +1,38 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906.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_C906_C906_H +#define __ARCH_RISCV_SRC_C906_C906_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include +#include "riscv_internal.h" +#include "chip.h" +#include "c906_lowputc.h" + +#endif /* __ARCH_RISCV_SRC_C906_C906_H */ diff --git a/arch/risc-v/src/c906/c906_allocateheap.c b/arch/risc-v/src/c906/c906_allocateheap.c new file mode 100644 index 0000000000..04e587a6c7 --- /dev/null +++ b/arch/risc-v/src/c906/c906_allocateheap.c @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_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 + +#include + +#include "c906.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SRAM1_END CONFIG_RAM_END + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_kheap + * + * Description: + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates + * (and protects) the kernel-space heap. + * + ****************************************************************************/ + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) +void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) +{ + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend; + ubase += CONFIG_MM_KERNEL_HEAPSIZE; + + size_t usize = SRAM1_END - ubase; + + DEBUGASSERT(ubase < (uintptr_t)SRAM1_END); + + /* TODO: Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the SRAM1_END + * is aligned to the MPU requirement. + */ + + ubase = SRAM1_END - usize; + + /* Return the kernel heap settings (i.e., the part of the heap region + * that was not dedicated to the user heap). + */ + + *heap_start = (FAR void *)USERSPACE->us_bssend; + *heap_size = ubase - (uintptr_t)USERSPACE->us_bssend; +} +#endif + +/**************************************************************************** + * Name: up_addregion + ****************************************************************************/ + +void up_addregion(void) +{ +} diff --git a/arch/risc-v/src/c906/c906_clockconfig.c b/arch/risc-v/src/c906/c906_clockconfig.c new file mode 100644 index 0000000000..42bea8e8bc --- /dev/null +++ b/arch/risc-v/src/c906/c906_clockconfig.c @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_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 "riscv_arch.h" +#include "c906_clockconfig.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define OSC_FREQ 20000000UL + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint64_t g_cpu_clock = OSC_FREQ; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: c906_get_cpuclk + ****************************************************************************/ + +uint64_t c906_get_cpuclk(void) +{ + return g_cpu_clock; +} + +/**************************************************************************** + * Name: c906_get_pll0clk + ****************************************************************************/ + +#ifndef CONFIG_C906_WITH_QEMU +uint64_t c906_get_pll0clk(void) +{ + return 0; +} +#endif + +/**************************************************************************** + * Name: c906_clockconfig + ****************************************************************************/ + +void c906_clockconfig(void) +{ +#ifndef CONFIG_C906_WITH_QEMU + +#endif +} diff --git a/arch/risc-v/src/c906/c906_clockconfig.h b/arch/risc-v/src/c906/c906_clockconfig.h new file mode 100644 index 0000000000..b67c1a0d83 --- /dev/null +++ b/arch/risc-v/src/c906/c906_clockconfig.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_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_C906_C906_CLOCKCONFIG_H +#define __ARCH_RISCV_SRC_C906_C906_CLOCKCONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "c906_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 uint64_t c906_get_cpuclk(void); +EXTERN uint64_t c906_get_pll0clk(void); +EXTERN void c906_clockconfig(void); + +#if defined(__cplusplus) +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_C906_C906_CLOCKCONFIG_H */ diff --git a/arch/risc-v/src/c906/c906_config.h b/arch/risc-v/src/c906/c906_config.h new file mode 100644 index 0000000000..25693eefc5 --- /dev/null +++ b/arch/risc-v/src/c906/c906_config.h @@ -0,0 +1,54 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_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_C906_C906_CONFIG_H +#define __ARCH_RISCV_SRC_C906_C906_CONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_C906_UART0) || defined(CONFIG_C906_UART1) +# define HAVE_UART_DEVICE 1 +#endif + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_C906_UART0) +# undef CONFIG_UART1_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_C906_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_C906_C906_CONFIG_H */ diff --git a/arch/risc-v/src/c906/c906_head.S b/arch/risc-v/src/c906/c906_head.S new file mode 100644 index 0000000000..5e6032906c --- /dev/null +++ b/arch/risc-v/src/c906/c906_head.S @@ -0,0 +1,251 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_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 + +#include "chip.h" + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .global exception_common + + /* Imported symbols */ + + .extern __trap_vec + + .section .text + .global __start + +__start: + +.option push +.option norelax + la gp, __global_pointer$ +.option pop + + /* invalid all MMU TLB Entry */ + + sfence.vma x0,x0 + + /* enable FPU if CFLAGS has 'f' or 'd' in -march */ + +#ifdef __riscv_xlen + li a0, MSTATUS_FS_INIT + csrs mstatus, a0 +#endif + + /* enable thead ISA extension: + * BIT22: enable the THEAD ISA extensions. + * BIT21: enable extended attributes in PTE. + * BIT15: enable misaligned address access. + * mxstatus is a CSR which locates at 0x7C0. + */ + +#ifdef __riscv_xthead + li t0, (1 << 22) | (1 << 21) | (1 << 15) + csrr t1, mxstatus + or t0, t1, t0 + csrw mxstatus, t0 +#endif + + /* Load mhartid (cpuid) */ + + csrr a0, mhartid + + /* Set stack pointer to the idle thread stack */ + + la sp, C906_IDLESTACK0_TOP + + /* Disable all interrupts (i.e. timer, external) in mie */ + + csrw mie, zero + csrw mip, zero + + /* Initialize the Machine Trap Vector */ + + la t0, __trap_vec + csrw mtvec, t0 + + /* Jump to __c906_start with mhartid */ + + j __c906_start + + /* We shouldn't return from __c906_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 + + sd x1, 1*8(sp) /* ra */ + + /* leave gp(x3) in 3*8(sp) untouched */ + + sd x4, 4*8(sp) /* tp */ + sd x5, 5*8(sp) /* t0 */ + sd x6, 6*8(sp) /* t1 */ + sd x7, 7*8(sp) /* t2 */ + sd x8, 8*8(sp) /* s0 */ + sd x9, 9*8(sp) /* s1 */ + sd x10, 10*8(sp) /* a0 */ + sd x11, 11*8(sp) /* a1 */ + sd x12, 12*8(sp) /* a2 */ + sd x13, 13*8(sp) /* a3 */ + sd x14, 14*8(sp) /* a4 */ + sd x15, 15*8(sp) /* a5 */ + sd x16, 16*8(sp) /* a6 */ + sd x17, 17*8(sp) /* a7 */ + sd x18, 18*8(sp) /* s2 */ + sd x19, 19*8(sp) /* s3 */ + sd x20, 20*8(sp) /* s4 */ + sd x21, 21*8(sp) /* s5 */ + sd x22, 22*8(sp) /* s6 */ + sd x23, 23*8(sp) /* s7 */ + sd x24, 24*8(sp) /* s8 */ + sd x25, 25*8(sp) /* s9 */ + sd x26, 26*8(sp) /* s10 */ + sd x27, 27*8(sp) /* s11 */ + sd x28, 28*8(sp) /* t3 */ + sd x29, 29*8(sp) /* t4 */ + sd x30, 30*8(sp) /* t5 */ + sd x31, 31*8(sp) /* t6 */ + + csrr s0, mstatus + sd s0, 32*8(sp) /* mstatus */ + + addi s0, sp, XCPTCONTEXT_SIZE + sd s0, 2*8(sp) /* original SP */ + + /* Setup arg0(exception cause), arg1(context) */ + + csrr a0, mcause /* exception cause */ + csrr s0, mepc + sd s0, 0(sp) /* exception PC */ + + mv a1, sp /* context = sp */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + /* Load mhartid (cpuid) */ + + csrr s0, mhartid + + /* Switch to interrupt stack */ + + bnez s0, 3f + la sp, g_intstackbase + j 4f +3: + la sp, g_intstackbase + addi sp, sp, -((CONFIG_ARCH_INTERRUPTSTACK) & ~7) +4: + +#endif + + /* Call interrupt handler in C */ + + jal x1, c906_dispatch_irq + + /* If context switch is needed, return a new sp */ + + mv sp, a0 + ld s0, 0(sp) /* restore mepc */ + csrw mepc, s0 + + ld s0, 32*8(sp) /* restore mstatus */ + csrw mstatus, s0 + + /* leave gp(x3) in 3*8(sp) untouched */ + + ld x4, 4*8(sp) /* tp */ + ld x5, 5*8(sp) /* t0 */ + ld x6, 6*8(sp) /* t1 */ + ld x7, 7*8(sp) /* t2 */ + ld x8, 8*8(sp) /* s0 */ + ld x9, 9*8(sp) /* s1 */ + ld x10, 10*8(sp) /* a0 */ + ld x11, 11*8(sp) /* a1 */ + ld x12, 12*8(sp) /* a2 */ + ld x13, 13*8(sp) /* a3 */ + ld x14, 14*8(sp) /* a4 */ + ld x15, 15*8(sp) /* a5 */ + ld x16, 16*8(sp) /* a6 */ + ld x17, 17*8(sp) /* a7 */ + ld x18, 18*8(sp) /* s2 */ + ld x19, 19*8(sp) /* s3 */ + ld x20, 20*8(sp) /* s4 */ + ld x21, 21*8(sp) /* s5 */ + ld x22, 22*8(sp) /* s6 */ + ld x23, 23*8(sp) /* s7 */ + ld x24, 24*8(sp) /* s8 */ + ld x25, 25*8(sp) /* s9 */ + ld x26, 26*8(sp) /* s10 */ + ld x27, 27*8(sp) /* s11 */ + ld x28, 28*8(sp) /* t3 */ + ld x29, 29*8(sp) /* t4 */ + ld x30, 30*8(sp) /* t5 */ + ld x31, 31*8(sp) /* t6 */ + + ld x1, 1*8(sp) /* ra */ + + ld sp, 2*8(sp) /* restore original sp */ + + /* Return from Machine Interrupt */ + + mret + +/************************************************************************************ + * Name: g_intstackalloc and g_intstackbase + ************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + .bss + .align 8 + .global g_intstackalloc + .global g_intstackbase + .type g_intstackalloc, object + .type g_intstackbase, object +g_intstackalloc: + .skip (((CONFIG_ARCH_INTERRUPTSTACK * 2) & ~7)) +g_intstackbase: + .skip 8 + .size g_intstackbase, 8 + .size g_intstackalloc, ((CONFIG_ARCH_INTERRUPTSTACK * 2) & ~7) +#endif diff --git a/arch/risc-v/src/c906/c906_idle.c b/arch/risc-v/src/c906/c906_idle.c new file mode 100644 index 0000000000..f0e6ac973b --- /dev/null +++ b/arch/risc-v/src/c906/c906_idle.c @@ -0,0 +1,65 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_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 "riscv_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/c906/c906_irq.c b/arch/risc-v/src/c906/c906_irq.c new file mode 100644 index 0000000000..57977ebddb --- /dev/null +++ b/arch/risc-v/src/c906/c906_irq.c @@ -0,0 +1,288 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_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 "riscv_internal.h" +#include "riscv_arch.h" + +#include "c906.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +volatile uint64_t *g_current_regs[1]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* Disable Machine interrupts */ + + up_irq_save(); + + /* enable access from supervisor mode */ + + putreg32(0x1, C906_PLIC_CTRL); + + /* Disable all global interrupts */ + + putreg32(0x0, C906_PLIC_MIE0); + putreg32(0x0, C906_PLIC_MIE1); + + /* Clear pendings in PLIC */ + + uint32_t val = getreg32(C906_PLIC_MCLAIM); + putreg32(val, C906_PLIC_MCLAIM); + + /* Colorize the interrupt stack for debug purposes */ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 7 + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~7); + up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), + intstack_size); +#endif + + /* Set priority for all global interrupts to 1 (lowest) */ + + int id; + + for (id = 1; id <= NR_IRQS; id++) + { + putreg32(1, (uintptr_t)(C906_PLIC_PRIORITY + (4 * id))); + } + + /* Set irq threshold to 0 (permits all global interrupts) */ + + putreg32(0, C906_PLIC_MTHRESHOLD); + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the ecall interrupt handler */ + + irq_attach(C906_IRQ_ECALLM, up_swint, NULL); + +#ifdef CONFIG_BUILD_PROTECTED + irq_attach(C906_IRQ_ECALLU, up_swint, NULL); +#endif + +#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 = 0; + uint64_t oldstat = 0; + + if (irq == C906_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 == C906_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 >= C906_IRQ_PERI_START) + { + extirq = irq - C906_IRQ_PERI_START; + + /* Clear enable bit for the irq */ + + if (0 <= extirq && extirq <= 63) + { + modifyreg32(C906_PLIC_MIE0 + (4 * (extirq / 32)), + 1 << (extirq % 32), 0); + } + else + { + ASSERT(false); + } + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + int extirq; + uint64_t oldstat; + + if (irq == C906_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 == C906_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 >= C906_IRQ_PERI_START) + { + extirq = irq - C906_IRQ_PERI_START; + + /* Set enable bit for the irq */ + + if (0 <= extirq && extirq <= 63) + { + modifyreg32(C906_PLIC_MIE0 + (4 * (extirq / 32)), + 0, 1 << (extirq % 32)); + } + 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. Reegardless of + * how NuttX is configured and of what kind of thread is being started. + * That is because all threads, even user-mode threads will start in + * kernel trampoline at nxtask_start() or pthread_start(). + * The thread's privileges will be dropped before transitioning to + * user code. Also set machine previous interrupt enable. + */ + + return (MSTATUS_FS_INIT | 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) +{ + uint64_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) +{ + uint64_t oldstat; + + /* Enable MEIE (machine external interrupt enable) */ + + /* TODO: should move to up_enable_irq() */ + + asm volatile ("csrrs %0, mie, %1": "=r" (oldstat) : "r"(MIE_MEIE)); + + /* 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/c906/c906_irq_dispatch.c b/arch/risc-v/src/c906/c906_irq_dispatch.c new file mode 100644 index 0000000000..ff40e5774b --- /dev/null +++ b/arch/risc-v/src/c906/c906_irq_dispatch.c @@ -0,0 +1,156 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_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 "riscv_arch.h" +#include "riscv_internal.h" + +#include "group/group.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern void up_fault(int irq, uint64_t *regs); + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * c906_dispatch_irq + ****************************************************************************/ + +void *c906_dispatch_irq(uint64_t vector, uint64_t *regs) +{ + uint32_t irq = (vector >> (27 + 32)) | (vector & 0xf); + uint64_t *mepc = regs; + + /* Check if fault happened */ + + if (vector < C906_IRQ_ECALLU) + { + up_fault((int)irq, regs); + } + + /* Firstly, check if the irq is machine external interrupt */ + + if (C906_IRQ_MEXT == irq) + { + uint32_t val = getreg32(C906_PLIC_MCLAIM); + + /* Add the value to nuttx irq which is offset to the mext */ + + irq = val + C906_IRQ_PERI_START; + } + + /* NOTE: In case of ecall, we need to adjust mepc in the context */ + + if (C906_IRQ_ECALLM == irq || C906_IRQ_ECALLU == 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; + * CURRENT_REGS is also used to manage interrupt level context switches. + * + * Nested interrupts are not supported + */ + + ASSERT(CURRENT_REGS == NULL); + CURRENT_REGS = regs; + + /* MEXT means no interrupt */ + + if (C906_IRQ_MEXT != irq) + { + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + } + + if (C906_IRQ_PERI_START <= irq) + { + /* Then write PLIC_CLAIM to clear pending in PLIC */ + + putreg32(irq - C906_IRQ_PERI_START, C906_PLIC_MCLAIM); + } + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * CURRENT_REGS will have a different value than it did on entry. If an + * interrupt level context switch has occurred, then restore the floating + * point state and the establish the correct address environment before + * returning from the interrupt. + */ + + if (regs != CURRENT_REGS) + { +#ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint64_t *)CURRENT_REGS); +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + group_addrenv(NULL); +#endif + } +#endif + +#endif + + /* If a context switch occurred while processing the interrupt then + * 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 = (uint64_t *)CURRENT_REGS; + CURRENT_REGS = NULL; + + return regs; +} diff --git a/arch/risc-v/src/c906/c906_lowputc.c b/arch/risc-v/src/c906/c906_lowputc.c new file mode 100644 index 0000000000..9b6c128827 --- /dev/null +++ b/arch/risc-v/src/c906/c906_lowputc.c @@ -0,0 +1,120 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_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 "riscv_internal.h" +#include "riscv_arch.h" + +#include "c906_config.h" +#include "hardware/c906_memorymap.h" +#include "hardware/c906_uart.h" +#include "c906_clockconfig.h" +#include "c906.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select UART parameters for the selected console */ + +#ifdef HAVE_SERIAL_CONSOLE +# if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define C906_CONSOLE_BASE C906_UART0_BASE +# define C906_CONSOLE_BAUD CONFIG_UART0_BAUD +# define C906_CONSOLE_BITS CONFIG_UART0_BITS +# define C906_CONSOLE_PARITY CONFIG_UART0_PARITY +# define C906_CONSOLE_2STOP CONFIG_UART0_2STOP +# define C906_CONSOLE_TX GPIO_UART0_TX +# define C906_CONSOLE_RX GPIO_UART0_RX +# define HAVE_UART +# elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define C906_CONSOLE_BASE C906_UART1_BASE +# define C906_CONSOLE_BAUD CONFIG_UART1_BAUD +# define C906_CONSOLE_BITS CONFIG_UART1_BITS +# define C906_CONSOLE_PARITY CONFIG_UART1_PARITY +# define C906_CONSOLE_2STOP CONFIG_UART1_2STOP +# define C906_CONSOLE_TX GPIO_UART1_TX +# define C906_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 ((!(getreg32(C906_UART0_LSR) & DW_LSR_TRANS_EMPTY))) + { + } + + /* Then send the character */ + + putreg32(ch, C906_UART0_TXDATA); + +#endif /* HAVE_CONSOLE */ +} + +/**************************************************************************** + * Name: c906_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 c906_lowsetup(void) +{ +#if defined(HAVE_UART) + + /* Enable and configure the selected console device */ + +#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + + /* Configure the UART Baud Rate */ + + /* Enable TX */ + +#endif /* HAVE_SERIAL_CONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */ +#endif /* HAVE_UART */ +} diff --git a/arch/risc-v/src/c906/c906_lowputc.h b/arch/risc-v/src/c906/c906_lowputc.h new file mode 100644 index 0000000000..9b028c9d8c --- /dev/null +++ b/arch/risc-v/src/c906/c906_lowputc.h @@ -0,0 +1,59 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_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_C906_C906_LOWPUTC_H +#define __ARCH_RISCV_SRC_C906_C906_LOWPUTC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: c906_lowsetup + ****************************************************************************/ + +EXTERN void c906_lowsetup(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_C906_C906_LOWPUTC_H */ diff --git a/arch/risc-v/src/c906/c906_memorymap.h b/arch/risc-v/src/c906/c906_memorymap.h new file mode 100644 index 0000000000..e416cc1906 --- /dev/null +++ b/arch/risc-v/src/c906/c906_memorymap.h @@ -0,0 +1,53 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_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_C906_C906_MEMORYMAP_H +#define _ARCH_RISCV_SRC_C906_C906_MEMORYMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "hardware/c906_memorymap.h" +#include "hardware/c906_uart.h" +#include "hardware/c906_clint.h" +#include "hardware/c906_plic.h" +#include "hardware/c906_sysctl.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Idle thread stack starts from _default_stack_limit */ + +#ifndef __ASSEMBLY__ +extern uintptr_t *_default_stack_limit; +#define C906_IDLESTACK_BASE (uintptr_t)&_default_stack_limit +#else +#define C906_IDLESTACK_BASE _default_stack_limit +#endif + +#define C906_IDLESTACK_SIZE (CONFIG_IDLETHREAD_STACKSIZE & ~7) + +#define C906_IDLESTACK0_TOP (C906_IDLESTACK_BASE + C906_IDLESTACK_SIZE) + +#define C906_IDLESTACK_TOP (C906_IDLESTACK0_TOP) + +#endif /* _ARCH_RISCV_SRC_C906_C906_MEMORYMAP_H */ diff --git a/arch/risc-v/src/c906/c906_serial.c b/arch/risc-v/src/c906/c906_serial.c new file mode 100644 index 0000000000..d073a06eb5 --- /dev/null +++ b/arch/risc-v/src/c906/c906_serial.c @@ -0,0 +1,742 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_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 "riscv_arch.h" +#include "riscv_internal.h" + +#include "c906_config.h" +#include "chip.h" +#include "c906.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* 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_C906_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_C906_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +static uint32_t g_rxdata; +#endif + +#ifdef CONFIG_C906_UART0 +static struct up_dev_s g_uart0priv = +{ + .uartbase = C906_UART0_BASE, + .baud = CONFIG_UART0_BAUD, + .irq = C906_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; + up_serialout(priv, UART_IE_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; + up_serialout(priv, UART_IE_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) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Enable RX */ + + up_serialout(priv, UART_RXCTL_OFFSET, + IER_RDA_INT_ENABLE | IIR_RECV_LINE_ENABLE); + + /* nothing to be done for QEMU */ + + 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 */ + + up_serialout(priv, UART_IE_OFFSET, + IER_RDA_INT_ENABLE | IER_THRE_INT_ENABLE); + + 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. + * + ****************************************************************************/ + +/* TODO: why no data ready flag LSR_DATA_READY in LSR under QEMU ??? */ +#ifdef CONFIG_C906_WITH_QEMU +static volatile uint32_t lsr_data_ready = 0; +#endif + +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_IIR_OFFSET); + + if (status == 0) + { + break; + } + + if (status & DW_IIR_RECV_DATA) + { + /* Process incoming bytes */ +#ifdef CONFIG_C906_WITH_QEMU + lsr_data_ready = 1; +#endif + uart_recvchars(dev); + } + + if (status & DW_IIR_THR_EMPTY) + { + /* Process outgoing bytes */ + + 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) +{ + /* Return status information */ + + if (status) + { + *status = 0; /* We are not yet tracking serial errors */ + } + + /* Return cached data */ + + return g_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 |= IER_RDA_INT_ENABLE; +#endif + } + else + { + priv->im &= ~IER_RDA_INT_ENABLE; + } + + up_serialout(priv, UART_IE_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; + uint32_t dr = 0; + + /* Return true is data is available in the receive data buffer */ + + uint32_t rxdata = up_serialin(priv, UART_RXDATA_OFFSET); + + g_rxdata = rxdata & 0xff; + +#ifdef CONFIG_C906_WITH_QEMU + dr = lsr_data_ready; + lsr_data_ready = 0; +#else + dr = up_serialin(priv, UART_LSR_OFFSET) & LSR_DATA_READY; +#endif + + return !!dr; +} + +/**************************************************************************** + * 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_TXDATA_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 |= IER_THRE_INT_ENABLE; + up_serialout(priv, UART_IE_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 &= ~IER_THRE_INT_ENABLE; + up_serialout(priv, UART_IE_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_LSR_OFFSET) & DW_LSR_TRANS_EMPTY); +} + +/**************************************************************************** + * 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 wartermak is pending */ + + return !!(up_serialin(priv, UART_LSR_OFFSET) & DW_LSR_TRANS_EMPTY); +} + +/**************************************************************************** + * 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 + * c906_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/c906/c906_start.c b/arch/risc-v/src/c906/c906_start.c new file mode 100644 index 0000000000..09336c3b8d --- /dev/null +++ b/arch/risc-v/src/c906/c906_start.c @@ -0,0 +1,149 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_start.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 "riscv_arch.h" +#include "c906_clockconfig.h" +#include "c906_userspace.h" +#include "c906.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. + */ + +uintptr_t g_idle_topstack = C906_IDLESTACK_TOP; +volatile bool g_serial_ok = false; + +extern void c906_cpu_boot(uint32_t); + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: __c906_start + ****************************************************************************/ + +void __c906_start(uint32_t mhartid) +{ + const uint32_t *src; + uint32_t *dest; + + if (0 != mhartid) + { + while (true); + } + + /* 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 (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + /* Setup PLL */ + + c906_clockconfig(); + + /* Configure the UART so we can get debug output */ + + c906_lowsetup(); + + showprogress('A'); + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + + showprogress('B'); + + g_serial_ok = true; + + /* Do board initialization */ + + c906_boardinitialize(); + + showprogress('C'); + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + +#ifdef CONFIG_BUILD_PROTECTED + c906_userspace(); + showprogress('D'); +#endif + + /* Call nx_start() */ + + nx_start(); + + showprogress('a'); + + while (true) + { + asm("WFI"); + } +} diff --git a/arch/risc-v/src/c906/c906_timerisr.c b/arch/risc-v/src/c906/c906_timerisr.c new file mode 100644 index 0000000000..677550bc4b --- /dev/null +++ b/arch/risc-v/src/c906/c906_timerisr.c @@ -0,0 +1,131 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_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 "riscv_arch.h" + +#include "c906.h" +#include "c906_clockconfig.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define getreg64(a) (*(volatile uint64_t *)(a)) +#define putreg64(v,a) (*(volatile uint64_t *)(a) = (v)) + +#ifdef CONFIG_C906_WITH_QEMU +#define TICK_COUNT (10000000UL / TICK_PER_SEC) +#else +#define TICK_COUNT ((c906_get_cpuclk()) / TICK_PER_SEC) +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static bool _b_tick_started = false; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: c906_reload_mtimecmp + ****************************************************************************/ + +static void c906_reload_mtimecmp(void) +{ + irqstate_t flags = spin_lock_irqsave(NULL); + + uint64_t current; + uint64_t next; + + if (!_b_tick_started) + { + _b_tick_started = true; + current = getreg64(C906_CLINT_MTIME); + } + else + { + current = getreg64(C906_CLINT_MTIMECMP); + } + + uint64_t tick = TICK_COUNT; + next = current + tick; + + putreg64(next, C906_CLINT_MTIMECMP); + + spin_unlock_irqrestore(NULL, flags); +} + +/**************************************************************************** + * Name: c906_timerisr + ****************************************************************************/ + +static int c906_timerisr(int irq, void *context, FAR void *arg) +{ + c906_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(C906_IRQ_MTIMER, c906_timerisr, NULL); + + /* Reload CLINT mtimecmp */ + + c906_reload_mtimecmp(); + + /* And enable the timer interrupt */ + + up_enable_irq(C906_IRQ_MTIMER); +} diff --git a/arch/risc-v/src/c906/c906_userspace.c b/arch/risc-v/src/c906/c906_userspace.c new file mode 100644 index 0000000000..0674e8e267 --- /dev/null +++ b/arch/risc-v/src/c906/c906_userspace.c @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_userspace.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 "c906_userspace.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: c906_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +void c906_userspace(void) +{ + uint8_t *src; + uint8_t *dest; + uint8_t *end; + + /* Clear all of user-space .bss */ + + DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 && + USERSPACE->us_bssstart <= USERSPACE->us_bssend); + + dest = (uint8_t *)USERSPACE->us_bssstart; + end = (uint8_t *)USERSPACE->us_bssend; + + while (dest != end) + { + *dest++ = 0; + } + + /* Initialize all of user-space .data */ + + DEBUGASSERT(USERSPACE->us_datasource != 0 && + USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 && + USERSPACE->us_datastart <= USERSPACE->us_dataend); + + src = (uint8_t *)USERSPACE->us_datasource; + dest = (uint8_t *)USERSPACE->us_datastart; + end = (uint8_t *)USERSPACE->us_dataend; + + while (dest != end) + { + *dest++ = *src++; + } + + /* TODO: + * Configure the PMP to permit user-space access to its ROM and RAM + */ +} + +#endif /* CONFIG_BUILD_PROTECTED */ diff --git a/arch/risc-v/src/c906/c906_userspace.h b/arch/risc-v/src/c906/c906_userspace.h new file mode 100644 index 0000000000..fa54a1387b --- /dev/null +++ b/arch/risc-v/src/c906/c906_userspace.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_userspace.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_C906_C906_USERSPACE_H +#define __ARCH_RISCV_SRC_C906_C906_USERSPACE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: c906_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void c906_userspace(void); +#endif + +#endif /* __ARCH_RISCV_SRC_C906_C906_USERSPACE_H */ diff --git a/arch/risc-v/src/c906/c906_vectors.S b/arch/risc-v/src/c906/c906_vectors.S new file mode 100644 index 0000000000..724717a88d --- /dev/null +++ b/arch/risc-v/src/c906/c906_vectors.S @@ -0,0 +1,46 @@ +/**************************************************************************** + * arch/risc-v/src/c906/c906_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 + * + * Description: + * All exceptions and interrupts will be handled from here. + * + ****************************************************************************/ + +__trap_vec: + j exception_common + nop diff --git a/arch/risc-v/src/c906/chip.h b/arch/risc-v/src/c906/chip.h new file mode 100644 index 0000000000..8c94eaa9f6 --- /dev/null +++ b/arch/risc-v/src/c906/chip.h @@ -0,0 +1,32 @@ +/**************************************************************************** + * arch/risc-v/src/c906/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_C906_CHIP_H +#define __ARCH_RISCV_SRC_C906_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "c906_memorymap.h" + +#endif /* __ARCH_RISCV_SRC_C906_CHIP_H */ diff --git a/arch/risc-v/src/c906/hardware/c906_clint.h b/arch/risc-v/src/c906/hardware/c906_clint.h new file mode 100644 index 0000000000..fe3a2e1dfe --- /dev/null +++ b/arch/risc-v/src/c906/hardware/c906_clint.h @@ -0,0 +1,32 @@ +/**************************************************************************** + * arch/risc-v/src/c906/hardware/c906_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_C906_HARDWARE_C906_CLINT_H +#define __ARCH_RISCV_SRC_C906_HARDWARE_C906_CLINT_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define C906_CLINT_MSIP (C906_CLINT_BASE + 0x0000) +#define C906_CLINT_MTIMECMP (C906_CLINT_BASE + 0x4000) +#define C906_CLINT_MTIME (C906_CLINT_BASE + 0xbff8) + +#endif /* __ARCH_RISCV_SRC_C906_HARDWARE_C906_CLINT_H */ diff --git a/arch/risc-v/src/c906/hardware/c906_memorymap.h b/arch/risc-v/src/c906/hardware/c906_memorymap.h new file mode 100644 index 0000000000..07ba456ff6 --- /dev/null +++ b/arch/risc-v/src/c906/hardware/c906_memorymap.h @@ -0,0 +1,40 @@ +/**************************************************************************** + * arch/risc-v/src/c906/hardware/c906_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_C906_HARDWARE_C906_MEMORYMAP_H +#define __ARCH_RISCV_SRC_C906_HARDWARE_C906_MEMORYMAP_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Base Address ****************************************************/ + +#define C906_PLIC_BASE (0x4000000000ULL) +#define C906_CLINT_BASE (C906_PLIC_BASE + 0x4000000UL) +#define C906_CORET_BASE (C906_PLIC_BASE + 0x4000000UL) + +#ifdef CONFIG_C906_WITH_QEMU +#define C906_UART0_BASE 0x10015000UL +#else +#define C906_UART0_BASE 0x10015000UL +#endif + +#endif /* __ARCH_RISCV_SRC_C906_HARDWARE_C906_MEMORYMAP_H */ diff --git a/arch/risc-v/src/c906/hardware/c906_plic.h b/arch/risc-v/src/c906/hardware/c906_plic.h new file mode 100644 index 0000000000..d333f7270d --- /dev/null +++ b/arch/risc-v/src/c906/hardware/c906_plic.h @@ -0,0 +1,41 @@ +/**************************************************************************** + * arch/risc-v/src/c906/hardware/c906_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_C906_HARDWARE_C906_PLIC_H +#define __ARCH_RISCV_SRC_C906_HARDWARE_C906_PLIC_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define C906_PLIC_PRIORITY (C906_PLIC_BASE + 0x000000) +#define C906_PLIC_IP0 (C906_PLIC_BASE + 0x001000) +#define C906_PLIC_IP1 (C906_PLIC_BASE + 0x001004) +#define C906_PLIC_MIE0 (C906_PLIC_BASE + 0x002000) +#define C906_PLIC_MIE1 (C906_PLIC_BASE + 0x002004) +#define C906_PLIC_SIE0 (C906_PLIC_BASE + 0x002080) +#define C906_PLIC_SIE1 (C906_PLIC_BASE + 0x002084) +#define C906_PLIC_CTRL (C906_PLIC_BASE + 0x1FFFFC) +#define C906_PLIC_MTHRESHOLD (C906_PLIC_BASE + 0x200000) +#define C906_PLIC_MCLAIM (C906_PLIC_BASE + 0x200004) +#define C906_PLIC_STHRESHOLD (C906_PLIC_BASE + 0x201000) +#define C906_PLIC_SCLAIM (C906_PLIC_BASE + 0x201004) + +#endif /* __ARCH_RISCV_SRC_C906_HARDWARE_C906_PLIC_H */ diff --git a/arch/risc-v/src/c906/hardware/c906_sysctl.h b/arch/risc-v/src/c906/hardware/c906_sysctl.h new file mode 100644 index 0000000000..6198a4a584 --- /dev/null +++ b/arch/risc-v/src/c906/hardware/c906_sysctl.h @@ -0,0 +1,34 @@ +/**************************************************************************** + * arch/risc-v/src/c906/hardware/c906_sysctl.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_C906_HARDWARE_C906_SYSCTL_H +#define __ARCH_RISCV_SRC_C906_HARDWARE_C906_SYSCTL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#endif /* __ARCH_RISCV_SRC_C906_HARDWARE_C906_SYSCTL_H */ diff --git a/arch/risc-v/src/c906/hardware/c906_uart.h b/arch/risc-v/src/c906/hardware/c906_uart.h new file mode 100644 index 0000000000..303cacf997 --- /dev/null +++ b/arch/risc-v/src/c906/hardware/c906_uart.h @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/risc-v/src/c906/hardware/c906_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_C906_CHIP_C906_UART_H +#define ARCH_RISCV_SRC_C906_CHIP_C906_UART_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define UART_TXDATA_OFFSET 0x00 +#define UART_RXDATA_OFFSET 0x00 +#define UART_TXCTL_OFFSET 0x04 +#define UART_RXCTL_OFFSET 0x04 +#define UART_IE_OFFSET 0x04 +#define UART_IIR_OFFSET 0x08 +#define UART_DIV_OFFSET 0x04 +#define UART_LSR_OFFSET 0x14 +#define UART_MSR_OFFSET 0x18 +#define UART_USR_OFFSET 0x7c + +#ifdef CONFIG_C906_UART0 +# define C906_UART0_TXDATA (C906_UART0_BASE + UART_TXDATA_OFFSET) +# define C906_UART0_RXDATA (C906_UART0_BASE + UART_RXDATA_OFFSET) +# define C906_UART0_TXCTRL (C906_UART0_BASE + UART_TXCTRL_OFFSET) +# define C906_UART0_RXCTRL (C906_UART0_BASE + UART_RXCTRL_OFFSET) +# define C906_UART0_IE (C906_UART0_BASE + UART_IE_OFFSET) +# define C906_UART0_IP (C906_UART0_BASE + UART_IP_OFFSET) +# define C906_UART0_DIV (C906_UART0_BASE + UART_DIV_OFFSET) +# define C906_UART0_LSR (C906_UART0_BASE + UART_LSR_OFFSET) +# define C906_UART0_MSR (C906_UART0_BASE + UART_MSR_OFFSET) +# define C906_UART0_USR (C906_UART0_BASE + UART_USR_OFFSET) +#endif + +#define USR_UART_BUSY 0x01 +#define USR_UART_TFE 0x04 +#define USR_UART_RFNE 0x08 +#define LSR_DATA_READY 0x01 +#define LSR_THR_EMPTY 0x20 +#define IER_RDA_INT_ENABLE 0x01 +#define IER_THRE_INT_ENABLE 0x02 +#define IIR_RECV_LINE_ENABLE 0x04 +#define IIR_NO_ISQ_PEND 0x01 + +#define LCR_SET_DLAB 0x80 /* enable r/w DLR to set the baud rate */ +#define LCR_PARITY_ENABLE 0x08 /* parity enabled */ +#define LCR_PARITY_EVEN 0x10 /* Even parity enabled */ +#define LCR_PARITY_ODD 0xef /* Odd parity enabled */ +#define LCR_WORD_SIZE_5 0xfc /* the data length is 5 bits */ +#define LCR_WORD_SIZE_6 0x01 /* the data length is 6 bits */ +#define LCR_WORD_SIZE_7 0x02 /* the data length is 7 bits */ +#define LCR_WORD_SIZE_8 0x03 /* the data length is 8 bits */ +#define LCR_STOP_BIT1 0xfb /* 1 stop bit */ +#define LCR_STOP_BIT2 0x04 /* 1.5 stop bit */ + +#define DW_LSR_PFE 0x80 +#define DW_LSR_TEMT 0x40 +#define DW_LSR_THRE 0x40 +#define DW_LSR_BI 0x10 +#define DW_LSR_FE 0x08 +#define DW_LSR_PE 0x04 +#define DW_LSR_OE 0x02 +#define DW_LSR_DR 0x01 +#define DW_LSR_TRANS_EMPTY 0x20 + +#define DW_IIR_THR_EMPTY 0x02 /* threshold empty */ +#define DW_IIR_RECV_DATA 0x04 /* received data available */ +#define DW_IIR_RECV_LINE 0x06 /* receiver line status */ +#define DW_IIR_CHAR_TIMEOUT 0x0c /* character timeout */ + +#endif /* ARCH_RISCV_SRC_C906_CHIP_C906_UART_H */ diff --git a/boards/Kconfig b/boards/Kconfig index c6bf1a46e4..d2b7424575 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -602,6 +602,14 @@ 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_SMARTL_C906 + bool "smartl evaluation board for C906" + depends on ARCH_CHIP_C906 + select ARCH_HAVE_LEDS if !C906_WITH_QEMU + ---help--- + This is the board configuration for the port of NuttX to the + THEAD smartl-c906 board. This board features the RISC-V C906. + config ARCH_BOARD_MAX32660_EVSYS bool "Maxim Integrated MAX32660-EVSYS" depends on ARCH_CHIP_MAX32660 @@ -2268,6 +2276,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 "smartl-c906" if ARCH_BOARD_SMARTL_C906 default "maple" if ARCH_BOARD_MAPLE default "makerlisp" if ARCH_BOARD_MAKERLISP default "max32660-evsys" if ARCH_BOARD_MAX32660_EVSYS @@ -3037,6 +3046,9 @@ endif if ARCH_BOARD_MAIX_BIT source "boards/risc-v/k210/maix-bit/Kconfig" endif +if ARCH_BOARD_SMARTL_C906 +source "boards/risc-v/c906/smartl-c906/Kconfig" +endif if ARCH_BOARD_ESP32C3_DEVKIT source "boards/risc-v/esp32c3/esp32c3-devkit/Kconfig" endif diff --git a/boards/risc-v/c906/smartl-c906/Kconfig b/boards/risc-v/c906/smartl-c906/Kconfig new file mode 100644 index 0000000000..d175cfbbf6 --- /dev/null +++ b/boards/risc-v/c906/smartl-c906/Kconfig @@ -0,0 +1,8 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# + +if ARCH_BOARD_SMARTL_C906 + +endif diff --git a/boards/risc-v/c906/smartl-c906/README-qemu.txt b/boards/risc-v/c906/smartl-c906/README-qemu.txt new file mode 100644 index 0000000000..68ddfb9b13 --- /dev/null +++ b/boards/risc-v/c906/smartl-c906/README-qemu.txt @@ -0,0 +1,35 @@ +1. Download and install toolchain + + https://occ.t-head.cn/community/download + +2. Download and install qemu + + https://occ.t-head.cn/community/download + +3. Modify defconfig + + CONFIG_C906_WITH_QEMU=y + +4. Configure and build NuttX + + $ make distclean + $ ./tools/configure.sh smartl-c906:nsh + $ make -j + +5. Run the nuttx with qemu + + Modify the soc config file "smarth_906_cfg.xml", enlarge the RAM size. +- ++ +... +- smart_inst_mem, Start: 0x0, Length: 0x20000 ++ smart_inst_mem, Start: 0x0, Length: 0x400000 + + Then launch QEMU: + $ ./cskysim -soc $PATH_TO_SOCCFG/smarth_906_cfg.xml -nographic -kernel $PATH_TO_NUTTX_BUILD_DIR/nuttx + +6. TODO + + Support FPU + Support ELF based file applications + Support RISC-V User mode diff --git a/boards/risc-v/c906/smartl-c906/README.txt b/boards/risc-v/c906/smartl-c906/README.txt new file mode 100644 index 0000000000..317b5498a3 --- /dev/null +++ b/boards/risc-v/c906/smartl-c906/README.txt @@ -0,0 +1,24 @@ +1. Download and install toolchain + + https://occ.t-head.cn/community/download + +2. Download and install qemu + + https://occ.t-head.cn/community/download + +3. Modify defconfig + +4. Configure and build NuttX + + $ make distclean + $ ./tools/configure.sh smartl-c906:nsh + $ make -j + +5. Run the nuttx by downloading elf to RAM via HW debugger + +6. TODO + + Support FPU + Support ELF based file applications + Support RISC-V User mode + diff --git a/boards/risc-v/c906/smartl-c906/configs/nsh/defconfig b/boards/risc-v/c906/smartl-c906/configs/nsh/defconfig new file mode 100644 index 0000000000..06ef27aec6 --- /dev/null +++ b/boards/risc-v/c906/smartl-c906/configs/nsh/defconfig @@ -0,0 +1,60 @@ +# +# 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_DISABLE_LOSMART is not set +# CONFIG_STANDARD_SERIAL is not set +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="smartl-c906" +CONFIG_ARCH_BOARD_SMARTL_C906=y +CONFIG_ARCH_CHIP="c906" +CONFIG_ARCH_CHIP_C906=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=46000 +CONFIG_BUILTIN=y +CONFIG_C906_WITH_QEMU=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEV_ZERO=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_FS_PROCFS=y +CONFIG_FS_ROMFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_MAX_TASKS=64 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=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_READLINE=y +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=262144 +CONFIG_RAM_START=0x00180000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=7 +CONFIG_START_MONTH=3 +CONFIG_START_YEAR=2021 +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=20 +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_USERMAIN_STACKSIZE=3072 +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/boards/risc-v/c906/smartl-c906/include/board.h b/boards/risc-v/c906/smartl-c906/include/board.h new file mode 100644 index 0000000000..de24f37fb6 --- /dev/null +++ b/boards/risc-v/c906/smartl-c906/include/board.h @@ -0,0 +1,74 @@ +/**************************************************************************** + * boards/risc-v/c906/smartl-c906/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_C906_SMARTL_C906_INCLUDE_BOARD_H +#define __BOARDS_RISCV_C906_SMARTL_C906_INCLUDE_BOARD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +#include "c906.h" + +/**************************************************************************** + * 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: c906_boardinitialize + ****************************************************************************/ + +void c906_boardinitialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_RISCV_C906_SMARTL_C906_INCLUDE_BOARD_H */ diff --git a/boards/risc-v/c906/smartl-c906/scripts/Make.defs b/boards/risc-v/c906/smartl-c906/scripts/Make.defs new file mode 100644 index 0000000000..55fbf39369 --- /dev/null +++ b/boards/risc-v/c906/smartl-c906/scripts/Make.defs @@ -0,0 +1,97 @@ +############################################################################ +# boards/risc-v/c906/smartl-c906/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/rv64gc/Toolchain.defs + +ifeq ($(CONFIG_C906_WITH_QEMU),y) + LDSCRIPT = ld-qemu.script +else + LDSCRIPT = ld.script +endif + +ifeq ($(CONFIG_CYGWIN_WINTOOL),y) + ARCHSCRIPT = -T "${shell cygpath -w $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)}" +else + ARCHSCRIPT = -T$(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT) +endif + +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 +endif + +# The following options are for the toolchain from T-HEAD. +# For more info ahout the T-HEAD ISA extensions, please refer to the C906 user guide. +# ARCHCPUFLAGS = -march=rv64gcxthead -mabi=lp64d -mtune=c906 -mcmodel=medany +# TODO: We are not going to enable this at this time for the CI compatiblity. + +ARCHCPUFLAGS = -march=rv64gc -mabi=lp64d -mcmodel=medany +ARCHCFLAGS = -fno-builtin -ffunction-sections -fdata-sections -fno-omit-frame-pointer +ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti +ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef +ARCHWARNINGSXX = -Wall -Wshadow -Wundef + +CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS) +CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +AFLAGS += $(CFLAGS) -D__ASSEMBLY__ $(ASARCHCPUFLAGS) + +# NXFLAT module definitions + +NXFLATLDFLAGS1 = -r -d -warn-common +NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections +LDNXFLATFLAGS = -e main -s 2048 + +# Loadable module definitions + +CMODULEFLAGS = $(CFLAGS) + +LDMODULEFLAGS = -r -e module_initialize +ifeq ($(CONFIG_CYGWIN_WINTOOL),y) + LDMODULEFLAGS += -T "${shell cygpath -w $(TOPDIR)/libs/libc/modlib/gnu-elf.ld}" +else + LDMODULEFLAGS += -T $(TOPDIR)/libs/libc/modlib/gnu-elf.ld +endif + +# ELF module definitions + +CELFFLAGS = $(CFLAGS) -fno-common +CXXELFFLAGS = $(CXXFLAGS) -fno-common + +LDELFFLAGS = -r -e main +ifeq ($(CONFIG_CYGWIN_WINTOOL),y) + LDELFFLAGS += -T "${shell cygpath -w $(BOARD_DIR)$(DELIM)scripts$(DELIM)gnu-elf.ld}" +else + LDELFFLAGS += -T $(BOARD_DIR)$(DELIM)scripts$(DELIM)gnu-elf.ld +endif + +# File extensions + +LDFLAGS += --gc-sections -melf64lriscv diff --git a/boards/risc-v/c906/smartl-c906/scripts/ld-qemu.script b/boards/risc-v/c906/smartl-c906/scripts/ld-qemu.script new file mode 100644 index 0000000000..e501e62410 --- /dev/null +++ b/boards/risc-v/c906/smartl-c906/scripts/ld-qemu.script @@ -0,0 +1,97 @@ +/**************************************************************************** + * boards/risc-v/c906/smartl-c906/scripts/ld-qemu.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 = 0x00000000, LENGTH = 1024K /* w/ cache */ + sram (rwx) : ORIGIN = 0x00100000, LENGTH = 1024K /* w/ cache */ +} + +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 + + PROVIDE(__global_pointer$ = _sdata + ((_edata - _sdata) / 2)); + + .bss : ALIGN(4) { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.sbss .sbss.*) + *(.gnu.linkonce.b.*) + *(.gnu.linkonce.sb.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + . = ALIGN(32); + _default_stack_limit = 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/c906/smartl-c906/scripts/ld.script b/boards/risc-v/c906/smartl-c906/scripts/ld.script new file mode 100644 index 0000000000..c4682a546b --- /dev/null +++ b/boards/risc-v/c906/smartl-c906/scripts/ld.script @@ -0,0 +1,97 @@ +/**************************************************************************** + * boards/risc-v/c906/smartl-c906/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 = 0x00000000, LENGTH = 1024K /* w/ cache */ + sram (rwx) : ORIGIN = 0x00100000, LENGTH = 1024K /* w/ cache */ +} + +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 + + PROVIDE(__global_pointer$ = _sdata + ((_edata - _sdata) / 2)); + + .bss : ALIGN(4) { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.sbss .sbss.*) + *(.gnu.linkonce.b.*) + *(.gnu.linkonce.sb.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + . = ALIGN(32); + _default_stack_limit = 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/c906/smartl-c906/src/Makefile b/boards/risc-v/c906/smartl-c906/src/Makefile new file mode 100644 index 0000000000..a61617675a --- /dev/null +++ b/boards/risc-v/c906/smartl-c906/src/Makefile @@ -0,0 +1,33 @@ +############################################################################ +# boards/risc-v/c906/smartl-c906/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 = c906_bringup.c c906_boot.c + +ifeq ($(CONFIG_LIB_BOARDCTL),y) +CSRCS += c906_appinit.c +endif + +ifeq ($(CONFIG_ARCH_LEDS),y) +CSRCS += c906_leds.c +endif + +include $(TOPDIR)/boards/Board.mk diff --git a/boards/risc-v/c906/smartl-c906/src/c906_appinit.c b/boards/risc-v/c906/smartl-c906/src/c906_appinit.c new file mode 100644 index 0000000000..932e8131d0 --- /dev/null +++ b/boards/risc-v/c906/smartl-c906/src/c906_appinit.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * boards/risc-v/c906/smartl-c906/src/c906_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 "c906.h" +#include "smartl-c906.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 could 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 c906_bringup(); +#endif +} diff --git a/boards/risc-v/c906/smartl-c906/src/c906_boot.c b/boards/risc-v/c906/smartl-c906/src/c906_boot.c new file mode 100644 index 0000000000..6370f967a0 --- /dev/null +++ b/boards/risc-v/c906/smartl-c906/src/c906_boot.c @@ -0,0 +1,58 @@ +/**************************************************************************** + * boards/risc-v/c906/smartl-c906/src/c906_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: c906_boardinitialize + * + * Description: + * All C906 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 c906_boardinitialize(void) +{ + board_autoled_initialize(); +} diff --git a/boards/risc-v/c906/smartl-c906/src/c906_bringup.c b/boards/risc-v/c906/smartl-c906/src/c906_bringup.c new file mode 100644 index 0000000000..71cf487f71 --- /dev/null +++ b/boards/risc-v/c906/smartl-c906/src/c906_bringup.c @@ -0,0 +1,61 @@ +/**************************************************************************** + * boards/risc-v/c906/smartl-c906/src/c906_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 "c906.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: c906_bringup + ****************************************************************************/ + +int c906_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/c906/smartl-c906/src/c906_leds.c b/boards/risc-v/c906/smartl-c906/src/c906_leds.c new file mode 100644 index 0000000000..e8c09ef150 --- /dev/null +++ b/boards/risc-v/c906/smartl-c906/src/c906_leds.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * boards/risc-v/c906/smartl-c906/src/c906_leds.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 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_autoled_initialize + * + * Description: + * Init the LEDs. + * + ****************************************************************************/ + +void board_autoled_initialize(void) +{ +} + +/**************************************************************************** + * Name: board_autoled_on + * + * Description: + * Turn on the LED specificed. + * + * Input Parameters: + * led - The LED which is under this control + * + ****************************************************************************/ + +void board_autoled_on(int led) +{ +} + +/**************************************************************************** + * Name: board_autoled_off + * + * Description: + * Turn off the LED specificed. + * + * Input Parameters: + * led - The LED which is under this control + * + ****************************************************************************/ + +void board_autoled_off(int led) +{ +} diff --git a/boards/risc-v/c906/smartl-c906/src/smartl-c906.h b/boards/risc-v/c906/smartl-c906/src/smartl-c906.h new file mode 100644 index 0000000000..26bbc73893 --- /dev/null +++ b/boards/risc-v/c906/smartl-c906/src/smartl-c906.h @@ -0,0 +1,32 @@ +/**************************************************************************** + * boards/risc-v/c906/smartl-c906/src/smartl-c906.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_C906_SMARTL_C906_SRC_SMARTL_C906_H +#define __BOARDS_RISCV_C906_SMARTL_C906_SRC_SMARTL_C906_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +int c906_bringup(void); + +#endif /* __BOARDS_RISCV_C906_SMARTL_C906_SRC_SMARTL_C906_H */