arch:riscv64:basic porting for C906.

Signed-off-by: hotislandn <hotislandn@hotmail.com>
This commit is contained in:
hotislandn 2021-03-08 23:19:29 +08:00 committed by Xiang Xiao
parent f292b67dce
commit 5e50938726
44 changed files with 3879 additions and 0 deletions

View file

@ -61,6 +61,12 @@ config ARCH_CHIP_ESP32C3
---help--- ---help---
Espressif ESP32-C3 (RV32IMC). 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 config ARCH_CHIP_RISCV_CUSTOM
bool "Custom RISC-V chip" bool "Custom RISC-V chip"
select ARCH_CHIP_CUSTOM select ARCH_CHIP_CUSTOM
@ -99,6 +105,7 @@ config ARCH_CHIP
default "gap8" if ARCH_CHIP_GAP8 default "gap8" if ARCH_CHIP_GAP8
default "bl602" if ARCH_CHIP_BL602 default "bl602" if ARCH_CHIP_BL602
default "esp32c3" if ARCH_CHIP_ESP32C3 default "esp32c3" if ARCH_CHIP_ESP32C3
default "c906" if ARCH_CHIP_C906
config NR5_MPU config NR5_MPU
bool "MPU support" bool "MPU support"
@ -137,4 +144,7 @@ endif
if ARCH_CHIP_ESP32C3 if ARCH_CHIP_ESP32C3
source arch/risc-v/src/esp32c3/Kconfig source arch/risc-v/src/esp32c3/Kconfig
endif endif
if ARCH_CHIP_C906
source arch/risc-v/src/c906/Kconfig
endif
endif endif

View file

@ -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 <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <arch/irq.h>
#endif /* __ARCH_RISCV_INCLUDE_C906_CHIP_H */

View file

@ -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 <arch/irq.h>
/****************************************************************************
* 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 */

View file

@ -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

View file

@ -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

View file

@ -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 <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <arch/irq.h>
#include "riscv_internal.h"
#include "chip.h"
#include "c906_lowputc.h"
#endif /* __ARCH_RISCV_SRC_C906_C906_H */

View file

@ -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 <nuttx/config.h>
#include <nuttx/kmalloc.h>
#include <nuttx/userspace.h>
#include <arch/board/board.h>
#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)
{
}

View file

@ -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 <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <arch/board/board.h>
#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
}

View file

@ -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 */

View file

@ -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 <nuttx/config.h>
#include <arch/chip/chip.h>
#include <arch/board/board.h>
/****************************************************************************
* 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 */

View file

@ -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 <nuttx/config.h>
#include <arch/csr.h>
#include <arch/rv64gc/irq.h>
#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

View file

@ -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 <nuttx/config.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#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
}

View file

@ -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 <nuttx/config.h>
#include <stdint.h>
#include <stdio.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <arch/irq.h>
#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;
}

View file

@ -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 <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#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;
}

View file

@ -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 <nuttx/config.h>
#include <stdint.h>
#include <arch/board/board.h>
#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 */
}

View file

@ -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 <nuttx/config.h>
#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 */

View file

@ -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 */

View file

@ -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 <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/serial/serial.h>
#include <arch/board/board.h>
#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 */

View file

@ -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 <nuttx/config.h>
#include <nuttx/init.h>
#include <nuttx/arch.h>
#include <arch/board/board.h>
#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");
}
}

View file

@ -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 <nuttx/config.h>
#include <stdint.h>
#include <time.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <arch/board/board.h>
#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);
}

View file

@ -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 <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <nuttx/userspace.h>
#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 */

View file

@ -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 <nuttx/config.h>
/****************************************************************************
* 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 */

View file

@ -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

View file

@ -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 <nuttx/config.h>
#include "c906_memorymap.h"
#endif /* __ARCH_RISCV_SRC_C906_CHIP_H */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 <nuttx/config.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#endif /* __ARCH_RISCV_SRC_C906_HARDWARE_C906_SYSCTL_H */

View file

@ -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 */

View file

@ -602,6 +602,14 @@ config ARCH_BOARD_MAIX_BIT
This is the board configuration for the port of NuttX to the This is the board configuration for the port of NuttX to the
Sipeed Maix Bit board. This board features the RISC-V K210 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 config ARCH_BOARD_MAX32660_EVSYS
bool "Maxim Integrated MAX32660-EVSYS" bool "Maxim Integrated MAX32660-EVSYS"
depends on ARCH_CHIP_MAX32660 depends on ARCH_CHIP_MAX32660
@ -2268,6 +2276,7 @@ config ARCH_BOARD
default "lpcxpresso-lpc54628" if ARCH_BOARD_LPCXPRESSO_LPC54628 default "lpcxpresso-lpc54628" if ARCH_BOARD_LPCXPRESSO_LPC54628
default "lx_cpu" if ARCH_BOARD_LX_CPU default "lx_cpu" if ARCH_BOARD_LX_CPU
default "maix-bit" if ARCH_BOARD_MAIX_BIT default "maix-bit" if ARCH_BOARD_MAIX_BIT
default "smartl-c906" if ARCH_BOARD_SMARTL_C906
default "maple" if ARCH_BOARD_MAPLE default "maple" if ARCH_BOARD_MAPLE
default "makerlisp" if ARCH_BOARD_MAKERLISP default "makerlisp" if ARCH_BOARD_MAKERLISP
default "max32660-evsys" if ARCH_BOARD_MAX32660_EVSYS default "max32660-evsys" if ARCH_BOARD_MAX32660_EVSYS
@ -3037,6 +3046,9 @@ endif
if ARCH_BOARD_MAIX_BIT if ARCH_BOARD_MAIX_BIT
source "boards/risc-v/k210/maix-bit/Kconfig" source "boards/risc-v/k210/maix-bit/Kconfig"
endif endif
if ARCH_BOARD_SMARTL_C906
source "boards/risc-v/c906/smartl-c906/Kconfig"
endif
if ARCH_BOARD_ESP32C3_DEVKIT if ARCH_BOARD_ESP32C3_DEVKIT
source "boards/risc-v/esp32c3/esp32c3-devkit/Kconfig" source "boards/risc-v/esp32c3/esp32c3-devkit/Kconfig"
endif endif

View file

@ -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

View file

@ -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.
- <mem name="smart_inst_mem" addr="0x0" size ="0x00020000" attr ="MEM_RAM"></mem>
+ <mem name="smart_inst_mem" addr="0x0" size ="0x00400000" attr ="MEM_RAM"></mem>
...
- 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

View file

@ -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

View file

@ -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"

View file

@ -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 <nuttx/config.h>
#ifndef __ASSEMBLY__
# include <stdint.h>
#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 */

View file

@ -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

View file

@ -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) }
}

View file

@ -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) }
}

View file

@ -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

View file

@ -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 <nuttx/config.h>
#include <stdbool.h>
#include <stdio.h>
#include <syslog.h>
#include <errno.h>
#include <nuttx/board.h>
#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
}

View file

@ -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 <nuttx/config.h>
#include <debug.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
/****************************************************************************
* 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();
}

View file

@ -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 <nuttx/config.h>
#include <sys/mount.h>
#include <stdbool.h>
#include <stdio.h>
#include <syslog.h>
#include <errno.h>
#include <nuttx/board.h>
#include <nuttx/drivers/ramdisk.h>
#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;
}

View file

@ -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 <nuttx/config.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
/****************************************************************************
* 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)
{
}

View file

@ -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 <nuttx/config.h>
int c906_bringup(void);
#endif /* __BOARDS_RISCV_C906_SMARTL_C906_SRC_SMARTL_C906_H */