From d6205642ab18342e12449552d1d22b87838061d8 Mon Sep 17 00:00:00 2001 From: Janne Rosberg Date: Tue, 4 May 2021 13:56:52 +0300 Subject: [PATCH] add support for PolarFire SoC and icicle board Co-authored-by: Eero Nurkkala --- arch/risc-v/Kconfig | 11 + arch/risc-v/include/mpfs/chip.h | 34 + arch/risc-v/include/mpfs/irq.h | 340 ++++++ arch/risc-v/src/mpfs/Kconfig | 93 ++ arch/risc-v/src/mpfs/Make.defs | 63 + arch/risc-v/src/mpfs/chip.h | 32 + arch/risc-v/src/mpfs/hardware/mpfs_clint.h | 42 + arch/risc-v/src/mpfs/hardware/mpfs_gpio.h | 96 ++ .../risc-v/src/mpfs/hardware/mpfs_memorymap.h | 120 ++ arch/risc-v/src/mpfs/hardware/mpfs_plic.h | 131 ++ arch/risc-v/src/mpfs/hardware/mpfs_sysctl.h | 34 + arch/risc-v/src/mpfs/hardware/mpfs_uart.h | 207 ++++ arch/risc-v/src/mpfs/mpfs.h | 38 + arch/risc-v/src/mpfs/mpfs_allocateheap.c | 132 ++ arch/risc-v/src/mpfs/mpfs_clockconfig.c | 80 ++ arch/risc-v/src/mpfs/mpfs_clockconfig.h | 66 + arch/risc-v/src/mpfs/mpfs_config.h | 68 ++ arch/risc-v/src/mpfs/mpfs_gpio.c | 184 +++ arch/risc-v/src/mpfs/mpfs_gpio.h | 272 +++++ arch/risc-v/src/mpfs/mpfs_head.S | 328 +++++ arch/risc-v/src/mpfs/mpfs_idle.c | 65 + arch/risc-v/src/mpfs/mpfs_irq.c | 330 +++++ arch/risc-v/src/mpfs/mpfs_irq_dispatch.c | 175 +++ arch/risc-v/src/mpfs/mpfs_lowputc.c | 228 ++++ arch/risc-v/src/mpfs/mpfs_lowputc.h | 59 + arch/risc-v/src/mpfs/mpfs_memorymap.h | 53 + arch/risc-v/src/mpfs/mpfs_serial.c | 1069 +++++++++++++++++ arch/risc-v/src/mpfs/mpfs_start.c | 144 +++ arch/risc-v/src/mpfs/mpfs_timerisr.c | 132 ++ arch/risc-v/src/mpfs/mpfs_userspace.c | 127 ++ arch/risc-v/src/mpfs/mpfs_userspace.h | 49 + arch/risc-v/src/mpfs/mpfs_vectors.S | 53 + boards/Kconfig | 12 + boards/risc-v/mpfs/icicle/Kconfig | 8 + .../risc-v/mpfs/icicle/configs/nsh/defconfig | 76 ++ boards/risc-v/mpfs/icicle/include/board.h | 111 ++ boards/risc-v/mpfs/icicle/kernel/Makefile | 107 ++ .../mpfs/icicle/kernel/mpfs_userspace.c | 121 ++ boards/risc-v/mpfs/icicle/scripts/Make.defs | 98 ++ boards/risc-v/mpfs/icicle/scripts/gnu-elf.ld | 115 ++ .../risc-v/mpfs/icicle/scripts/hss-nuttx.yml | 12 + boards/risc-v/mpfs/icicle/scripts/ld.script | 97 ++ boards/risc-v/mpfs/icicle/scripts/memory.ld | 35 + .../risc-v/mpfs/icicle/scripts/user-space.ld | 104 ++ boards/risc-v/mpfs/icicle/src/Makefile | 37 + boards/risc-v/mpfs/icicle/src/mpfs_appinit.c | 75 ++ boards/risc-v/mpfs/icicle/src/mpfs_autoleds.c | 147 +++ boards/risc-v/mpfs/icicle/src/mpfs_boot.c | 58 + boards/risc-v/mpfs/icicle/src/mpfs_bringup.c | 61 + boards/risc-v/mpfs/icicle/src/mpfs_ostest.c | 92 ++ boards/risc-v/mpfs/icicle/src/mpfsicicle.h | 46 + 51 files changed, 6267 insertions(+) create mode 100755 arch/risc-v/include/mpfs/chip.h create mode 100755 arch/risc-v/include/mpfs/irq.h create mode 100755 arch/risc-v/src/mpfs/Kconfig create mode 100755 arch/risc-v/src/mpfs/Make.defs create mode 100755 arch/risc-v/src/mpfs/chip.h create mode 100755 arch/risc-v/src/mpfs/hardware/mpfs_clint.h create mode 100755 arch/risc-v/src/mpfs/hardware/mpfs_gpio.h create mode 100755 arch/risc-v/src/mpfs/hardware/mpfs_memorymap.h create mode 100755 arch/risc-v/src/mpfs/hardware/mpfs_plic.h create mode 100755 arch/risc-v/src/mpfs/hardware/mpfs_sysctl.h create mode 100755 arch/risc-v/src/mpfs/hardware/mpfs_uart.h create mode 100755 arch/risc-v/src/mpfs/mpfs.h create mode 100755 arch/risc-v/src/mpfs/mpfs_allocateheap.c create mode 100755 arch/risc-v/src/mpfs/mpfs_clockconfig.c create mode 100755 arch/risc-v/src/mpfs/mpfs_clockconfig.h create mode 100755 arch/risc-v/src/mpfs/mpfs_config.h create mode 100644 arch/risc-v/src/mpfs/mpfs_gpio.c create mode 100644 arch/risc-v/src/mpfs/mpfs_gpio.h create mode 100755 arch/risc-v/src/mpfs/mpfs_head.S create mode 100755 arch/risc-v/src/mpfs/mpfs_idle.c create mode 100755 arch/risc-v/src/mpfs/mpfs_irq.c create mode 100755 arch/risc-v/src/mpfs/mpfs_irq_dispatch.c create mode 100755 arch/risc-v/src/mpfs/mpfs_lowputc.c create mode 100755 arch/risc-v/src/mpfs/mpfs_lowputc.h create mode 100755 arch/risc-v/src/mpfs/mpfs_memorymap.h create mode 100755 arch/risc-v/src/mpfs/mpfs_serial.c create mode 100755 arch/risc-v/src/mpfs/mpfs_start.c create mode 100755 arch/risc-v/src/mpfs/mpfs_timerisr.c create mode 100755 arch/risc-v/src/mpfs/mpfs_userspace.c create mode 100755 arch/risc-v/src/mpfs/mpfs_userspace.h create mode 100755 arch/risc-v/src/mpfs/mpfs_vectors.S create mode 100755 boards/risc-v/mpfs/icicle/Kconfig create mode 100644 boards/risc-v/mpfs/icicle/configs/nsh/defconfig create mode 100755 boards/risc-v/mpfs/icicle/include/board.h create mode 100755 boards/risc-v/mpfs/icicle/kernel/Makefile create mode 100755 boards/risc-v/mpfs/icicle/kernel/mpfs_userspace.c create mode 100755 boards/risc-v/mpfs/icicle/scripts/Make.defs create mode 100755 boards/risc-v/mpfs/icicle/scripts/gnu-elf.ld create mode 100644 boards/risc-v/mpfs/icicle/scripts/hss-nuttx.yml create mode 100755 boards/risc-v/mpfs/icicle/scripts/ld.script create mode 100755 boards/risc-v/mpfs/icicle/scripts/memory.ld create mode 100755 boards/risc-v/mpfs/icicle/scripts/user-space.ld create mode 100755 boards/risc-v/mpfs/icicle/src/Makefile create mode 100755 boards/risc-v/mpfs/icicle/src/mpfs_appinit.c create mode 100755 boards/risc-v/mpfs/icicle/src/mpfs_autoleds.c create mode 100755 boards/risc-v/mpfs/icicle/src/mpfs_boot.c create mode 100755 boards/risc-v/mpfs/icicle/src/mpfs_bringup.c create mode 100755 boards/risc-v/mpfs/icicle/src/mpfs_ostest.c create mode 100755 boards/risc-v/mpfs/icicle/src/mpfsicicle.h diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index 074827444e..8adee3a09e 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -60,6 +60,13 @@ config ARCH_CHIP_C906 ---help--- THEAD C906 processor (RISC-V 64bit core with GCVX extensions). +config ARCH_CHIP_MPFS + bool "MicroChip Polarfire (MPFS)" + select ARCH_RV64GC + select ARCH_HAVE_MPU + ---help--- + MicroChip Polarfire processor (RISC-V 64bit core with GCVX extensions). + config ARCH_CHIP_RISCV_CUSTOM bool "Custom RISC-V chip" select ARCH_CHIP_CUSTOM @@ -97,6 +104,7 @@ config ARCH_CHIP default "bl602" if ARCH_CHIP_BL602 default "esp32c3" if ARCH_CHIP_ESP32C3 default "c906" if ARCH_CHIP_C906 + default "mpfs" if ARCH_CHIP_MPFS if ARCH_RV32IM source arch/risc-v/src/rv32im/Kconfig @@ -122,4 +130,7 @@ endif if ARCH_CHIP_C906 source arch/risc-v/src/c906/Kconfig endif +if ARCH_CHIP_MPFS +source arch/risc-v/src/mpfs/Kconfig +endif endif diff --git a/arch/risc-v/include/mpfs/chip.h b/arch/risc-v/include/mpfs/chip.h new file mode 100755 index 0000000000..0efd02220d --- /dev/null +++ b/arch/risc-v/include/mpfs/chip.h @@ -0,0 +1,34 @@ +/**************************************************************************** + * arch/risc-v/include/mpfs/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_MPFS_CHIP_H +#define __ARCH_RISCV_INCLUDE_MPFS_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include + +#endif /* __ARCH_RISCV_INCLUDE_MPFS_CHIP_H */ diff --git a/arch/risc-v/include/mpfs/irq.h b/arch/risc-v/include/mpfs/irq.h new file mode 100755 index 0000000000..89c78785a3 --- /dev/null +++ b/arch/risc-v/include/mpfs/irq.h @@ -0,0 +1,340 @@ +/**************************************************************************** + * arch/risc-v/include/mpfs/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_MPFS_IRQ_H +#define __ARCH_RISCV_INCLUDE_MPFS_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Map RISC-V exception code to NuttX IRQ */ + +/* IRQ 0-15 : (exception:interrupt=0) */ + +#define MPFS_IRQ_IAMISALIGNED (0) /* Instruction Address Misaligned */ +#define MPFS_IRQ_IAFAULT (1) /* Instruction Address Fault */ +#define MPFS_IRQ_IINSTRUCTION (2) /* Illegal Instruction */ +#define MPFS_IRQ_BPOINT (3) /* Break Point */ +#define MPFS_IRQ_LAMISALIGNED (4) /* Load Address Misaligned */ +#define MPFS_IRQ_LAFAULT (5) /* Load Access Fault */ +#define MPFS_IRQ_SAMISALIGNED (6) /* Store/AMO Address Misaligned */ +#define MPFS_IRQ_SAFAULT (7) /* Store/AMO Access Fault */ +#define MPFS_IRQ_ECALLU (8) /* Environment Call from U-mode */ +#define MPFS_IRQ_ECALLS (9) /* Environment Call from S-mode */ +#define MPFS_IRQ_ECALLH (10) /* Environment Call from H-mode */ +#define MPFS_IRQ_ECALLM (11) /* Environment Call from M-mode */ +#define MPFS_IRQ_INSTRUCTIONPF (12) /* Instruction page fault */ +#define MPFS_IRQ_LOADPF (13) /* Load page fault */ +#define MPFS_IRQ_RESERVED (14) /* Reserved */ +#define MPFS_IRQ_SROREPF (15) /* Store/AMO page fault */ + +/* IRQ 16- : (async event:interrupt=1) */ + +#define MPFS_IRQ_ASYNC (16) +#define MPFS_IRQ_SSOFT (MPFS_IRQ_ASYNC + 1) /* Supervisor Software Int */ +#define MPFS_IRQ_MSOFT (MPFS_IRQ_ASYNC + 3) /* Machine Software Int */ +#define MPFS_IRQ_STIMER (MPFS_IRQ_ASYNC + 5) /* Supervisor Timer Int */ +#define MPFS_IRQ_MTIMER (MPFS_IRQ_ASYNC + 7) /* Machine Timer Int */ +#define MPFS_IRQ_SEXT (MPFS_IRQ_ASYNC + 9) /* Supervisor External Int */ +#define MPFS_IRQ_MEXT (MPFS_IRQ_ASYNC + 11) /* Machine External Int */ + +/* IRQ 32-79 : 47 Local interrupts. */ + +#define MPFS_IRQ_LOCAL_START (MPFS_IRQ_ASYNC + 16) +#define MPFS_IRQ_LOCAL_0 (MPFS_IRQ_LOCAL_START + 0) /* Local 0 spare */ +#define MPFS_IRQ_LOCAL_1 (MPFS_IRQ_LOCAL_START + 1) /* Local 1 spare */ +#define MPFS_IRQ_LOCAL_2 (MPFS_IRQ_LOCAL_START + 2) /* Local 2 spare */ +#define MPFS_IRQ_LOCAL_U54_MAC_MMSL (MPFS_IRQ_LOCAL_START + 3) /* check hartid for mac source */ +#define MPFS_IRQ_LOCAL_U54_MAC_EMAC (MPFS_IRQ_LOCAL_START + 4) +#define MPFS_IRQ_LOCAL_U54_MAC_QUE3 (MPFS_IRQ_LOCAL_START + 5) +#define MPFS_IRQ_LOCAL_U54_MAC_QUE2 (MPFS_IRQ_LOCAL_START + 6) +#define MPFS_IRQ_LOCAL_U54_MAC_QUE1 (MPFS_IRQ_LOCAL_START + 7) +#define MPFS_IRQ_LOCAL_U54_MAC_INT (MPFS_IRQ_LOCAL_START + 8) +#define MPFS_IRQ_LOCAL_U54_WDOG_TOUT (MPFS_IRQ_LOCAL_START + 9) /* check hartid for wdog source */ +#define MPFS_IRQ_LOCAL_U54_MVRP (MPFS_IRQ_LOCAL_START + 10) +#define MPFS_IRQ_LOCAL_E51_MMUART0 (MPFS_IRQ_LOCAL_START + 11) +#define MPFS_IRQ_LOCAL_U54_H1_MMUART1 (MPFS_IRQ_LOCAL_START + 11) +#define MPFS_IRQ_LOCAL_U54_H2_MMUART2 (MPFS_IRQ_LOCAL_START + 11) +#define MPFS_IRQ_LOCAL_U54_H3_MMUART3 (MPFS_IRQ_LOCAL_START + 11) +#define MPFS_IRQ_LOCAL_U54_H4_MMUART4 (MPFS_IRQ_LOCAL_START + 11) +#define MPFS_IRQ_LOCAL_12 (MPFS_IRQ_LOCAL_START + 12) /* Local 12 spare */ +#define MPFS_IRQ_LOCAL_13 (MPFS_IRQ_LOCAL_START + 13) /* Local 13 spare */ +#define MPFS_IRQ_LOCAL_14 (MPFS_IRQ_LOCAL_START + 14) /* Local 14 spare */ +#define MPFS_IRQ_LOCAL_15 (MPFS_IRQ_LOCAL_START + 15) /* Local 15 spare */ +#define MPFS_IRQ_LOCAL_U54_F2H_0 (MPFS_IRQ_LOCAL_START + 16) /* Fabric 0 */ +#define MPFS_IRQ_LOCAL_U54_F2H_1 (MPFS_IRQ_LOCAL_START + 17) /* Fabric 1 */ +#define MPFS_IRQ_LOCAL_U54_F2H_2 (MPFS_IRQ_LOCAL_START + 18) /* Fabric 2 */ +#define MPFS_IRQ_LOCAL_U54_F2H_3 (MPFS_IRQ_LOCAL_START + 19) /* Fabric 3 */ +#define MPFS_IRQ_LOCAL_U54_F2H_4 (MPFS_IRQ_LOCAL_START + 20) /* Fabric 4 */ +#define MPFS_IRQ_LOCAL_U54_F2H_5 (MPFS_IRQ_LOCAL_START + 21) /* Fabric 5 */ +#define MPFS_IRQ_LOCAL_U54_F2H_6 (MPFS_IRQ_LOCAL_START + 22) /* Fabric 6 */ +#define MPFS_IRQ_LOCAL_U54_F2H_7 (MPFS_IRQ_LOCAL_START + 23) /* Fabric 7 */ +#define MPFS_IRQ_LOCAL_U54_F2H_8 (MPFS_IRQ_LOCAL_START + 24) /* Fabric 8 */ +#define MPFS_IRQ_LOCAL_U54_F2H_9 (MPFS_IRQ_LOCAL_START + 25) /* Fabric 9 */ +#define MPFS_IRQ_LOCAL_U54_F2H_10 (MPFS_IRQ_LOCAL_START + 26) /* Fabric 10 */ +#define MPFS_IRQ_LOCAL_U54_F2H_11 (MPFS_IRQ_LOCAL_START + 27) /* Fabric 11 */ +#define MPFS_IRQ_LOCAL_U54_F2H_12 (MPFS_IRQ_LOCAL_START + 28) /* Fabric 12 */ +#define MPFS_IRQ_LOCAL_U54_F2H_13 (MPFS_IRQ_LOCAL_START + 29) /* Fabric 13 */ +#define MPFS_IRQ_LOCAL_U54_F2H_14 (MPFS_IRQ_LOCAL_START + 30) /* Fabric 14 */ +#define MPFS_IRQ_LOCAL_U54_F2H_15 (MPFS_IRQ_LOCAL_START + 31) /* Fabric 15 */ +#define MPFS_IRQ_LOCAL_U54_F2H_16 (MPFS_IRQ_LOCAL_START + 32) /* Fabric 16 */ +#define MPFS_IRQ_LOCAL_U54_F2H_17 (MPFS_IRQ_LOCAL_START + 33) /* Fabric 17 */ +#define MPFS_IRQ_LOCAL_U54_F2H_18 (MPFS_IRQ_LOCAL_START + 34) /* Fabric 18 */ +#define MPFS_IRQ_LOCAL_U54_F2H_19 (MPFS_IRQ_LOCAL_START + 35) /* Fabric 19 */ +#define MPFS_IRQ_LOCAL_U54_F2H_20 (MPFS_IRQ_LOCAL_START + 36) /* Fabric 20 */ +#define MPFS_IRQ_LOCAL_U54_F2H_21 (MPFS_IRQ_LOCAL_START + 37) /* Fabric 21 */ +#define MPFS_IRQ_LOCAL_U54_F2H_22 (MPFS_IRQ_LOCAL_START + 38) /* Fabric 22 */ +#define MPFS_IRQ_LOCAL_U54_F2H_23 (MPFS_IRQ_LOCAL_START + 39) /* Fabric 23 */ +#define MPFS_IRQ_LOCAL_U54_F2H_24 (MPFS_IRQ_LOCAL_START + 40) /* Fabric 24 */ +#define MPFS_IRQ_LOCAL_U54_F2H_25 (MPFS_IRQ_LOCAL_START + 41) /* Fabric 25 */ +#define MPFS_IRQ_LOCAL_U54_F2H_26 (MPFS_IRQ_LOCAL_START + 42) /* Fabric 26 */ +#define MPFS_IRQ_LOCAL_U54_F2H_27 (MPFS_IRQ_LOCAL_START + 43) /* Fabric 27 */ +#define MPFS_IRQ_LOCAL_U54_F2H_28 (MPFS_IRQ_LOCAL_START + 44) /* Fabric 28 */ +#define MPFS_IRQ_LOCAL_U54_F2H_29 (MPFS_IRQ_LOCAL_START + 45) /* Fabric 29 */ +#define MPFS_IRQ_LOCAL_U54_F2H_30 (MPFS_IRQ_LOCAL_START + 46) /* Fabric 30 */ +#define MPFS_IRQ_LOCAL_U54_F2H_31 (MPFS_IRQ_LOCAL_START + 47) /* Fabric 31 */ + +/* External Interrupts. if irq is MPFS_IRQ_MEXT or MPFS_IRQ_SEXT */ + +#define MPFS_IRQ_EXT_START (MPFS_IRQ_ASYNC + 80U) +#define MPFS_IRQ_INVALID (MPFS_IRQ_EXT_START + 0) +#define MPFS_IRQ_L2_METADATA_CORR (MPFS_IRQ_EXT_START + 1) +#define MPFS_IRQ_L2_METADATA_UNCORR (MPFS_IRQ_EXT_START + 2) +#define MPFS_IRQ_L2_DATA_CORR (MPFS_IRQ_EXT_START + 3) +#define MPFS_IRQ_L2_DATA_UNCORR (MPFS_IRQ_EXT_START + 4) +#define MPFS_IRQ_DMA_CH0_DONE (MPFS_IRQ_EXT_START + 5) +#define MPFS_IRQ_DMA_CH0_ERR (MPFS_IRQ_EXT_START + 6) +#define MPFS_IRQ_DMA_CH1_DONE (MPFS_IRQ_EXT_START + 7) +#define MPFS_IRQ_DMA_CH1_ERR (MPFS_IRQ_EXT_START + 8) +#define MPFS_IRQ_DMA_CH2_DONE (MPFS_IRQ_EXT_START + 9) +#define MPFS_IRQ_DMA_CH2_ERR (MPFS_IRQ_EXT_START + 10) +#define MPFS_IRQ_DMA_CH3_DONE (MPFS_IRQ_EXT_START + 11) +#define MPFS_IRQ_DMA_CH3_ERR (MPFS_IRQ_EXT_START + 12) + +/* Global Interrupts */ + +#define OFFSET_TO_MSS_GLOBAL_INTS (13U) +#define MPFS_IRQ_GLOBAL_START (MPFS_IRQ_EXT_START + OFFSET_TO_MSS_GLOBAL_INTS) +#define MPFS_IRQ_GPIO02_BIT0 (MPFS_IRQ_GLOBAL_START + 0) +#define MPFS_IRQ_GPIO02_BIT1 (MPFS_IRQ_GLOBAL_START + 1) +#define MPFS_IRQ_GPIO02_BIT2 (MPFS_IRQ_GLOBAL_START + 2) +#define MPFS_IRQ_GPIO02_BIT3 (MPFS_IRQ_GLOBAL_START + 3) +#define MPFS_IRQ_GPIO02_BIT4 (MPFS_IRQ_GLOBAL_START + 4) +#define MPFS_IRQ_GPIO02_BIT5 (MPFS_IRQ_GLOBAL_START + 5) +#define MPFS_IRQ_GPIO02_BIT6 (MPFS_IRQ_GLOBAL_START + 6) +#define MPFS_IRQ_GPIO02_BIT7 (MPFS_IRQ_GLOBAL_START + 7) +#define MPFS_IRQ_GPIO02_BIT8 (MPFS_IRQ_GLOBAL_START + 8) +#define MPFS_IRQ_GPIO02_BIT9 (MPFS_IRQ_GLOBAL_START + 9) +#define MPFS_IRQ_GPIO02_BIT10 (MPFS_IRQ_GLOBAL_START + 10) +#define MPFS_IRQ_GPIO02_BIT11 (MPFS_IRQ_GLOBAL_START + 11) +#define MPFS_IRQ_GPIO02_BIT12 (MPFS_IRQ_GLOBAL_START + 12) +#define MPFS_IRQ_GPIO02_BIT13 (MPFS_IRQ_GLOBAL_START + 13) +#define MPFS_IRQ_GPIO1_BIT0_OR_GPIO2_BIT14 (MPFS_IRQ_GLOBAL_START + 14) +#define MPFS_IRQ_GPIO1_BIT1_OR_GPIO2_BIT15 (MPFS_IRQ_GLOBAL_START + 15) +#define MPFS_IRQ_GPIO1_BIT2_OR_GPIO2_BIT16 (MPFS_IRQ_GLOBAL_START + 16) +#define MPFS_IRQ_GPIO1_BIT3_OR_GPIO2_BIT17 (MPFS_IRQ_GLOBAL_START + 17) +#define MPFS_IRQ_GPIO1_BIT4_OR_GPIO2_BIT18 (MPFS_IRQ_GLOBAL_START + 18) +#define MPFS_IRQ_GPIO1_BIT5_OR_GPIO2_BIT19 (MPFS_IRQ_GLOBAL_START + 19) +#define MPFS_IRQ_GPIO1_BIT6_OR_GPIO2_BIT20 (MPFS_IRQ_GLOBAL_START + 20) +#define MPFS_IRQ_GPIO1_BIT7_OR_GPIO2_BIT21 (MPFS_IRQ_GLOBAL_START + 21) +#define MPFS_IRQ_GPIO1_BIT8_OR_GPIO2_BIT22 (MPFS_IRQ_GLOBAL_START + 22) +#define MPFS_IRQ_GPIO1_BIT9_OR_GPIO2_BIT23 (MPFS_IRQ_GLOBAL_START + 23) +#define MPFS_IRQ_GPIO1_BIT10_OR_GPIO2_BIT24 (MPFS_IRQ_GLOBAL_START + 24) +#define MPFS_IRQ_GPIO1_BIT11_OR_GPIO2_BIT25 (MPFS_IRQ_GLOBAL_START + 25) +#define MPFS_IRQ_GPIO1_BIT12_OR_GPIO2_BIT26 (MPFS_IRQ_GLOBAL_START + 26) +#define MPFS_IRQ_GPIO1_BIT13_OR_GPIO2_BIT27 (MPFS_IRQ_GLOBAL_START + 27) +#define MPFS_IRQ_GPIO1_BIT14_OR_GPIO2_BIT28 (MPFS_IRQ_GLOBAL_START + 28) +#define MPFS_IRQ_GPIO1_BIT15_OR_GPIO2_BIT29 (MPFS_IRQ_GLOBAL_START + 29) +#define MPFS_IRQ_GPIO1_BIT16_OR_GPIO2_BIT30 (MPFS_IRQ_GLOBAL_START + 30) +#define MPFS_IRQ_GPIO1_BIT17_OR_GPIO2_BIT31 (MPFS_IRQ_GLOBAL_START + 31) +#define MPFS_IRQ_GPIO1_BIT18 (MPFS_IRQ_GLOBAL_START + 32) +#define MPFS_IRQ_GPIO1_BIT19 (MPFS_IRQ_GLOBAL_START + 33) +#define MPFS_IRQ_GPIO1_BIT20 (MPFS_IRQ_GLOBAL_START + 34) +#define MPFS_IRQ_GPIO1_BIT21 (MPFS_IRQ_GLOBAL_START + 35) +#define MPFS_IRQ_GPIO1_BIT22 (MPFS_IRQ_GLOBAL_START + 36) +#define MPFS_IRQ_GPIO1_BIT23 (MPFS_IRQ_GLOBAL_START + 37) +#define MPFS_IRQ_GPIO0_NON_DIRECT (MPFS_IRQ_GLOBAL_START + 38) +#define MPFS_IRQ_GPIO1_NON_DIRECT (MPFS_IRQ_GLOBAL_START + 39) +#define MPFS_IRQ_GPIO2_NON_DIRECT (MPFS_IRQ_GLOBAL_START + 40) +#define MPFS_IRQ_SPI0 (MPFS_IRQ_GLOBAL_START + 41) +#define MPFS_IRQ_SPI1 (MPFS_IRQ_GLOBAL_START + 42) +#define MPFS_IRQ_CAN0 (MPFS_IRQ_GLOBAL_START + 43) +#define MPFS_IRQ_CAN1 (MPFS_IRQ_GLOBAL_START + 44) +#define MPFS_IRQ_I2C0_MAIN (MPFS_IRQ_GLOBAL_START + 45) +#define MPFS_IRQ_I2C0_ALERT (MPFS_IRQ_GLOBAL_START + 46) +#define MPFS_IRQ_I2C0_SUS (MPFS_IRQ_GLOBAL_START + 47) +#define MPFS_IRQ_I2C1_MAIN (MPFS_IRQ_GLOBAL_START + 48) +#define MPFS_IRQ_I2C1_ALERT (MPFS_IRQ_GLOBAL_START + 49) +#define MPFS_IRQ_I2C1_SUS (MPFS_IRQ_GLOBAL_START + 50) +#define MPFS_IRQ_MAC0_INT (MPFS_IRQ_GLOBAL_START + 51) +#define MPFS_IRQ_MAC0_QUEUE1 (MPFS_IRQ_GLOBAL_START + 52) +#define MPFS_IRQ_MAC0_QUEUE2 (MPFS_IRQ_GLOBAL_START + 53) +#define MPFS_IRQ_MAC0_QUEUE3 (MPFS_IRQ_GLOBAL_START + 54) +#define MPFS_IRQ_MAC0_EMAC (MPFS_IRQ_GLOBAL_START + 55) +#define MPFS_IRQ_MAC0_MMSL (MPFS_IRQ_GLOBAL_START + 56) +#define MPFS_IRQ_MAC1_INT (MPFS_IRQ_GLOBAL_START + 57) +#define MPFS_IRQ_MAC1_QUEUE1 (MPFS_IRQ_GLOBAL_START + 58) +#define MPFS_IRQ_MAC1_QUEUE2 (MPFS_IRQ_GLOBAL_START + 59) +#define MPFS_IRQ_MAC1_QUEUE3 (MPFS_IRQ_GLOBAL_START + 60) +#define MPFS_IRQ_MAC1_EMAC (MPFS_IRQ_GLOBAL_START + 61) +#define MPFS_IRQ_MAC1_MMSL (MPFS_IRQ_GLOBAL_START + 62) +#define MPFS_IRQ_DDRC_TRAIN (MPFS_IRQ_GLOBAL_START + 63) +#define MPFS_IRQ_SCB_INTERRUPT (MPFS_IRQ_GLOBAL_START + 64) +#define MPFS_IRQ_ECC_ERROR (MPFS_IRQ_GLOBAL_START + 65) +#define MPFS_IRQ_ECC_CORRECT (MPFS_IRQ_GLOBAL_START + 66) +#define MPFS_IRQ_RTC_WAKEUP (MPFS_IRQ_GLOBAL_START + 67) +#define MPFS_IRQ_RTC_MATCH (MPFS_IRQ_GLOBAL_START + 68) +#define MPFS_IRQ_TIMER1 (MPFS_IRQ_GLOBAL_START + 69) +#define MPFS_IRQ_TIMER2 (MPFS_IRQ_GLOBAL_START + 70) +#define MPFS_IRQ_ENVM (MPFS_IRQ_GLOBAL_START + 71) +#define MPFS_IRQ_QSPI (MPFS_IRQ_GLOBAL_START + 72) +#define MPFS_IRQ_USB_DMA (MPFS_IRQ_GLOBAL_START + 73) +#define MPFS_IRQ_USB_MC (MPFS_IRQ_GLOBAL_START + 74) +#define MPFS_IRQ_MMC_MAIN (MPFS_IRQ_GLOBAL_START + 75) +#define MPFS_IRQ_MMC_WAKEUP (MPFS_IRQ_GLOBAL_START + 76) +#define MPFS_IRQ_MMUART0 (MPFS_IRQ_GLOBAL_START + 77) +#define MPFS_IRQ_MMUART1 (MPFS_IRQ_GLOBAL_START + 78) +#define MPFS_IRQ_MMUART2 (MPFS_IRQ_GLOBAL_START + 79) +#define MPFS_IRQ_MMUART3 (MPFS_IRQ_GLOBAL_START + 80) +#define MPFS_IRQ_MMUART4 (MPFS_IRQ_GLOBAL_START + 81) +#define MPFS_IRQ_WDOG0_MRVP (MPFS_IRQ_GLOBAL_START + 87) +#define MPFS_IRQ_WDOG1_MRVP (MPFS_IRQ_GLOBAL_START + 88) +#define MPFS_IRQ_WDOG2_MRVP (MPFS_IRQ_GLOBAL_START + 89) +#define MPFS_IRQ_WDOG3_MRVP (MPFS_IRQ_GLOBAL_START + 90) +#define MPFS_IRQ_WDOG4_MRVP (MPFS_IRQ_GLOBAL_START + 91) +#define MPFS_IRQ_WDOG0_TOUT (MPFS_IRQ_GLOBAL_START + 92) +#define MPFS_IRQ_WDOG1_TOUT (MPFS_IRQ_GLOBAL_START + 93) +#define MPFS_IRQ_WDOG2_TOUT (MPFS_IRQ_GLOBAL_START + 94) +#define MPFS_IRQ_WDOG3_TOUT (MPFS_IRQ_GLOBAL_START + 95) +#define MPFS_IRQ_WDOG4_TOUT (MPFS_IRQ_GLOBAL_START + 96) +#define MPFS_IRQ_FABRIC_F2H_0 (MPFS_IRQ_GLOBAL_START + 105) +#define MPFS_IRQ_FABRIC_F2H_1 (MPFS_IRQ_GLOBAL_START + 106) +#define MPFS_IRQ_FABRIC_F2H_2 (MPFS_IRQ_GLOBAL_START + 107) +#define MPFS_IRQ_FABRIC_F2H_3 (MPFS_IRQ_GLOBAL_START + 108) +#define MPFS_IRQ_FABRIC_F2H_4 (MPFS_IRQ_GLOBAL_START + 109) +#define MPFS_IRQ_FABRIC_F2H_5 (MPFS_IRQ_GLOBAL_START + 110) +#define MPFS_IRQ_FABRIC_F2H_6 (MPFS_IRQ_GLOBAL_START + 111) +#define MPFS_IRQ_FABRIC_F2H_7 (MPFS_IRQ_GLOBAL_START + 112) +#define MPFS_IRQ_FABRIC_F2H_8 (MPFS_IRQ_GLOBAL_START + 113) +#define MPFS_IRQ_FABRIC_F2H_9 (MPFS_IRQ_GLOBAL_START + 114) +#define MPFS_IRQ_FABRIC_F2H_10 (MPFS_IRQ_GLOBAL_START + 115) +#define MPFS_IRQ_FABRIC_F2H_11 (MPFS_IRQ_GLOBAL_START + 116) +#define MPFS_IRQ_FABRIC_F2H_12 (MPFS_IRQ_GLOBAL_START + 117) +#define MPFS_IRQ_FABRIC_F2H_13 (MPFS_IRQ_GLOBAL_START + 118) +#define MPFS_IRQ_FABRIC_F2H_14 (MPFS_IRQ_GLOBAL_START + 119) +#define MPFS_IRQ_FABRIC_F2H_15 (MPFS_IRQ_GLOBAL_START + 120) +#define MPFS_IRQ_FABRIC_F2H_16 (MPFS_IRQ_GLOBAL_START + 121) +#define MPFS_IRQ_FABRIC_F2H_17 (MPFS_IRQ_GLOBAL_START + 122) +#define MPFS_IRQ_FABRIC_F2H_18 (MPFS_IRQ_GLOBAL_START + 123) +#define MPFS_IRQ_FABRIC_F2H_19 (MPFS_IRQ_GLOBAL_START + 124) +#define MPFS_IRQ_FABRIC_F2H_20 (MPFS_IRQ_GLOBAL_START + 125) +#define MPFS_IRQ_FABRIC_F2H_21 (MPFS_IRQ_GLOBAL_START + 126) +#define MPFS_IRQ_FABRIC_F2H_22 (MPFS_IRQ_GLOBAL_START + 127) +#define MPFS_IRQ_FABRIC_F2H_23 (MPFS_IRQ_GLOBAL_START + 128) +#define MPFS_IRQ_FABRIC_F2H_24 (MPFS_IRQ_GLOBAL_START + 129) +#define MPFS_IRQ_FABRIC_F2H_25 (MPFS_IRQ_GLOBAL_START + 130) +#define MPFS_IRQ_FABRIC_F2H_26 (MPFS_IRQ_GLOBAL_START + 131) +#define MPFS_IRQ_FABRIC_F2H_27 (MPFS_IRQ_GLOBAL_START + 132) +#define MPFS_IRQ_FABRIC_F2H_28 (MPFS_IRQ_GLOBAL_START + 133) +#define MPFS_IRQ_FABRIC_F2H_29 (MPFS_IRQ_GLOBAL_START + 134) +#define MPFS_IRQ_FABRIC_F2H_30 (MPFS_IRQ_GLOBAL_START + 135) +#define MPFS_IRQ_FABRIC_F2H_31 (MPFS_IRQ_GLOBAL_START + 136) +#define MPFS_IRQ_FABRIC_F2H_32 (MPFS_IRQ_GLOBAL_START + 137) +#define MPFS_IRQ_FABRIC_F2H_33 (MPFS_IRQ_GLOBAL_START + 138) +#define MPFS_IRQ_FABRIC_F2H_34 (MPFS_IRQ_GLOBAL_START + 139) +#define MPFS_IRQ_FABRIC_F2H_35 (MPFS_IRQ_GLOBAL_START + 140) +#define MPFS_IRQ_FABRIC_F2H_36 (MPFS_IRQ_GLOBAL_START + 141) +#define MPFS_IRQ_FABRIC_F2H_37 (MPFS_IRQ_GLOBAL_START + 142) +#define MPFS_IRQ_FABRIC_F2H_38 (MPFS_IRQ_GLOBAL_START + 143) +#define MPFS_IRQ_FABRIC_F2H_39 (MPFS_IRQ_GLOBAL_START + 144) +#define MPFS_IRQ_FABRIC_F2H_40 (MPFS_IRQ_GLOBAL_START + 145) +#define MPFS_IRQ_FABRIC_F2H_41 (MPFS_IRQ_GLOBAL_START + 146) +#define MPFS_IRQ_FABRIC_F2H_42 (MPFS_IRQ_GLOBAL_START + 147) +#define MPFS_IRQ_FABRIC_F2H_43 (MPFS_IRQ_GLOBAL_START + 148) +#define MPFS_IRQ_FABRIC_F2H_44 (MPFS_IRQ_GLOBAL_START + 149) +#define MPFS_IRQ_FABRIC_F2H_45 (MPFS_IRQ_GLOBAL_START + 150) +#define MPFS_IRQ_FABRIC_F2H_46 (MPFS_IRQ_GLOBAL_START + 151) +#define MPFS_IRQ_FABRIC_F2H_47 (MPFS_IRQ_GLOBAL_START + 152) +#define MPFS_IRQ_FABRIC_F2H_48 (MPFS_IRQ_GLOBAL_START + 153) +#define MPFS_IRQ_FABRIC_F2H_49 (MPFS_IRQ_GLOBAL_START + 154) +#define MPFS_IRQ_FABRIC_F2H_50 (MPFS_IRQ_GLOBAL_START + 155) +#define MPFS_IRQ_FABRIC_F2H_51 (MPFS_IRQ_GLOBAL_START + 156) +#define MPFS_IRQ_FABRIC_F2H_52 (MPFS_IRQ_GLOBAL_START + 157) +#define MPFS_IRQ_FABRIC_F2H_53 (MPFS_IRQ_GLOBAL_START + 158) +#define MPFS_IRQ_FABRIC_F2H_54 (MPFS_IRQ_GLOBAL_START + 159) +#define MPFS_IRQ_FABRIC_F2H_55 (MPFS_IRQ_GLOBAL_START + 160) +#define MPFS_IRQ_FABRIC_F2H_56 (MPFS_IRQ_GLOBAL_START + 161) +#define MPFS_IRQ_FABRIC_F2H_57 (MPFS_IRQ_GLOBAL_START + 162) +#define MPFS_IRQ_FABRIC_F2H_58 (MPFS_IRQ_GLOBAL_START + 163) +#define MPFS_IRQ_FABRIC_F2H_59 (MPFS_IRQ_GLOBAL_START + 164) +#define MPFS_IRQ_FABRIC_F2H_60 (MPFS_IRQ_GLOBAL_START + 165) +#define MPFS_IRQ_FABRIC_F2H_61 (MPFS_IRQ_GLOBAL_START + 166) +#define MPFS_IRQ_FABRIC_F2H_62 (MPFS_IRQ_GLOBAL_START + 167) +#define MPFS_IRQ_FABRIC_F2H_63 (MPFS_IRQ_GLOBAL_START + 168) +#define MPFS_IRQ_BUS_ERROR_UNIT_HART_0 (MPFS_IRQ_GLOBAL_START + 169) +#define MPFS_IRQ_BUS_ERROR_UNIT_HART_1 (MPFS_IRQ_GLOBAL_START + 170) +#define MPFS_IRQ_BUS_ERROR_UNIT_HART_2 (MPFS_IRQ_GLOBAL_START + 171) +#define MPFS_IRQ_BUS_ERROR_UNIT_HART_3 (MPFS_IRQ_GLOBAL_START + 172) +#define MPFS_IRQ_BUS_ERROR_UNIT_HART_4 (MPFS_IRQ_GLOBAL_START + 173) + +/* Total number of IRQs */ + +#define NR_IRQS (MPFS_IRQ_BUS_ERROR_UNIT_HART_4 + 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_MPFS_IRQ_H */ diff --git a/arch/risc-v/src/mpfs/Kconfig b/arch/risc-v/src/mpfs/Kconfig new file mode 100755 index 0000000000..3531c9772f --- /dev/null +++ b/arch/risc-v/src/mpfs/Kconfig @@ -0,0 +1,93 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "Polarfire Configuration Options" + +config MPFS_ENABLE_DPFPU + bool "MPFS DP_FPU Support" + default n + select ARCH_HAVE_FPU + select ARCH_HAVE_DPFPU + ---help--- + Enable the RISC-V Double-Precision Floating Point Unit (DP-FPU). + +menu "MPFS Peripheral Support" + +# These "hidden" settings determine whether a peripheral option is available +# for the selected MCU + +config MPFS_HAVE_UART0 + bool + default n + select UART0_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS + +config MPFS_HAVE_UART1 + bool + default n + select UART1_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS + +config MPFS_HAVE_UART2 + bool + default n + select UART2_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS + +config MPFS_HAVE_UART3 + bool + default n + select UART3_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS + +config MPFS_HAVE_UART4 + bool + default n + select UART4_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS + +# These are the peripheral selections proper + +config MPFS_UART0 + bool "UART 0" + default n + select ARCH_HAVE_UART0 + select ARCH_HAVE_SERIAL_TERMIOS + select MPFS_HAVE_UART0 + +config MPFS_UART1 + bool "UART 1" + default n + select ARCH_HAVE_UART1 + select ARCH_HAVE_SERIAL_TERMIOS + select MPFS_HAVE_UART1 + +config MPFS_UART2 + bool "UART 2" + default n + select ARCH_HAVE_UART2 + select ARCH_HAVE_SERIAL_TERMIOS + select MPFS_HAVE_UART2 + +config MPFS_UART3 + bool "UART 3" + default n + select ARCH_HAVE_UART3 + select ARCH_HAVE_SERIAL_TERMIOS + select MPFS_HAVE_UART3 + +config MPFS_UART4 + bool "UART 4" + default n + select ARCH_HAVE_UART4 + select ARCH_HAVE_SERIAL_TERMIOS + select MPFS_HAVE_UART4 + +endmenu + +menu "MPFS Others" + + +endmenu diff --git a/arch/risc-v/src/mpfs/Make.defs b/arch/risc-v/src/mpfs/Make.defs new file mode 100755 index 0000000000..ec15c7482b --- /dev/null +++ b/arch/risc-v/src/mpfs/Make.defs @@ -0,0 +1,63 @@ +############################################################################ +# arch/risc-v/src/mpfs/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 = mpfs_vectors.S + +# Specify our general Assembly files +CHIP_ASRCS = mpfs_head.S + +# Specify C code within the common directory to be included +CMN_CSRCS += riscv_initialize.c riscv_swint.c +CMN_CSRCS += 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_FPU),y) +CMN_ASRCS += riscv_fpu.S +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 = mpfs_allocateheap.c mpfs_clockconfig.c +CHIP_CSRCS += mpfs_idle.c mpfs_irq.c mpfs_irq_dispatch.c +CHIP_CSRCS += mpfs_lowputc.c mpfs_serial.c +CHIP_CSRCS += mpfs_start.c mpfs_timerisr.c +CHIP_CSRCS += mpfs_gpio.c + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += riscv_task_start.c riscv_pthread_start.c +CMN_CSRCS += riscv_signal_dispatch.c riscv_pmp.c +CMN_UASRCS += riscv_signal_handler.S + +CHIP_CSRCS += mpfs_userspace.c +endif diff --git a/arch/risc-v/src/mpfs/chip.h b/arch/risc-v/src/mpfs/chip.h new file mode 100755 index 0000000000..960c76b8f2 --- /dev/null +++ b/arch/risc-v/src/mpfs/chip.h @@ -0,0 +1,32 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/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_MPFS_CHIP_H +#define __ARCH_RISCV_SRC_MPFS_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "mpfs_memorymap.h" + +#endif /* __ARCH_RISCV_SRC_MPFS_CHIP_H */ diff --git a/arch/risc-v/src/mpfs/hardware/mpfs_clint.h b/arch/risc-v/src/mpfs/hardware/mpfs_clint.h new file mode 100755 index 0000000000..a15d849267 --- /dev/null +++ b/arch/risc-v/src/mpfs/hardware/mpfs_clint.h @@ -0,0 +1,42 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/hardware/mpfs_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_MPFS_HARDWARE_MPFS_CLINT_H +#define __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_CLINT_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MPFS_CLINT_MSIP0 (MPFS_CLINT_BASE + 0x0000) +#define MPFS_CLINT_MSIP1 (MPFS_CLINT_BASE + 0x0004) +#define MPFS_CLINT_MSIP2 (MPFS_CLINT_BASE + 0x0008) +#define MPFS_CLINT_MSIP3 (MPFS_CLINT_BASE + 0x000C) +#define MPFS_CLINT_MSIP4 (MPFS_CLINT_BASE + 0x0010) + +#define MPFS_CLINT_MTIMECMP0 (MPFS_CLINT_BASE + 0x4000) +#define MPFS_CLINT_MTIMECMP1 (MPFS_CLINT_BASE + 0x4008) +#define MPFS_CLINT_MTIMECMP2 (MPFS_CLINT_BASE + 0x4010) +#define MPFS_CLINT_MTIMECMP3 (MPFS_CLINT_BASE + 0x4018) +#define MPFS_CLINT_MTIMECMP4 (MPFS_CLINT_BASE + 0x4020) + +#define MPFS_CLINT_MTIME (MPFS_CLINT_BASE + 0xbff8) + +#endif /* __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_CLINT_H */ diff --git a/arch/risc-v/src/mpfs/hardware/mpfs_gpio.h b/arch/risc-v/src/mpfs/hardware/mpfs_gpio.h new file mode 100755 index 0000000000..6f40fcae9b --- /dev/null +++ b/arch/risc-v/src/mpfs/hardware/mpfs_gpio.h @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/hardware/mpfs_gpio.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_MPFS_HARDWARE_MPFS_GPIO_H +#define __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_GPIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "hardware/mpfs_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register offsets *********************************************************/ + +#define MPFS_GPIO_CONFIG_0_OFFSET 0x0000 /* GPIO Config 0 */ +#define MPFS_GPIO_CONFIG_1_OFFSET 0x0004 /* GPIO Config 1 */ +#define MPFS_GPIO_CONFIG_2_OFFSET 0x0008 /* GPIO Config 2 */ +#define MPFS_GPIO_CONFIG_3_OFFSET 0x000C /* GPIO Config 3 */ +#define MPFS_GPIO_CONFIG_4_OFFSET 0x0010 /* GPIO Config 4 */ +#define MPFS_GPIO_CONFIG_5_OFFSET 0x0014 /* GPIO Config 5 */ +#define MPFS_GPIO_CONFIG_6_OFFSET 0x0018 /* GPIO Config 6 */ +#define MPFS_GPIO_CONFIG_7_OFFSET 0x001C /* GPIO Config 7 */ +#define MPFS_GPIO_CONFIG_8_OFFSET 0x0020 /* GPIO Config 8 */ +#define MPFS_GPIO_CONFIG_9_OFFSET 0x0024 /* GPIO Config 9 */ +#define MPFS_GPIO_CONFIG_10_OFFSET 0x0028 /* GPIO Config 10 */ +#define MPFS_GPIO_CONFIG_11_OFFSET 0x002C /* GPIO Config 11 */ +#define MPFS_GPIO_CONFIG_12_OFFSET 0x0020 /* GPIO Config 12 */ +#define MPFS_GPIO_CONFIG_13_OFFSET 0x0024 /* GPIO Config 13 */ +#define MPFS_GPIO_CONFIG_14_OFFSET 0x0028 /* GPIO Config 14 */ +#define MPFS_GPIO_CONFIG_15_OFFSET 0x002C /* GPIO Config 15 */ +#define MPFS_GPIO_CONFIG_16_OFFSET 0x0040 /* GPIO Config 16 */ +#define MPFS_GPIO_CONFIG_17_OFFSET 0x0044 /* GPIO Config 17 */ +#define MPFS_GPIO_CONFIG_18_OFFSET 0x0048 /* GPIO Config 18 */ +#define MPFS_GPIO_CONFIG_19_OFFSET 0x004C /* GPIO Config 19 */ +#define MPFS_GPIO_CONFIG_20_OFFSET 0x0050 /* GPIO Config 20 */ +#define MPFS_GPIO_CONFIG_21_OFFSET 0x0054 /* GPIO Config 21 */ +#define MPFS_GPIO_CONFIG_22_OFFSET 0x0058 /* GPIO Config 22 */ +#define MPFS_GPIO_CONFIG_23_OFFSET 0x005C /* GPIO Config 23 */ +#define MPFS_GPIO_CONFIG_24_OFFSET 0x0060 /* GPIO Config 24 */ +#define MPFS_GPIO_CONFIG_25_OFFSET 0x0064 /* GPIO Config 25 */ +#define MPFS_GPIO_CONFIG_26_OFFSET 0x0068 /* GPIO Config 26 */ +#define MPFS_GPIO_CONFIG_27_OFFSET 0x006C /* GPIO Config 27 */ +#define MPFS_GPIO_CONFIG_28_OFFSET 0x0070 /* GPIO Config 28 */ +#define MPFS_GPIO_CONFIG_29_OFFSET 0x0074 /* GPIO Config 29 */ +#define MPFS_GPIO_CONFIG_30_OFFSET 0x0078 /* GPIO Config 30 */ +#define MPFS_GPIO_CONFIG_31_OFFSET 0x007C /* GPIO Config 31 */ +#define MPFS_GPIO_INTR_OFFSET 0x0080 /* GPIO Irq state */ +#define MPFS_GPIO_GPIN_OFFSET 0x0084 /* GPIO Input states */ +#define MPFS_GPIO_GPOUT_OFFSET 0x0088 /* GPIO Ouput states */ +#define MPFS_GPIO_CONFIG_ALL_OFFSET 0x008C /* GPIO set all configs */ +#define MPFS_GPIO_CONFIG_BYTE0_OFFSET 0x0090 /* GPIO set all configs in byte-0 */ +#define MPFS_GPIO_CONFIG_BYTE1_OFFSET 0x0094 /* GPIO set all configs in byte-1 */ +#define MPFS_GPIO_CONFIG_BYTE2_OFFSET 0x0098 /* GPIO set all configs in byte-3 */ +#define MPFS_GPIO_CONFIG_BYTE3_OFFSET 0x009C /* GPIO set all configs in byte-4 */ +#define MPFS_GPIO_CLEAR_BITS_OFFSET 0x00A0 /* GPIO Clear bits */ +#define MPFS_GPIO_SET_BITS_OFFSET 0x00A4 /* GPIO Set bits */ + +/* Register bit field definitions *******************************************/ + +/* CONFIG_X */ + +#define GPIO_CONFIG_EN_OUT (1 << 0) /* Output enable */ +#define GPIO_CONFIG_EN_IN (1 << 1) /* Input enable */ +#define GPIO_CONFIG_EN_OE_BUF (1 << 2) /* Output buffer enable */ +#define GPIO_CONFIG_EN_INT (1 << 3) /* Interrupt enable */ +#define GPIO_CONFIG_INT_SHIFT (5) /* Bits: 5-7: Interrupt Types */ +#define GPIO_CONFIG_INT_MASK (7) +# define GPIO_CONFIG_INT_HIGH (0 << GPIO_CONFIG_INT_SHIFT) +# define GPIO_CONFIG_INT_LOW (1 << GPIO_CONFIG_INT_SHIFT) +# define GPIO_CONFIG_INT_EDGE_POS (2 << GPIO_CONFIG_INT_SHIFT) +# define GPIO_CONFIG_INT_EDGE_NEG (3 << GPIO_CONFIG_INT_SHIFT) +# define GPIO_CONFIG_INT_EDGE_BOTH (4 << GPIO_CONFIG_INT_SHIFT) + +#endif /* __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_GPIO_H */ diff --git a/arch/risc-v/src/mpfs/hardware/mpfs_memorymap.h b/arch/risc-v/src/mpfs/hardware/mpfs_memorymap.h new file mode 100755 index 0000000000..4d07554114 --- /dev/null +++ b/arch/risc-v/src/mpfs/hardware/mpfs_memorymap.h @@ -0,0 +1,120 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/hardware/mpfs_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_MPFS_HARDWARE_MPFS_MEMORYMAP_H +#define __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_MEMORYMAP_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Base Address ****************************************************/ + +#define MPFS_PLIC_BASE (0x0C000000UL) +#define MPFS_CLINT_BASE (0x02000000UL) + +#define MPFS_UART0_LO_BASE (0x20000000UL) +#define MPFS_WDOG0_LO_BASE (0x20001000UL) +#define MPFS_SYSREG_BASE (0x20002000UL) +#define MPFS_SYSREGSCB_BASE (0x20003000UL) +#define MPFS_AXISW_BASE (0x20004000UL) +#define MPFS_MPUCFG_BASE (0x20005000UL) +#define MPFS_FMETER_BASE (0x20006000UL) +#define MPFS_CFG_DDR_SGMII_PHY_BASE (0x20007000UL) +#define MPFS_EMMC_SD_BASE (0x20008000UL) +#define MPFS_DDRCFG_BASE (0x20080000UL) +#define MPFS_UART1_LO_BASE (0x20100000UL) +#define MPFS_WDOG1_LO_BASE (0x20101000UL) +#define MPFS_UART2_LO_BASE (0x20102000UL) +#define MPFS_WDOG2_LO_BASE (0x20103000UL) +#define MPFS_UART3_LO_BASE (0x20104000UL) +#define MPFS_WDOG3_LO_BASE (0x20105000UL) +#define MPFS_UART4_LO_BASE (0x20106000UL) +#define MPFS_WDOG4_LO_BASE (0x20107000UL) +#define MPFS_SPI0_LO_BASE (0x20108000UL) +#define MPFS_SPI1_LO_BASE (0x20109000UL) +#define MPFS_I2C0_LO_BASE (0x2010A000UL) +#define MPFS_I2C1_LO_BASE (0x2010B000UL) +#define MPFS_CAN0_LO_BASE (0x2010C000UL) +#define MPFS_CAN1_LO_BASE (0x2010D000UL) +#define MPFS_GEM0_LO_BASE (0x20110000UL) +#define MPFS_GEM1_LO_BASE (0x20112000UL) +#define MPFS_GPIO0_LO_BASE (0x20120000UL) +#define MPFS_GPIO1_LO_BASE (0x20121000UL) +#define MPFS_GPIO2_LO_BASE (0x20122000UL) +#define MPFS_MSRTC_LO_BASE (0x20124000UL) +#define MPFS_MSTIMER_LO_BASE (0x20125000UL) +#define MPFS_H2FINT_LO_BASE (0x20126000UL) +#define MPFS_CRYPTO_BASE (0x20127000UL) +#define MPFS_ENVMCFG_BASE (0x20200000UL) +#define MPFS_USB_BASE (0x20201000UL) +#define MPFS_QSPIXIP_BASE (0x21000000UL) +#define MPFS_ATHENA_BASE (0x22000000UL) +#define MPFS_TRACE_BASE (0x23000000UL) + +/* These are high base */ + +#define MPFS_UART0_HI_BASE (0x28000000UL) +#define MPFS_WDOG0_HI_BASE (0x28001000UL) +#define MPFS_UART1_HI_BASE (0x28100000UL) +#define MPFS_WDOG1_HI_BASE (0x28101000UL) +#define MPFS_UART2_HI_BASE (0x28102000UL) +#define MPFS_WDOG2_HI_BASE (0x28103000UL) +#define MPFS_UART3_HI_BASE (0x28104000UL) +#define MPFS_WDOG3_HI_BASE (0x28105000UL) +#define MPFS_UART4_HI_BASE (0x28106000UL) +#define MPFS_WDOG4_HI_BASE (0x28107000UL) +#define MPFS_SPI0_HI_BASE (0x28108000UL) +#define MPFS_SPI1_HI_BASE (0x28109000UL) +#define MPFS_I2C0_HI_BASE (0x2810A000UL) +#define MPFS_I2C1_HI_BASE (0x2810B000UL) +#define MPFS_CAN0_HI_BASE (0x2810C000UL) +#define MPFS_CAN1_HI_BASE (0x2810D000UL) +#define MPFS_GEM0_HI_BASE (0x28110000UL) +#define MPFS_GEM1_HI_BASE (0x28112000UL) +#define MPFS_GPIO0_HI_BASE (0x28120000UL) +#define MPFS_GPIO1_HI_BASE (0x28121000UL) +#define MPFS_GPIO2_HI_BASE (0x28122000UL) +#define MPFS_MSRTC_HI_BASE (0x28124000UL) +#define MPFS_MSTIMER_HI_BASE (0x28125000UL) +#define MPFS_H2FINT_HI_BASE (0x28126000UL) + +#define MPFS_IOSCBCFG_BASE (0x37080000UL) + +/* TODO: How to select if peripheral is on HI base address kconfig? + * + * On PolarFire SoC an AXI switch forms a bus matrix interconnect among + * multiple masters and multiple slaves. Five RISC-V CPUs connect to the + * Master ports M10 to M14 of the AXI switch. By default, all the APB + * peripherals are accessible on AXI-Slave 5 of the AXI switch via the AXI to + * AHB and AHB to APB bridges (referred as main APB bus). + * However, to support logical separation in the Asymmetric Multi-Processing + * (AMP) mode of operation, the APB peripherals can alternatively be accessed + * on the AXI-Slave 6 via the AXI to AHB and AHB to APB bridges + * (referred as the AMP APB bus). + */ + +#define MPFS_UART0_BASE MPFS_UART0_LO_BASE +#define MPFS_UART1_BASE MPFS_UART1_LO_BASE +#define MPFS_UART2_BASE MPFS_UART2_LO_BASE +#define MPFS_UART3_BASE MPFS_UART3_LO_BASE +#define MPFS_UART4_BASE MPFS_UART4_LO_BASE + +#endif /* __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_MEMORYMAP_H */ diff --git a/arch/risc-v/src/mpfs/hardware/mpfs_plic.h b/arch/risc-v/src/mpfs/hardware/mpfs_plic.h new file mode 100755 index 0000000000..1789524436 --- /dev/null +++ b/arch/risc-v/src/mpfs/hardware/mpfs_plic.h @@ -0,0 +1,131 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/hardware/mpfs_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_MPFS_HARDWARE_MPFS_PLIC_H +#define __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_PLIC_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* following 187 uint32_t for irq priority */ + +#define MPFS_PLIC_PRIORITY (MPFS_PLIC_BASE + 0x000000) + +#define MPFS_PLIC_IP0 (MPFS_PLIC_BASE + 0x001000) +#define MPFS_PLIC_IP1 (MPFS_PLIC_BASE + 0x001004) +#define MPFS_PLIC_IP2 (MPFS_PLIC_BASE + 0x001008) +#define MPFS_PLIC_IP3 (MPFS_PLIC_BASE + 0x00100C) +#define MPFS_PLIC_IP4 (MPFS_PLIC_BASE + 0x001010) +#define MPFS_PLIC_I51 (MPFS_PLIC_BASE + 0x001014) + +#define MPFS_HART_MIE_OFFSET (0x100) + +#define MPFS_PLIC_H0_MIE0 (MPFS_PLIC_BASE + 0x002000) +#define MPFS_PLIC_H0_MIE1 (MPFS_PLIC_BASE + 0x002004) +#define MPFS_PLIC_H0_MIE2 (MPFS_PLIC_BASE + 0x002008) +#define MPFS_PLIC_H0_MIE3 (MPFS_PLIC_BASE + 0x00200C) +#define MPFS_PLIC_H0_MIE4 (MPFS_PLIC_BASE + 0x002010) +#define MPFS_PLIC_H0_MIE5 (MPFS_PLIC_BASE + 0x002014) + +#define MPFS_PLIC_H1_MIE0 (MPFS_PLIC_BASE + 0x002080) +#define MPFS_PLIC_H1_MIE1 (MPFS_PLIC_BASE + 0x002084) +#define MPFS_PLIC_H1_MIE2 (MPFS_PLIC_BASE + 0x002088) +#define MPFS_PLIC_H1_MIE3 (MPFS_PLIC_BASE + 0x00208C) +#define MPFS_PLIC_H1_MIE4 (MPFS_PLIC_BASE + 0x002090) +#define MPFS_PLIC_H1_MIE5 (MPFS_PLIC_BASE + 0x002094) +#define MPFS_PLIC_H1_SIE0 (MPFS_PLIC_BASE + 0x002100) +#define MPFS_PLIC_H1_SIE1 (MPFS_PLIC_BASE + 0x002104) +#define MPFS_PLIC_H1_SIE2 (MPFS_PLIC_BASE + 0x002108) +#define MPFS_PLIC_H1_SIE3 (MPFS_PLIC_BASE + 0x00210C) +#define MPFS_PLIC_H1_SIE4 (MPFS_PLIC_BASE + 0x002110) +#define MPFS_PLIC_H1_SIE5 (MPFS_PLIC_BASE + 0x002114) + +#define MPFS_PLIC_H2_MIE0 (MPFS_PLIC_BASE + 0x002180) +#define MPFS_PLIC_H2_MIE1 (MPFS_PLIC_BASE + 0x002184) +#define MPFS_PLIC_H2_MIE2 (MPFS_PLIC_BASE + 0x002188) +#define MPFS_PLIC_H2_MIE3 (MPFS_PLIC_BASE + 0x00218C) +#define MPFS_PLIC_H2_MIE4 (MPFS_PLIC_BASE + 0x002190) +#define MPFS_PLIC_H2_MIE5 (MPFS_PLIC_BASE + 0x002194) +#define MPFS_PLIC_H2_SIE0 (MPFS_PLIC_BASE + 0x002200) +#define MPFS_PLIC_H2_SIE1 (MPFS_PLIC_BASE + 0x002204) +#define MPFS_PLIC_H2_SIE2 (MPFS_PLIC_BASE + 0x002208) +#define MPFS_PLIC_H2_SIE3 (MPFS_PLIC_BASE + 0x00220C) +#define MPFS_PLIC_H2_SIE4 (MPFS_PLIC_BASE + 0x002210) +#define MPFS_PLIC_H2_SIE5 (MPFS_PLIC_BASE + 0x002214) + +#define MPFS_PLIC_H3_MIE0 (MPFS_PLIC_BASE + 0x002280) +#define MPFS_PLIC_H3_MIE1 (MPFS_PLIC_BASE + 0x002284) +#define MPFS_PLIC_H3_MIE2 (MPFS_PLIC_BASE + 0x002288) +#define MPFS_PLIC_H3_MIE3 (MPFS_PLIC_BASE + 0x00228C) +#define MPFS_PLIC_H3_MIE4 (MPFS_PLIC_BASE + 0x002290) +#define MPFS_PLIC_H3_MIE5 (MPFS_PLIC_BASE + 0x002294) +#define MPFS_PLIC_H3_SIE0 (MPFS_PLIC_BASE + 0x002300) +#define MPFS_PLIC_H3_SIE1 (MPFS_PLIC_BASE + 0x002304) +#define MPFS_PLIC_H3_SIE2 (MPFS_PLIC_BASE + 0x002308) +#define MPFS_PLIC_H3_SIE3 (MPFS_PLIC_BASE + 0x00230C) +#define MPFS_PLIC_H3_SIE4 (MPFS_PLIC_BASE + 0x002310) +#define MPFS_PLIC_H3_SIE5 (MPFS_PLIC_BASE + 0x002314) + +#define MPFS_PLIC_H4_MIE0 (MPFS_PLIC_BASE + 0x002380) +#define MPFS_PLIC_H4_MIE1 (MPFS_PLIC_BASE + 0x002384) +#define MPFS_PLIC_H4_MIE2 (MPFS_PLIC_BASE + 0x002388) +#define MPFS_PLIC_H4_MIE3 (MPFS_PLIC_BASE + 0x00238C) +#define MPFS_PLIC_H4_MIE4 (MPFS_PLIC_BASE + 0x002390) +#define MPFS_PLIC_H4_MIE5 (MPFS_PLIC_BASE + 0x002394) +#define MPFS_PLIC_H4_SIE0 (MPFS_PLIC_BASE + 0x002400) +#define MPFS_PLIC_H4_SIE1 (MPFS_PLIC_BASE + 0x002404) +#define MPFS_PLIC_H4_SIE2 (MPFS_PLIC_BASE + 0x002408) +#define MPFS_PLIC_H4_SIE3 (MPFS_PLIC_BASE + 0x00240C) +#define MPFS_PLIC_H4_SIE4 (MPFS_PLIC_BASE + 0x002410) +#define MPFS_PLIC_H4_SIE5 (MPFS_PLIC_BASE + 0x002414) + +#define MPFS_PLIC_CTRL (MPFS_PLIC_BASE + 0x1FFFFC) + +#define MPFS_PLIC_NEXTHART_OFFSET (0x2000) +#define MPFS_PLIC_MTHRESHOLD_OFFSET (0x0000) +#define MPFS_PLIC_MCLAIM_OFFSET (0x0004) +#define MPFS_PLIC_STHRESHOLD_OFFSET (0x1000) +#define MPFS_PLIC_SCLAIM_OFFSET (0x1004) + +#define MPFS_PLIC_H0_MTHRESHOLD (MPFS_PLIC_BASE + 0x200000) +#define MPFS_PLIC_H0_MCLAIM (MPFS_PLIC_BASE + 0x200004) + +#define MPFS_PLIC_H1_MTHRESHOLD (MPFS_PLIC_BASE + 0x201000) +#define MPFS_PLIC_H1_MCLAIM (MPFS_PLIC_BASE + 0x201004) +#define MPFS_PLIC_H1_STHRESHOLD (MPFS_PLIC_BASE + 0x202000) +#define MPFS_PLIC_H1_SCLAIM (MPFS_PLIC_BASE + 0x202004) + +#define MPFS_PLIC_H2_MTHRESHOLD (MPFS_PLIC_BASE + 0x203000) +#define MPFS_PLIC_H2_MCLAIM (MPFS_PLIC_BASE + 0x203004) +#define MPFS_PLIC_H2_STHRESHOLD (MPFS_PLIC_BASE + 0x204000) +#define MPFS_PLIC_H2_SCLAIM (MPFS_PLIC_BASE + 0x204004) + +#define MPFS_PLIC_H3_MTHRESHOLD (MPFS_PLIC_BASE + 0x205000) +#define MPFS_PLIC_H3_MCLAIM (MPFS_PLIC_BASE + 0x205004) +#define MPFS_PLIC_H3_STHRESHOLD (MPFS_PLIC_BASE + 0x206000) +#define MPFS_PLIC_H3_SCLAIM (MPFS_PLIC_BASE + 0x206004) + +#define MPFS_PLIC_H4_MTHRESHOLD (MPFS_PLIC_BASE + 0x207000) +#define MPFS_PLIC_H4_MCLAIM (MPFS_PLIC_BASE + 0x207004) +#define MPFS_PLIC_H4_STHRESHOLD (MPFS_PLIC_BASE + 0x208000) +#define MPFS_PLIC_H4_SCLAIM (MPFS_PLIC_BASE + 0x208004) + +#endif /* __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_PLIC_H */ diff --git a/arch/risc-v/src/mpfs/hardware/mpfs_sysctl.h b/arch/risc-v/src/mpfs/hardware/mpfs_sysctl.h new file mode 100755 index 0000000000..a8d51039dc --- /dev/null +++ b/arch/risc-v/src/mpfs/hardware/mpfs_sysctl.h @@ -0,0 +1,34 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/hardware/mpfs_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_MPFS_HARDWARE_MPFS_SYSCTL_H +#define __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_SYSCTL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#endif /* __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_SYSCTL_H */ diff --git a/arch/risc-v/src/mpfs/hardware/mpfs_uart.h b/arch/risc-v/src/mpfs/hardware/mpfs_uart.h new file mode 100755 index 0000000000..2d3b0ccf91 --- /dev/null +++ b/arch/risc-v/src/mpfs/hardware/mpfs_uart.h @@ -0,0 +1,207 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/hardware/mpfs_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_MPFS_HARDWARE_MPFS_UART_H +#define __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_UART_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "hardware/mpfs_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register offsets *********************************************************/ + +#define MPFS_UART_RBR_OFFSET 0x0000 /* UART Receive Buffer Register */ +#define MPFS_UART_THR_OFFSET 0x0000 /* UART Transmit Holding Register */ +#define MPFS_UART_DLL_OFFSET 0x0000 /* UART Divisor Latch Low Register */ +#define MPFS_UART_DLH_OFFSET 0x0004 /* UART Divisor Latch High Register */ +#define MPFS_UART_IER_OFFSET 0x0004 /* UART Interrupt Enable Register */ +#define MPFS_UART_IIR_OFFSET 0x0008 /* UART Interrupt Identity Register */ +#define MPFS_UART_FCR_OFFSET 0x0008 /* UART FIFO Control Register */ +#define MPFS_UART_LCR_OFFSET 0x000c /* UART Line Control Register */ +#define MPFS_UART_MCR_OFFSET 0x0010 /* UART Modem Control Register */ +#define MPFS_UART_LSR_OFFSET 0x0014 /* UART Line Status Register */ +#define MPFS_UART_MSR_OFFSET 0x0018 /* UART Modem Status Register */ +#define MPFS_UART_SCH_OFFSET 0x001c /* UART Scratch Register */ +#define MPFS_UART_IEM_OFFSET 0x0024 /* UART Multi-mode interrupt enable register */ +#define MPFS_UART_IIM_OFFSET 0x0028 /* UART Multi-mode interrupt identification register */ +#define MPFS_UART_MM0_OFFSET 0x0030 /* UART Multi-mode control register 0 */ +#define MPFS_UART_MM1_OFFSET 0x0034 /* UART Multi-mode control register 1 */ +#define MPFS_UART_MM2_OFFSET 0x0038 /* UART Multi-mode control register 2 */ +#define MPFS_UART_DFR_OFFSET 0x003C /* UART Fractional divisor register */ +#define MPFS_UART_GFR_OFFSET 0x0044 /* UART Glitch filter register */ +#define MPFS_UART_TTG_OFFSET 0x0048 /* UART Transmitter time guard register */ +#define MPFS_UART_RTO_OFFSET 0x004C /* UART Receiver time-out register */ +#define MPFS_UART_ADR_OFFSET 0x0050 /* UART Address register */ + +/* Register virtual addresses ***********************************************/ + +#define MPFS250_UART0_VADDR MPFS_UART0_BASE +#define MPFS250_UART1_VADDR MPFS_UART1_BASE +#define MPFS250_UART2_VADDR MPFS_UART2_BASE +#define MPFS250_UART3_VADDR MPFS_UART3_BASE +#define MPFS250_UART4_VADDR MPFS_UART4_BASE + +/* Register bit field definitions *******************************************/ + +/* UART Receive Buffer Register */ + +#define UART_RBR_MASK 0x000000ff + +/* UART Transmit Holding Register */ + +#define UART_THR_MASK 0x000000ff + +/* UART Divisor Latch Low Register */ + +#define UART_DLL_MASK 0x000000ff + +/* UART Divisor Latch High Register */ + +#define UART_DLH_MASK 0x000000ff + +/* UART Interrupt Enable Register */ + +#define UART_IER_ERBFI (1 << 0) /* Bit 0: Enable Received Data Available Interrupt */ +#define UART_IER_ETBEI (1 << 1) /* Bit 1: Enable Transmit Holding Register Empty Interrupt */ +#define UART_IER_ELSI (1 << 2) /* Bit 2: Enable Receiver Line Status Interrupt */ +#define UART_IER_EDSSI (1 << 3) /* Bit 3: Enable Modem Status Interrupt */ +#define UART_IER_PTIME (1 << 7) /* Bit 7: Programmable THRE Interrupt Mode Enable */ +#define UART_IER_ALLIE 0x0000008f + +/* UART Interrupt Identity Register */ + +#define UART_IIR_IID_SHIFT (0) /* Bits: 0-3: Interrupt ID */ +#define UART_IIR_IID_MASK (15 << UART_IIR_IID_SHIFT) +# define UART_IIR_IID_MODEM (0 << UART_IIR_IID_SHIFT) /* Modem status */ +# define UART_IIR_IID_NONE (1 << UART_IIR_IID_SHIFT) /* No interrupt pending */ +# define UART_IIR_IID_TXEMPTY (2 << UART_IIR_IID_SHIFT) /* THR empty */ +# define UART_IIR_IID_RECV (4 << UART_IIR_IID_SHIFT) /* Received data available */ +# define UART_IIR_IID_LINESTATUS (6 << UART_IIR_IID_SHIFT) /* Receiver line status */ +# define UART_IIR_IID_TIMEOUT (12 << UART_IIR_IID_SHIFT) /* Character timeout */ + +#define UART_IIR_FEFLAG_SHIFT (6) /* Bits 6-7: FIFOs Enable Flag */ +#define UART_IIR_FEFLAG_MASK (3 << UART_IIR_FEFLAG_SHIFT) +# define UART_IIR_FEFLAG_DISABLE (0 << UART_IIR_FEFLAG_SHIFT) +# define UART_IIR_FEFLAG_ENABLE (3 << UART_IIR_FEFLAG_SHIFT) + +/* UART FIFO Control Register */ + +#define UART_FCR_FIFOE (1 << 0) /* Bit 0: Enable FIFOs */ +#define UART_FCR_RFIFOR (1 << 1) /* Bit 1: RCVR FIFO Reset */ +#define UART_FCR_XFIFOR (1 << 2) /* Bit 2: XMIT FIFO reset */ +#define UART_FCR_DMAM (1 << 3) /* Bit 3: DMA mode */ +#define UART_FCR_TFT_SHIFT (4) /* Bits 4-5: TX Empty Trigger */ +#define UART_FCR_TFT_MASK (3 << UART_FCR_TFT_SHIFT) +# define UART_FCR_TFT_EMPTY (0 << UART_FCR_TFT_SHIFT) /* FIFO empty */ +# define UART_FCR_TFT_TWO (1 << UART_FCR_TFT_SHIFT) /* 2 characters in the FIFO */ +# define UART_FCR_TFT_QUARTER (2 << UART_FCR_TFT_SHIFT) /* FIFO 1/4 full */ +# define UART_FCR_TFT_HALF (3 << UART_FCR_TFT_SHIFT) /* FIFO 1/2 full */ + +#define UART_FCR_RT_SHIFT (6) /* Bits 6-7: RCVR Trigger */ +#define UART_FCR_RT_MASK (3 << UART_FCR_RT_SHIFT) +# define UART_FCR_RT_ONE (0 << UART_FCR_RT_SHIFT) /* 1 character in the FIFO */ +# define UART_FCR_RT_QUARTER (1 << UART_FCR_RT_SHIFT) /* FIFO 1/4 full */ +# define UART_FCR_RT_HALF (2 << UART_FCR_RT_SHIFT) /* FIFO 1/2 full */ +# define UART_FCR_RT_MINUS2 (3 << UART_FCR_RT_SHIFT) /* FIFO-2 less than full */ + +/* UART Line Control Register */ + +#define UART_LCR_DLS_SHIFT (0) /* Bits 0-1: Data Length Select */ +#define UART_LCR_DLS_MASK (3 << UART_LCR_DLS_SHIFT) +# define UART_LCR_DLS_5BITS (0 << UART_LCR_DLS_SHIFT) /* 5 bits */ +# define UART_LCR_DLS_6BITS (1 << UART_LCR_DLS_SHIFT) /* 6 bits */ +# define UART_LCR_DLS_7BITS (2 << UART_LCR_DLS_SHIFT) /* 7 bits */ +# define UART_LCR_DLS_8BITS (3 << UART_LCR_DLS_SHIFT) /* 8 bits */ + +#define UART_LCR_STOP (1 << 2) /* Bit 2: Number of stop bits */ +#define UART_LCR_PEN (1 << 3) /* Bit 3: Parity Enable */ +#define UART_LCR_EPS (1 << 4) /* Bit 4: Even Parity Select */ +#define UART_LCR_BC (1 << 6) /* Bit 6: Break Control Bit */ +#define UART_LCR_DLAB (1 << 7) /* Bit 7: Divisor Latch Access Bit */ + +/* UART Modem Control Register */ + +#define UART_MCR_DTR (1 << 0) /* Bit 0: Data Terminal Ready */ +#define UART_MCR_RTS (1 << 1) /* Bit 1: Request to Send */ +#define UART_MCR_LOOP (1 << 4) /* Bit 4: Loop Back Mode */ +#define UART_MCR_AFCE (1 << 5) /* Bit 5: Auto Flow Control Enable */ +#define UART_MCR_SIRE (1 << 6) /* Bit 6: SIR Mode Enable */ + +/* UART Line Status Register */ + +#define UART_LSR_DR (1 << 0) /* Bit 0: Data Ready */ +#define UART_LSR_OE (1 << 1) /* Bit 1: Overrun Error */ +#define UART_LSR_PE (1 << 2) /* Bit 2: Parity Error */ +#define UART_LSR_FE (1 << 3) /* Bit 3: Framing Error */ +#define UART_LSR_BI (1 << 4) /* Bit 4: Break Interrupt */ +#define UART_LSR_THRE (1 << 5) /* Bit 5: TX Holding Register Empty */ +#define UART_LSR_TEMT (1 << 6) /* Bit 6: Transmitter Empty */ +#define UART_LSR_FIFOERR (1 << 7) /* Bit 7: RX Data Error in FIFO */ + +/* UART Modem Status Register */ + +#define UART_MSR_DCTS (1 << 0) /* Bit 0: Delta Clear to Send */ +#define UART_MSR_DDSR (1 << 1) /* Bit 1: Delta Data Set Ready */ +#define UART_MSR_TERI (1 << 2) /* Bit 2: Trailing Edge Ring Indicator */ +#define UART_MSR_DDCD (1 << 3) /* Bit 3: Delta Data Carrier Detect */ +#define UART_MSR_CTS (1 << 4) /* Bit 4: Line State of Clear To Send */ +#define UART_MSR_DSR (1 << 5) /* Bit 5: Line State of Data Set Ready */ +#define UART_MSR_RI (1 << 6) /* Bit 6: Line State of Ring Indicator */ +#define UART_MSR_DCD (1 << 7) /* Bit 7: Line State of Data Carrier Detect */ + +/* UART Scratch Register */ + +#define UART_SCH_MASK 0x000000ff + +/* UART Status Register */ + +#define UART_USR_BUSY (1 << 0) /* Bit 0: UART Busy Bit */ +#define UART_USR_TFNF (1 << 1) /* Bit 1: Transmit FIFO Not Full */ +#define UART_USR_TFE (1 << 2) /* Bit 2: Transmit FIFO Empty */ +#define UART_USR_RFNE (1 << 3) /* Bit 3: Receive FIFO Not Empty */ +#define UART_USR_RFF (1 << 4) /* Bit 4: Receive FIFO Full */ + +/* UART Transmit FIFO Level */ + +#define UART_TFL_SHIFT (0) /* Bits 0-6: Transmit FIFO Level */ +#define UART_TFL_MASK (0x7f << UART_TFL_SHIFT) +# define UART_TFL(n) ((uint32_t)(n) << UART_TFL_SHIFT) + +/* UART Receive FIFO Level */ + +#define UART_RFL_SHIFT (0) /* Bits 0-6: Receive FIFO Level */ +#define UART_RFL_MASK (0x7f << UART_RFL_SHIFT) +# define UART_RFL(n) ((uint32_t)(n) << UART_RFL_SHIFT) + +/* Multimode register 0 */ + +#define UART_MM0_ELIN (1 << 3) /* Bit 3: Enable LIN header detection */ +#define UART_MM0_ETIG (1 << 5) /* Bit 5: Enable transmitter time guard */ +#define UART_MM0_ERTO (1 << 6) /* Bit 6: Enable receiver time-out */ +#define UART_MM0_EFBR (1 << 7) /* Bit 7: Enable fractional baud rate mode */ + +#endif /* __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_UART_H */ diff --git a/arch/risc-v/src/mpfs/mpfs.h b/arch/risc-v/src/mpfs/mpfs.h new file mode 100755 index 0000000000..8d78f2c606 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs.h @@ -0,0 +1,38 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs.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_MPFS_MPFS_H +#define __ARCH_RISCV_SRC_MPFS_MPFS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include "chip.h" +#include "mpfs_lowputc.h" +#include "riscv_internal.h" +#include + +#endif /* __ARCH_RISCV_SRC_MPFS_MPFS_H */ diff --git a/arch/risc-v/src/mpfs/mpfs_allocateheap.c b/arch/risc-v/src/mpfs/mpfs_allocateheap.c new file mode 100755 index 0000000000..c6bb153fb8 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_allocateheap.c @@ -0,0 +1,132 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_allocateheap.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "mpfs.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define KRAM_END CONFIG_RAM_END + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + * The following memory map is assumed for the flat build: + * + * .data region. Size determined at link time. + * .bss region Size determined at link time. + * IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Heap. Extends to the end of User SRAM. + * + * The following memory map is assumed for the protect build. + * The kernel and user space have it's own dedicated heap space. + * + * User .data region Size determined at link time + * User .bss region Size determined at link time + * User heap Extends to the end of User SRAM + * Kernel .data region Size determined at link time + * Kernel .bss region Size determined at link time + * Kernel IDLE thread stack Size determined by CONFIG_IDLETHREAD_STACKSIZE + * Kernel heap Size determined by CONFIG_MM_KERNEL_HEAPSIZE + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + /* Get the size and position of the user-space heap. + * This heap begins after the user-space .bss section. + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend; + size_t usize = (uintptr_t)USERSPACE->us_heapend - ubase; + + /* Return the user-space heap settings */ + + *heap_start = (FAR void *)ubase; + *heap_size = usize; + + /* Allow user-mode access to the user heap memory in PMP + * is already done in mpfs_userspace(). + */ + +#else + /* Return the heap settings */ + + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = KRAM_END - g_idle_topstack; +#endif +} + +/**************************************************************************** + * 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) +{ + /* Return the kernel heap settings. */ + + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = KRAM_END - g_idle_topstack; +} +#endif + +/**************************************************************************** + * Name: up_addregion + ****************************************************************************/ + +void up_addregion(void) +{ +} diff --git a/arch/risc-v/src/mpfs/mpfs_clockconfig.c b/arch/risc-v/src/mpfs/mpfs_clockconfig.c new file mode 100755 index 0000000000..90aaee60fd --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_clockconfig.c @@ -0,0 +1,80 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_clockconfig.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "mpfs_clockconfig.h" +#include "riscv_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define OSC_FREQ 80000000UL + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint64_t g_cpu_clock = MPFS_MSS_COREPLEX_CPU_CLK; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpfs_get_cpuclk + ****************************************************************************/ + +uint64_t mpfs_get_cpuclk(void) +{ + return g_cpu_clock; +} + +/**************************************************************************** + * Name: mpfs_get_pll0clk + ****************************************************************************/ + +#ifndef CONFIG_MPFS_WITH_QEMU +uint64_t mpfs_get_pll0clk(void) +{ + return 0; +} +#endif + +/**************************************************************************** + * Name: mpfs_clockconfig + ****************************************************************************/ + +void mpfs_clockconfig(void) +{ + /* All is currently done in bootloader HSS */ +} diff --git a/arch/risc-v/src/mpfs/mpfs_clockconfig.h b/arch/risc-v/src/mpfs/mpfs_clockconfig.h new file mode 100755 index 0000000000..2e317a76be --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_clockconfig.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_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_MPFS_MPFS_CLOCKCONFIG_H +#define __ARCH_RISCV_SRC_MPFS_MPFS_CLOCKCONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "mpfs_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 mpfs_get_cpuclk(void); +EXTERN uint64_t mpfs_get_pll0clk(void); +EXTERN void mpfs_clockconfig(void); + +#if defined(__cplusplus) +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_MPFS_MPFS_CLOCKCONFIG_H */ diff --git a/arch/risc-v/src/mpfs/mpfs_config.h b/arch/risc-v/src/mpfs/mpfs_config.h new file mode 100755 index 0000000000..48020199b6 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_config.h @@ -0,0 +1,68 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_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_MPFS_MPFS_CONFIG_H +#define __ARCH_RISCV_SRC_MPFS_MPFS_CONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_MPFS_UART0) || defined(CONFIG_MPFS_UART1) || \ + defined(CONFIG_MPFS_UART2) || defined(CONFIG_MPFS_UART3) || \ + defined(CONFIG_MPFS_UART4) +# define HAVE_UART_DEVICE 1 +#endif + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_MPFS_UART0) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_MPFS_UART1) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_MPFS_UART2) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_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_MPFS_MPFS_CONFIG_H */ diff --git a/arch/risc-v/src/mpfs/mpfs_gpio.c b/arch/risc-v/src/mpfs/mpfs_gpio.c new file mode 100644 index 0000000000..8e9e74be84 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_gpio.c @@ -0,0 +1,184 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_gpio.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "riscv_arch.h" + +#include "hardware/mpfs_gpio.h" +#include "mpfs_gpio.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +static uintptr_t g_gpio_base[] = +{ + MPFS_GPIO0_LO_BASE, /* Bank-0 Normal GPIO */ + MPFS_GPIO1_LO_BASE, /* Bank-1 Normal GPIO */ + MPFS_GPIO2_LO_BASE /* Bank-2 Fabric only */ +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpfs_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + * Returned Value: + * OK on success + * ERROR on invalid port. + * + ****************************************************************************/ + +int mpfs_configgpio(gpio_pinset_t cfgset) +{ + uintptr_t baseaddr; + uint32_t cfg = 0; + uint8_t pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + uint8_t bank = (cfgset & GPIO_BANK_MASK) >> GPIO_BANK_SHIFT; + uint8_t irq_mode = (cfgset & GPIO_IRQ_MASK) >> GPIO_IRQ_SHIFT; + + if (bank == 3) + { + return ERROR; + } + + /* REVISIT: limit the gpios as + * bank0 0 - 13 + * bank1 0 - 23 + * bank2 0 - 31 + */ + + baseaddr = g_gpio_base[bank] + (pin * sizeof(uint32_t)); + + if (cfgset & GPIO_INPUT) + { + cfg |= GPIO_CONFIG_EN_IN; + } + + if (cfgset & GPIO_OUTPUT) + { + cfg |= GPIO_CONFIG_EN_OUT; + } + + if (cfgset & GPIO_BUFFER_ENABLE) + { + cfg |= GPIO_CONFIG_EN_OE_BUF; + } + + if (cfgset & GPIO_IRQ_ENABLE) + { + cfg |= GPIO_CONFIG_EN_INT; + + /* Clear irq bit */ + + putreg32(1 << pin, baseaddr + MPFS_GPIO_INTR_OFFSET); + } + + /* set irq mode bits */ + + irq_mode &= 7; + cfg |= irq_mode << 5; + + putreg32(cfg, baseaddr); + + return OK; +} + +/**************************************************************************** + * Name: mpfs_gpio_deinit + * + * Description: + * Deinit a GPIO (Set GPIO to input state) + * + * Returned Value: + * OK on success + * ERROR on invalid port. + * + ****************************************************************************/ + +/* REVISIT: */ + +int mpfs_gpio_deinit(uint8_t pin) +{ + mpfs_configgpio(pin); + return OK; +} + +/**************************************************************************** + * Name: mpfs_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void mpfs_gpiowrite(gpio_pinset_t pinset, bool value) +{ + uint8_t pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + uint8_t bank = (pinset & GPIO_BANK_MASK) >> GPIO_BANK_SHIFT; + uintptr_t baseaddr = g_gpio_base[bank]; + + if (bank == 3) + { + return; + } + + if (value) + { + putreg32((1 << pin), baseaddr + MPFS_GPIO_SET_BITS_OFFSET); + } + else + { + putreg32((1 << pin), baseaddr + MPFS_GPIO_CLEAR_BITS_OFFSET); + } +} + +/**************************************************************************** + * Name: mpfs_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool mpfs_gpioread(gpio_pinset_t pinset) +{ + uint8_t pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + uint8_t bank = (pinset & GPIO_BANK_MASK) >> GPIO_BANK_SHIFT; + uintptr_t baseaddr = g_gpio_base[bank]; + + if (bank == 3) + { + return 0; + } + + return ((getreg32(baseaddr + MPFS_GPIO_GPIN_OFFSET) & (1 << pin)) ? 1 : 0); +} + diff --git a/arch/risc-v/src/mpfs/mpfs_gpio.h b/arch/risc-v/src/mpfs/mpfs_gpio.h new file mode 100644 index 0000000000..2c15ef084e --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_gpio.h @@ -0,0 +1,272 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_gpio.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_MPFS_MPFS_GPIO_H +#define __ARCH_RISCV_SRC_MPFS_MPFS_GPIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +#include +#include +#endif + +#include +#include + +#include "chip.h" +#include "hardware/mpfs_gpio.h" + +/**************************************************************************** + * Pre-Processor Declarations + ****************************************************************************/ + +/* Bit-encoded input to mpfs_configgpio() */ + +/* Each port bit of the general-purpose I/O (GPIO) ports can be individually + * configured by software in several modes: + * + * - Input + * - Output + * - Output with buffer enable + * - Output with buffer disable + * - Input with irq level high + * - Input with irq level low + * - Input with irq edge positive + * - Input with irq edge negative + * + * 16-bit Encoding: 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * MMBI III. .bbP PPPP + */ + +/* Mode: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * MM.. .... .... .... + */ + +#define GPIO_MODE_SHIFT (14) /* Bit 14-15: IO Mode */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_NOINOUT (0 << GPIO_MODE_SHIFT) /* No input or output */ +# define GPIO_INPUT (1 << GPIO_MODE_SHIFT) /* Input Enable */ +# define GPIO_OUTPUT (2 << GPIO_MODE_SHIFT) /* Output Enable */ + +/* Output buffer: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * ..B. .... .... .... + */ + +#define GPIO_BUFFER_SHIFT (13) /* Bit 13: Output buffer enabled */ +#define GPIO_BUFFER_MASK (1 << GPIO_BUFFER_SHIFT) +#define GPIO_BUFFER_DISABLE (0 << GPIO_BUFFER_SHIFT) /* Disable Output buffer */ +#define GPIO_BUFFER_ENABLE (1 << GPIO_BUFFER_SHIFT) /* Enable Output buffer */ + +/* Irq: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * ...I III. .... .... + */ + +#define GPIO_IRQ_SHIFT (9) /* Bits 9-12: Irq Mode */ +#define GPIO_IRQ_MASK (15 << GPIO_IRQ_SHIFT) +#define GPIO_IRQ_HIGH (0 << GPIO_IRQ_SHIFT) +#define GPIO_IRQ_LOW (1 << GPIO_IRQ_SHIFT) +#define GPIO_IRQ_EDGE_POS (2 << GPIO_IRQ_SHIFT) +#define GPIO_IRQ_EDGE_NEG (3 << GPIO_IRQ_SHIFT) +#define GPIO_IRQ_EDGE_BOTH (4 << GPIO_IRQ_SHIFT) +#define GPIO_IRQ_ENABLE (8 << GPIO_IRQ_SHIFT) +#define GPIO_IRQ_DISABLE (0 << GPIO_IRQ_SHIFT) + +/* Bank: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * .... .... .bb. .... + */ + +#define GPIO_BANK_SHIFT (5) /* Bits 5-6: Bank */ +#define GPIO_BANK_MASK (3 << GPIO_BANK_SHIFT) +#define GPIO_BANK0 (0 << GPIO_BANK_SHIFT) +#define GPIO_BANK1 (1 << GPIO_BANK_SHIFT) +#define GPIO_BANK2 (2 << GPIO_BANK_SHIFT) + +/* This identifies the bit in the bank: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * .... .... ...P PPPP + */ + +#define GPIO_PIN_SHIFT (0) /* Bits 0-4: GPIO number: 0-31 */ +#define GPIO_PIN_MASK (0x1f << GPIO_PIN_SHIFT) +#define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +#define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +#define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +#define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +#define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +#define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +#define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +#define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +#define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +#define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +#define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +#define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +#define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +#define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +#define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +#define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) +#define GPIO_PIN16 (16 << GPIO_PIN_SHIFT) +#define GPIO_PIN17 (17 << GPIO_PIN_SHIFT) +#define GPIO_PIN18 (18 << GPIO_PIN_SHIFT) +#define GPIO_PIN19 (19 << GPIO_PIN_SHIFT) +#define GPIO_PIN20 (20 << GPIO_PIN_SHIFT) +#define GPIO_PIN21 (21 << GPIO_PIN_SHIFT) +#define GPIO_PIN22 (22 << GPIO_PIN_SHIFT) +#define GPIO_PIN23 (23 << GPIO_PIN_SHIFT) +#define GPIO_PIN24 (24 << GPIO_PIN_SHIFT) +#define GPIO_PIN25 (25 << GPIO_PIN_SHIFT) +#define GPIO_PIN26 (26 << GPIO_PIN_SHIFT) +#define GPIO_PIN27 (27 << GPIO_PIN_SHIFT) +#define GPIO_PIN28 (28 << GPIO_PIN_SHIFT) +#define GPIO_PIN29 (29 << GPIO_PIN_SHIFT) +#define GPIO_PIN30 (30 << GPIO_PIN_SHIFT) +#define GPIO_PIN31 (31 << GPIO_PIN_SHIFT) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* The smallest integer type that can hold the GPIO encoding */ + +typedef uint16_t gpio_pinset_t; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: mpfs_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + * Returned Value: + * OK on success + * ERROR on invalid port. + * + ****************************************************************************/ + +int mpfs_configgpio(gpio_pinset_t cfgset); + +/**************************************************************************** + * Name: mpfs_gpio_deinit + * + * Description: + * Deinit a GPIO (Set GPIO to floating input state) + * + * Returned Value: + * OK on success + * ERROR on invalid port. + * + ****************************************************************************/ + +int mpfs_gpio_deinit(uint8_t pin); + +/**************************************************************************** + * Name: mpfs_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void mpfs_gpiowrite(gpio_pinset_t pinset, bool value); + +/**************************************************************************** + * Name: mpfs_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool mpfs_gpioread(gpio_pinset_t pinset); + +/**************************************************************************** + * Name: mpfs_gpio_initialize + * + * Description: + * Initialize GPIO drivers for use with /apps/examples/gpio + * + ****************************************************************************/ + +int mpfs_gpio_initialize(void); + +/**************************************************************************** + * Function: mpfs_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO_INFO +int mpfs_dumpgpio(gpio_pinset_t pinset, const char *msg); +#else +#define mpfs_dumpgpio(p, m) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_MPFS_MPFS_GPIO_H */ diff --git a/arch/risc-v/src/mpfs/mpfs_head.S b/arch/risc-v/src/mpfs/mpfs_head.S new file mode 100755 index 0000000000..c99cd9f40a --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_head.S @@ -0,0 +1,328 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_head.S + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "chip.h" +#include "mpfs_memorymap.h" +#include "riscv_internal.h" + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .global exception_common + + /* Imported symbols */ + + .extern __trap_vec + + .section .text + .global __start_mpfs + +__start_mpfs: + + /* invalid all MMU TLB Entry */ + + sfence.vma x0, x0 + + /* 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 + + /* Make sure that mtvec is updated before continuing */ + +1: + csrr t1, mtvec + bne t0, t1, 1b + + /* Init delegation registers, mideleg, medeleg, if a U54 + * These are not initialised by the hardware and come up in a random state + */ + + csrr a0, mhartid + beqz a0, .skip_e51 + csrw mideleg, 0 + csrw medeleg, 0 +.skip_e51: + + /* mscratch must be init to zero- we are not using scratch memory */ + + csrw mscratch, zero + csrw mcause, zero + csrw mepc, zero + li x1, 0 + li x2, 0 + li x3, 0 + li x4, 0 + li x5, 0 + li x6, 0 + li x7, 0 + li x8, 0 + li x9, 0 + li x10, 0 + li x11, 0 + li x12, 0 + li x13, 0 + li x14, 0 + li x15, 0 + li x16, 0 + li x17, 0 + li x18, 0 + li x19, 0 + li x20, 0 + li x21, 0 + li x22, 0 + li x23, 0 + li x24, 0 + li x25, 0 + li x26, 0 + li x27, 0 + li x28, 0 + li x29, 0 + li x30, 0 + li x31, 0 + + /* enable FPU and accelerator if present, setting ignored on E51 + * 15,16 = MSTATUS_XS, 17,18 = MSTATUS_MPRV + * not defined on riscv-v/include/csr.h + */ + + li t0, MSTATUS_FS_DIRTY | (1 << 15) | (1 << 16) | (1 << 17) | (1 << 18) + csrs mstatus, t0 + + /* Init floating point control register to zero. skip if E51 */ + + csrr a0, mhartid + beqz a0, .no_float +#ifdef __riscv_flen + fscsr x0 +#endif +.no_float: + + /* Set stack pointer to the idle thread stack */ + + la sp, MPFS_IDLESTACK_TOP + + +/* initialize global pointer, global data + * The __global_pointer is allocated in the linker script. + * It points to a location between _sdata and _edata as the offsets used in the gp are +/- 2k + * See https://www.sifive.com/blog/2017/08/28/all-aboard-part-3-linker-relaxation-in-riscv-toolchain/ + * see: http://www.rowleydownload.co.uk/arm/documentation/gnu/as/RISC_002dV_002dDirectives.html + */ + +.option push +.option norelax + la gp, __global_pointer$ +.option pop + + +#ifdef CONFIG_STACK_COLORATION + + /* Write a known value to the IDLE thread stack to support stack + * monitoring logic + */ + + la t0, MPFS_IDLESTACK_BASE + la t1, MPFS_IDLESTACK_TOP + li t2, STACK_COLOR + bgeu t0, t1, 2f + + /* t0 = start of IDLE stack; t1 = top of stack; t2 = coloration */ + +1: + sw t2, 0(t0) + addi t0, t0, 4 + bne t0, t1, 1b +2: + +#endif + + /* Jump to __mpfs_start with mhartid in a0 */ + + j __mpfs_start + + /* We shouldn't return from __mpfs_start + * in case of return, loop forever. nop's added so can be seen in debugger + */ + +1: + nop + nop + j 1b + + .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 > 15 + /* Load mhartid (cpuid) */ + + csrr s0, mhartid + + /* Switch to interrupt stack TODO: select correct for hart */ + + la sp, g_intstacktop + +#endif + + /* Call interrupt handler in C */ + + jal x1, mpfs_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 > 15 + .bss + .balign 16 + .global g_intstackalloc + .global g_intstacktop + .type g_intstackalloc, object + .type g_intstacktop, object +g_intstackalloc: + .skip (((CONFIG_ARCH_INTERRUPTSTACK + 8) & ~15)) +g_intstacktop: + .size g_intstacktop, 0 + .size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~15) +#endif diff --git a/arch/risc-v/src/mpfs/mpfs_idle.c b/arch/risc-v/src/mpfs/mpfs_idle.c new file mode 100755 index 0000000000..53960bb527 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_idle.c @@ -0,0 +1,65 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_idle.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "riscv_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + nxsched_process_timer(); +#else + + /* This would be an appropriate place to put some MCU-specific logic to + * sleep in a reduced power mode until an interrupt occurs to save power + */ + + asm("WFI"); + +#endif +} diff --git a/arch/risc-v/src/mpfs/mpfs_irq.c b/arch/risc-v/src/mpfs/mpfs_irq.c new file mode 100755 index 0000000000..64eda61538 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_irq.c @@ -0,0 +1,330 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_irq.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "riscv_internal.h" +#include "riscv_arch.h" + +#include "mpfs.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(); + + /* Disable timer interrupt (in case of hotloading with debugger) */ + + up_disable_irq(MPFS_IRQ_MTIMER); + + /* enable access from supervisor mode */ + + putreg32(0x1, MPFS_PLIC_CTRL); + + /* Disable all global interrupts for current hart */ + + uint64_t hart_id = READ_CSR(mhartid); + + /* hart0 is E51 we can't run on that (need different irq handling) */ + + DEBUGASSERT(hart_id != 0); + + uint32_t *miebase = (uint32_t *)(MPFS_PLIC_H1_MIE0 + + (hart_id - 1) * MPFS_HART_MIE_OFFSET); + + putreg32(0x0, miebase + 0); + putreg32(0x0, miebase + 1); + putreg32(0x0, miebase + 2); + putreg32(0x0, miebase + 3); + putreg32(0x0, miebase + 4); + putreg32(0x0, miebase + 5); + + /* Clear pendings in PLIC (for current hart) */ + + uintptr_t claim_address = MPFS_PLIC_H1_MCLAIM + + ((hart_id - 1) * MPFS_PLIC_NEXTHART_OFFSET); + uint32_t val = getreg32(claim_address); + putreg32(val, claim_address); + + /* Colorize the interrupt stack for debug purposes */ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 15 + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~15); + riscv_stack_color((FAR void *)&g_intstackalloc, 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)(MPFS_PLIC_PRIORITY + (4 * id))); + } + + /* Set irq threshold to 0 (permits all global interrupts) */ + + uint32_t *threshold_address = (uint32_t *)(MPFS_PLIC_H1_MTHRESHOLD + + ((hart_id - 1) * MPFS_PLIC_NEXTHART_OFFSET)); + putreg32(0, threshold_address); + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the ecall interrupt handler */ + + irq_attach(MPFS_IRQ_ECALLM, riscv_swint, NULL); + +#ifdef CONFIG_BUILD_PROTECTED + irq_attach(MPFS_IRQ_ECALLU, riscv_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 == MPFS_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 == MPFS_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 >= MPFS_IRQ_GLOBAL_START) + { + /* REVISIT: + * Comment from baremetal lib: + * OFFSET_TO_MSS_GLOBAL_INTS: + * "Think this was required in early bitfile" + * Seems to be still true with 2021.04 release + */ + + extirq = (irq - MPFS_IRQ_GLOBAL_START) + OFFSET_TO_MSS_GLOBAL_INTS; + + /* Clear enable bit for the irq */ + + uint64_t hart_id = READ_CSR(mhartid); + uintptr_t miebase = MPFS_PLIC_H1_MIE0 + + ((hart_id - 1) * MPFS_HART_MIE_OFFSET); + + if (0 <= extirq && extirq <= NR_IRQS - MPFS_IRQ_GLOBAL_START) + { + modifyreg32(miebase + (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 == MPFS_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 == MPFS_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 >= MPFS_IRQ_GLOBAL_START) + { + /* REVISIT: + * Comment from baremetal lib: + * OFFSET_TO_MSS_GLOBAL_INTS: + * "Think this was required in early bitfile" + * Seems to be still true with 2021.04 release + */ + + extirq = (irq - MPFS_IRQ_GLOBAL_START) + OFFSET_TO_MSS_GLOBAL_INTS; + + /* Set enable bit for the irq */ + + uint64_t hart_id = READ_CSR(mhartid); + uintptr_t miebase = MPFS_PLIC_H1_MIE0 + + ((hart_id - 1) * MPFS_HART_MIE_OFFSET); + + if (0 <= extirq && extirq <= NR_IRQS - MPFS_IRQ_GLOBAL_START) + { + modifyreg32(miebase + (4 * (extirq / 32)), 0, 1 << (extirq % 32)); + } + else + { + ASSERT(false); + } + } +} + +/**************************************************************************** + * Name: riscv_get_newintctx + * + * Description: + * Return initial mstatus when a task is created. + * + ****************************************************************************/ + +uint32_t riscv_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. + */ + +#ifdef CONFIG_ARCH_FPU + return (MSTATUS_FS_INIT | MSTATUS_MPPM | MSTATUS_MPIE); +#else + return (MSTATUS_MPPM | MSTATUS_MPIE); +#endif +} + +/**************************************************************************** + * Name: riscv_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void riscv_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) */ + + asm volatile ("csrrs %0, mie, %1": "=r" (oldstat) : "r"(MIE_MEIE)); + + /* Read mstatus & set machine interrupt enable (MIE) in mstatus */ + + asm volatile ("csrrs %0, mstatus, %1": "=r" (oldstat) : "r"(MSTATUS_MIE)); + return oldstat; +} diff --git a/arch/risc-v/src/mpfs/mpfs_irq_dispatch.c b/arch/risc-v/src/mpfs/mpfs_irq_dispatch.c new file mode 100755 index 0000000000..2632aa6589 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_irq_dispatch.c @@ -0,0 +1,175 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_irq_dispatch.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "riscv_arch.h" +#include "riscv_internal.h" + +#include "group/group.h" +#include "hardware/mpfs_memorymap.h" +#include "hardware/mpfs_plic.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern void up_fault(int irq, uint64_t *regs); + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * mpfs_dispatch_irq + ****************************************************************************/ + +void *mpfs_dispatch_irq(uint64_t vector, uint64_t *regs) +{ + uint32_t irq = (vector & 0x3f); + uint64_t *mepc = regs; + + board_autoled_on(LED_INIRQ); + + /* Check if fault happened */ + + if (vector < MPFS_IRQ_ECALLU || + vector == MPFS_IRQ_INSTRUCTIONPF || + vector == MPFS_IRQ_LOADPF || + vector == MPFS_IRQ_SROREPF || + vector == MPFS_IRQ_RESERVED) + { + up_fault((int)irq, regs); + } + + if (vector & 0x8000000000000000) + { + irq += MPFS_IRQ_ASYNC; + } + + /* Firstly, check if the irq is machine external interrupt */ + + uint64_t hart_id = READ_CSR(mhartid); + uintptr_t claim_address = MPFS_PLIC_H1_MCLAIM + + ((hart_id - 1) * MPFS_PLIC_NEXTHART_OFFSET); + + if (irq == MPFS_IRQ_MEXT) + { + uint32_t ext = getreg32(claim_address); + + /* Add the value to nuttx irq which is offset to the mext */ + + irq = MPFS_IRQ_EXT_START + ext; + } + + /* NOTE: In case of ecall, we need to adjust mepc in the context */ + + if (irq == MPFS_IRQ_ECALLM || irq == MPFS_IRQ_ECALLU) + { + *mepc += 4; + } + + /* Acknowledge the interrupt */ + + riscv_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 (irq != MPFS_IRQ_MEXT && irq != MPFS_IRQ_INVALID) + { + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + } + + if (irq > MPFS_IRQ_EXT_START) + { + /* Then write PLIC_CLAIM to clear pending in PLIC */ + + putreg32(irq - MPFS_IRQ_EXT_START, claim_address); + } + +#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 */ + + riscv_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; + + board_autoled_off(LED_INIRQ); + + return regs; +} diff --git a/arch/risc-v/src/mpfs/mpfs_lowputc.c b/arch/risc-v/src/mpfs/mpfs_lowputc.c new file mode 100755 index 0000000000..a294e72029 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_lowputc.c @@ -0,0 +1,228 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_lowputc.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "riscv_internal.h" +#include "riscv_arch.h" + +#include "hardware/mpfs_memorymap.h" +#include "hardware/mpfs_uart.h" +#include "mpfs.h" +#include "mpfs_clockconfig.h" +#include "mpfs_config.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select UART parameters for the selected console */ +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define MPFS_CONSOLE_BASE MPFS_UART0_BASE +# define MPFS_CONSOLE_BAUD CONFIG_UART0_BAUD +# define MPFS_CONSOLE_BITS CONFIG_UART0_BITS +# define MPFS_CONSOLE_PARITY CONFIG_UART0_PARITY +# define MPFS_CONSOLE_2STOP CONFIG_UART0_2STOP +# define HAVE_UART +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define MPFS_CONSOLE_BASE MPFS_UART1_BASE +# define MPFS_CONSOLE_BAUD CONFIG_UART1_BAUD +# define MPFS_CONSOLE_BITS CONFIG_UART1_BITS +# define MPFS_CONSOLE_PARITY CONFIG_UART1_PARITY +# define MPFS_CONSOLE_2STOP CONFIG_UART1_2STOP +# define HAVE_UART +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define MPFS_CONSOLE_BASE MPFS_UART2_BASE +# define MPFS_CONSOLE_BAUD CONFIG_UART2_BAUD +# define MPFS_CONSOLE_BITS CONFIG_UART2_BITS +# define MPFS_CONSOLE_PARITY CONFIG_UART2_PARITY +# define MPFS_CONSOLE_2STOP CONFIG_UART2_2STOP +# define HAVE_UART +# elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define MPFS_CONSOLE_BASE MPFS_UART3_BASE +# define MPFS_CONSOLE_BAUD CONFIG_UART3_BAUD +# define MPFS_CONSOLE_BITS CONFIG_UART3_BITS +# define MPFS_CONSOLE_PARITY CONFIG_UART3_PARITY +# define MPFS_CONSOLE_2STOP CONFIG_UART3_2STOP +# define HAVE_UART +# elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define MPFS_CONSOLE_BASE MPFS_UART4_BASE +# define MPFS_CONSOLE_BAUD CONFIG_UART4_BAUD +# define MPFS_CONSOLE_BITS CONFIG_UART4BITS +# define MPFS_CONSOLE_PARITY CONFIG_UART4_PARITY +# define MPFS_CONSOLE_2STOP CONFIG_UART4_2STOP +# define HAVE_UART +# elif defined(HAVE_UART) +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +# endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#if !defined(CONFIG_SUPPRESS_UART_CONFIG) + +/**************************************************************************** + * Name: config_baud_divisors + * + * Description: + * Configure the UART baudrate divisors. + * + ****************************************************************************/ + +static void config_baud_divisors(void) +{ + uint32_t baud_value; + uint32_t baud_value_by_64; + uint32_t baud_value_by_128; + uint32_t fractional_baud_value; + uint64_t pclk_freq; + + pclk_freq = MPFS_MSS_APB_AHB_CLK; + + /* Compute baud value based on requested baud rate and PCLK frequency. + * The baud value is computed using the following equation: + * baud_value = PCLK_Frequency / (baud_rate * 16) + */ + + baud_value_by_128 = (uint32_t)((8UL * pclk_freq) / MPFS_CONSOLE_BAUD); + baud_value_by_64 = baud_value_by_128 / 2U; + baud_value = baud_value_by_64 / 64U; + fractional_baud_value = baud_value_by_64 - (baud_value * 64U); + fractional_baud_value += (baud_value_by_128 - (baud_value * 128U)) + - (fractional_baud_value * 2U); + + if (baud_value <= (uint32_t)UINT16_MAX) + { + putreg32(baud_value >> 8, MPFS_CONSOLE_BASE + MPFS_UART_DLH_OFFSET); + putreg32(baud_value & 0xff, MPFS_CONSOLE_BASE + MPFS_UART_DLH_OFFSET); + + if (baud_value > 1) + { + /* Enable Fractional baud rate */ + + uint8_t mm0 = getreg32(MPFS_CONSOLE_BASE + MPFS_UART_MM0_OFFSET); + mm0 |= UART_MM0_EFBR; + putreg32(mm0, MPFS_CONSOLE_BASE + MPFS_UART_MM0_OFFSET); + putreg32(fractional_baud_value, + MPFS_CONSOLE_BASE + MPFS_UART_DFR_OFFSET); + } + } +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: riscv_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void riscv_lowputc(char ch) +{ +#if defined HAVE_UART && defined HAVE_SERIAL_CONSOLE + /* Wait for the transmitter to be available */ + + while ((getreg32(MPFS_CONSOLE_BASE + MPFS_UART_LSR_OFFSET) + & UART_LSR_THRE) == 0); + + /* Send the character */ + + putreg32((uint32_t)ch, MPFS_CONSOLE_BASE + MPFS_UART_THR_OFFSET); +#endif +} + +/**************************************************************************** + * Name: mpfs_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 mpfs_lowsetup(void) +{ +#if defined(HAVE_UART) + + /* Enable and configure the selected console device */ + + /* REVISIT: bringup UART from reset and set clocking. + * Currently done by HSS bootloader + */ + +#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + uint32_t lcr = 0; + + lcr = 0; + switch (MPFS_CONSOLE_BITS) + { + case 5: + lcr |= UART_LCR_DLS_5BITS; + break; + + case 6: + lcr |= UART_LCR_DLS_6BITS; + break; + + case 7: + lcr |= UART_LCR_DLS_7BITS; + break; + + case 8: + default: + lcr |= UART_LCR_DLS_8BITS; + break; + } + +#ifdef MPFS_CONSOLE_2STOP + lcr |= UART_LCR_STOP; +#endif + + if (MPFS_CONSOLE_PARITY == 1) + { + lcr |= UART_LCR_PEN; + } + else if (MPFS_CONSOLE_PARITY == 2) + { + lcr |= (UART_LCR_PEN | UART_LCR_EPS); + } + + putreg32(lcr | UART_LCR_DLAB, MPFS_CONSOLE_BASE + MPFS_UART_LCR_OFFSET); + config_baud_divisors(); + putreg32(lcr, MPFS_CONSOLE_BASE + MPFS_UART_LCR_OFFSET); + +#endif /* HAVE_SERIAL_CONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */ +#endif /* HAVE_UART */ +} diff --git a/arch/risc-v/src/mpfs/mpfs_lowputc.h b/arch/risc-v/src/mpfs/mpfs_lowputc.h new file mode 100755 index 0000000000..710a16c866 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_lowputc.h @@ -0,0 +1,59 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_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_MPFS_MPFS_LOWPUTC_H +#define __ARCH_RISCV_SRC_MPFS_MPFS_LOWPUTC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: mpfs_lowsetup + ****************************************************************************/ + +EXTERN void mpfs_lowsetup(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_MPFS_MPFS_LOWPUTC_H */ diff --git a/arch/risc-v/src/mpfs/mpfs_memorymap.h b/arch/risc-v/src/mpfs/mpfs_memorymap.h new file mode 100755 index 0000000000..68620c06f2 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_memorymap.h @@ -0,0 +1,53 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_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_MPFS_MPFS_MEMORYMAP_H +#define _ARCH_RISCV_SRC_MPFS_MPFS_MEMORYMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "hardware/mpfs_clint.h" +#include "hardware/mpfs_memorymap.h" +#include "hardware/mpfs_plic.h" +#include "hardware/mpfs_sysctl.h" +#include "hardware/mpfs_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Idle thread stack starts from _default_stack_limit */ + +#ifndef __ASSEMBLY__ +extern uintptr_t *_default_stack_limit; +#define MPFS_IDLESTACK_BASE (uintptr_t)&_default_stack_limit +#else +#define MPFS_IDLESTACK_BASE _default_stack_limit +#endif + +#define MPFS_IDLESTACK_SIZE (CONFIG_IDLETHREAD_STACKSIZE & ~15) + +#define MPFS_IDLESTACK0_TOP (MPFS_IDLESTACK_BASE + MPFS_IDLESTACK_SIZE) + +#define MPFS_IDLESTACK_TOP (MPFS_IDLESTACK0_TOP) + +#endif /* _ARCH_RISCV_SRC_MPFS_MPFS_MEMORYMAP_H */ diff --git a/arch/risc-v/src/mpfs/mpfs_serial.c b/arch/risc-v/src/mpfs/mpfs_serial.c new file mode 100755 index 0000000000..26e20ff642 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_serial.c @@ -0,0 +1,1069 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_serial.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "riscv_arch.h" +#include "riscv_internal.h" + +#include "chip.h" +#include "mpfs.h" +#include "mpfs_config.h" +#include "mpfs_clockconfig.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 SERIAL_CONSOLE 1 +# elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define SERIAL_CONSOLE 2 +# elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart2port /* UART2 is console */ +# define SERIAL_CONSOLE 3 +# elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart3port /* UART3 is console */ +# define SERIAL_CONSOLE 4 +# elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart4port /* UART4 is console */ +# define SERIAL_CONSOLE 5 +# 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 +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# if defined(CONFIG_MPFS_UART0) +# define SERIAL_CONSOLE 1 +# elif defined(CONFIG_MPFS_UART1) +# define SERIAL_CONSOLE 2 +# elif defined(CONFIG_MPFS_UART2) +# define SERIAL_CONSOLE 3 +# elif defined(CONFIG_MPFS_UART3) +# define SERIAL_CONSOLE 4 +# elif defined(CONFIG_MPFS_UART4) +# define SERIAL_CONSOLE 5 +# 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 riscv_earlyserialinit(), riscv_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 */ + uint32_t ier; /* Saved IER value */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +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 uart_interrupt(int irq, void *context, void *arg); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, unsigned int *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_MPFS_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif + +#ifdef CONFIG_MPFS_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif + +#ifdef CONFIG_MPFS_UART2 +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; +#endif + +#ifdef CONFIG_MPFS_UART3 +static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE]; +static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE]; +#endif + +#ifdef CONFIG_MPFS_UART4 +static char g_uart4rxbuffer[CONFIG_UART4_RXBUFSIZE]; +static char g_uart4txbuffer[CONFIG_UART4_TXBUFSIZE]; +#endif + +#ifdef CONFIG_MPFS_UART0 +static struct up_dev_s g_uart0priv = +{ + .uartbase = MPFS_UART0_BASE, + .baud = CONFIG_UART0_BAUD, + .irq = MPFS_IRQ_MMUART0, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, + .stopbits2 = CONFIG_UART0_2STOP, +}; + +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 + +#ifdef CONFIG_MPFS_UART1 +static struct up_dev_s g_uart1priv = +{ + .uartbase = MPFS_UART1_BASE, + .baud = CONFIG_UART1_BAUD, + .irq = MPFS_IRQ_MMUART1, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = CONFIG_UART1_2STOP, +}; + +static uart_dev_t g_uart1port = +{ +#if SERIAL_CONSOLE == 2 + .isconsole = 1, +#endif + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +#ifdef CONFIG_MPFS_UART2 +static struct up_dev_s g_uart2priv = +{ + .uartbase = MPFS_UART2_BASE, + .baud = CONFIG_UART2_BAUD, + .irq = MPFS_IRQ_MMUART2, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, + .stopbits2 = CONFIG_UART2_2STOP, +}; + +static uart_dev_t g_uart2port = +{ +#if SERIAL_CONSOLE == 3 + .isconsole = 1, +#endif + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +#ifdef CONFIG_MPFS_UART3 +static struct up_dev_s g_uart3priv = +{ + .uartbase = MPFS_UART3_BASE, + .baud = CONFIG_UART3_BAUD, + .irq = MPFS_IRQ_MMUART3, + .parity = CONFIG_UART3_PARITY, + .bits = CONFIG_UART3_BITS, + .stopbits2 = CONFIG_UART3_2STOP, +}; + +static uart_dev_t g_uart3port = +{ +#if SERIAL_CONSOLE == 4 + .isconsole = 1, +#endif + .recv = + { + .size = CONFIG_UART3_RXBUFSIZE, + .buffer = g_uart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART3_TXBUFSIZE, + .buffer = g_uart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart3priv, +}; +#endif + +#ifdef CONFIG_MPFS_UART4 +static struct up_dev_s g_uart4priv = +{ + .uartbase = MPFS_UART4_BASE, + .baud = CONFIG_UART4_BAUD, + .irq = MPFS_IRQ_MMUART4, + .parity = CONFIG_UART4_PARITY, + .bits = CONFIG_UART4_BITS, + .stopbits2 = CONFIG_UART4_2STOP, +}; + +static uart_dev_t g_uart4port = +{ +#if SERIAL_CONSOLE == 5 + .isconsole = 1, +#endif + .recv = + { + .size = CONFIG_UART4_RXBUFSIZE, + .buffer = g_uart4rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART3_TXBUFSIZE, + .buffer = g_uart4txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart4priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, uint32_t offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, + uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(struct up_dev_s *priv, uint32_t *ier) +{ + if (ier) + { + *ier = priv->ier & UART_IER_ALLIE; + } + + priv->ier &= ~UART_IER_ALLIE; + up_serialout(priv, MPFS_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(struct up_dev_s *priv, uint32_t ier) +{ + priv->ier |= ier & UART_IER_ALLIE; + up_serialout(priv, MPFS_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_enablebreaks + ****************************************************************************/ + +static inline void up_enablebreaks(struct up_dev_s *priv, bool enable) +{ + uint32_t lcr = up_serialin(priv, MPFS_UART_LCR_OFFSET); + + if (enable) + { + lcr |= UART_LCR_BC; + } + else + { + lcr &= ~UART_LCR_BC; + } + + up_serialout(priv, MPFS_UART_LCR_OFFSET, lcr); +} + +/**************************************************************************** + * Name: up_config_baud_divisors + * + * Description: + * Configure the UART baudrate divisors. + * + ****************************************************************************/ + +static void up_config_baud_divisors(struct up_dev_s *priv, uint32_t baudrate) +{ + uint32_t baud_value; + uint32_t baud_value_by_64; + uint32_t baud_value_by_128; + uint32_t fractional_baud_value; + uint64_t pclk_freq; + + pclk_freq = MPFS_MSS_APB_AHB_CLK; + + /* Compute baud value based on requested baud rate and PCLK frequency. + * The baud value is computed using the following equation: + * baud_value = PCLK_Frequency / (baud_rate * 16) + */ + + baud_value_by_128 = (uint32_t)((8UL * pclk_freq) / baudrate); + baud_value_by_64 = baud_value_by_128 / 2U; + baud_value = baud_value_by_64 / 64U; + fractional_baud_value = baud_value_by_64 - (baud_value * 64U); + fractional_baud_value += (baud_value_by_128 - (baud_value * 128U)) + - (fractional_baud_value * 2U); + + if (baud_value <= (uint32_t)UINT16_MAX) + { + up_serialout(priv, MPFS_UART_DLH_OFFSET, baud_value >> 8); + up_serialout(priv, MPFS_UART_DLL_OFFSET, baud_value & 0xff); + + if (baud_value > 1) + { + /* Enable Fractional baud rate */ + + uint8_t mm0 = up_serialin(priv, MPFS_UART_MM0_OFFSET); + mm0 |= UART_MM0_EFBR; + up_serialout(priv, MPFS_UART_MM0_OFFSET, mm0); + up_serialout(priv, MPFS_UART_DFR_OFFSET, fractional_baud_value); + } + } +} + +/**************************************************************************** + * 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) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t lcr; + + /* Clear fifos */ + + up_serialout(priv, MPFS_UART_FCR_OFFSET, + (UART_FCR_RFIFOR | UART_FCR_XFIFOR)); + + /* set filter to minimum value */ + + up_serialout(priv, MPFS_UART_GFR_OFFSET, 0); + + /* set default TX time guard */ + + up_serialout(priv, MPFS_UART_TTG_OFFSET, 0); + + /* Set trigger */ + + up_serialout(priv, MPFS_UART_FCR_OFFSET, + (UART_FCR_FIFOE | UART_FCR_RT_HALF)); + + /* Set up the IER */ + + priv->ier = up_serialin(priv, MPFS_UART_IER_OFFSET); + + /* Set up the LCR */ + + lcr = 0; + + switch (priv->bits) + { + case 5: + lcr |= UART_LCR_DLS_5BITS; + break; + + case 6: + lcr |= UART_LCR_DLS_6BITS; + break; + + case 7: + lcr |= UART_LCR_DLS_7BITS; + break; + + case 8: + default: + lcr |= UART_LCR_DLS_8BITS; + break; + } + + if (priv->stopbits2) + { + lcr |= UART_LCR_STOP; + } + + if (priv->parity == 1) + { + lcr |= UART_LCR_PEN; + } + else if (priv->parity == 2) + { + lcr |= (UART_LCR_PEN | UART_LCR_EPS); + } + + /* Enter DLAB=1 */ + + up_serialout(priv, MPFS_UART_LCR_OFFSET, (lcr | UART_LCR_DLAB)); + + /* Set the BAUD divisor */ + + up_config_baud_divisors(priv, priv->baud); + + /* Clear DLAB */ + + up_serialout(priv, MPFS_UART_LCR_OFFSET, lcr); + + /* Configure the FIFOs */ + + up_serialout(priv, MPFS_UART_FCR_OFFSET, + (UART_FCR_RT_HALF | UART_FCR_XFIFOR | UART_FCR_RFIFOR | + UART_FCR_FIFOE)); + + /* Enable Auto-Flow Control in the Modem Control Register */ + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) +# warning Missing logic +#endif + +#endif + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, uart_interrupt, dev); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_disable_irq(priv->irq); + + /* Detach from the interrupt */ + + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int uart_interrupt(int irq, void *context, 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++) + { + /* Get the current UART status */ + + status = up_serialin(priv, MPFS_UART_IIR_OFFSET); + + /* Handle the interrupt by its interrupt ID field */ + + switch (status & UART_IIR_IID_MASK) + { + /* Handle incoming, receive bytes (with or without timeout) */ + + case UART_IIR_IID_RECV: + case UART_IIR_IID_TIMEOUT: + { + uart_recvchars(dev); + break; + } + + /* Handle outgoing, transmit bytes */ + + case UART_IIR_IID_TXEMPTY: + { + uart_xmitchars(dev); + break; + } + + /* Just clear modem status interrupts */ + + case UART_IIR_IID_MODEM: + { + /* Read the modem status register (MSR) to clear */ + + status = up_serialin(priv, MPFS_UART_MSR_OFFSET); + _info("MSR: %02" PRIx32 "\n", status); + break; + } + + /* Just clear any line status interrupts */ + + case UART_IIR_IID_LINESTATUS: + { + /* Read the line status register (LSR) to clear */ + + status = up_serialin(priv, MPFS_UART_LSR_OFFSET); + _info("LSR: %02" PRIx32 "\n", status); + break; + } + + /* No further interrupts pending... return now */ + + case UART_IIR_IID_NONE: + { + return OK; + } + + /* Otherwise we have received an interrupt + * that we cannot handle + */ + + default: + { + _err("ERROR: Unexpected IIR: %02" PRIx32 "\n", status); + break; + } + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rbr; + + *status = up_serialin(priv, MPFS_UART_LSR_OFFSET); + rbr = up_serialin(priv, MPFS_UART_RBR_OFFSET); + return rbr; +} + +/**************************************************************************** + * 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; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= UART_IER_ERBFI; +#endif + } + else + { + priv->ier &= ~UART_IER_ERBFI; + } + + up_serialout(priv, MPFS_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, MPFS_UART_LSR_OFFSET) & UART_LSR_DR) != 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART. + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + while ((up_serialin(priv, MPFS_UART_LSR_OFFSET) + & UART_LSR_THRE) == 0); + + up_serialout(priv, MPFS_UART_THR_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) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= UART_IER_ETBEI; + up_serialout(priv, MPFS_UART_IER_OFFSET, priv->ier); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + priv->ier &= ~UART_IER_ETBEI; + up_serialout(priv, MPFS_UART_IER_OFFSET, priv->ier); + } + + 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 ((up_serialin(priv, MPFS_UART_LSR_OFFSET) & UART_LSR_THRE) != 0); +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, MPFS_UART_LSR_OFFSET) & UART_LSR_THRE) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT + +/**************************************************************************** + * Name: riscv_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 riscv_serialinit. NOTE: This function depends on GPIO pin + * configuration performed in up_consoleinit() and main clock iniialization + * performed in up_clkinitialize(). + * + ****************************************************************************/ + +void riscv_earlyserialinit(void) +{ + /* Disable interrupts from all UARTS. The console is enabled in + * mpfs_consoleinit(). + */ + +#ifdef CONFIG_MPFS_UART0 + up_disableuartint(g_uart0port.priv, NULL); +#endif + +#ifdef CONFIG_MPFS_UART1 + up_disableuartint(g_uart1port.priv, NULL); +#endif + +#ifdef CONFIG_MPFS_UART2 + up_disableuartint(g_uart2port.priv, NULL); +#endif + +#ifdef CONFIG_MPFS_UART3 + up_disableuartint(g_uart3port.priv, NULL); +#endif + +#ifdef CONFIG_MPFS_UART4 + up_disableuartint(g_uart4port.priv, NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_SERIAL_CONSOLE + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} +#endif + +/**************************************************************************** + * Name: riscv_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that riscv_earlyserialinit was called previously. + * + ****************************************************************************/ + +void riscv_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_SERIAL_CONSOLE + uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs NOTE: we don't reorganize the numbering */ + +#ifdef CONFIG_MPFS_UART0 + uart_register("/dev/ttyS0", &g_uart0port); +#endif +#ifdef CONFIG_MPFS_UART1 + uart_register("/dev/ttyS1", &g_uart1port); +#endif +#ifdef CONFIG_MPFS_UART2 + uart_register("/dev/ttyS2", &g_uart2port); +#endif +#ifdef CONFIG_MPFS_UART3 + uart_register("/dev/ttyS3", &g_uart3port); +#endif +#ifdef CONFIG_MPFS_UART4 + uart_register("/dev/ttyS4", &g_uart4port); +#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; + uint32_t ier; + up_disableuartint(priv, &ier); +#endif + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + riscv_lowputc('\r'); + } + + riscv_lowputc(ch); +#ifdef HAVE_SERIAL_CONSOLE + up_restoreuartint(priv, ier); +#endif + return ch; +} + +/**************************************************************************** + * Name: riscv_earlyserialinit, riscv_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 riscv_earlyserialinit(void) +{ +} + +void riscv_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 */ + + riscv_lowputc('\r'); + } + + riscv_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/risc-v/src/mpfs/mpfs_start.c b/arch/risc-v/src/mpfs/mpfs_start.c new file mode 100755 index 0000000000..487fc398ab --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_start.c @@ -0,0 +1,144 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_start.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "chip.h" +#include "mpfs.h" +#include "mpfs_clockconfig.h" +#include "mpfs_userspace.h" +#include "riscv_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +# define showprogress(c) riscv_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 = MPFS_IDLESTACK_TOP; +volatile bool g_serial_ok = false; + +extern void mpfs_cpu_boot(uint32_t); + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: __mpfs_start + ****************************************************************************/ + +void __mpfs_start(uint32_t mhartid) +{ + const uint32_t *src; + uint32_t *dest; + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + /* Setup PLL */ + + mpfs_clockconfig(); + + /* Configure the UART so we can get debug output */ + + mpfs_lowsetup(); + + showprogress('A'); + +#ifdef USE_EARLYSERIALINIT + riscv_earlyserialinit(); +#endif + + showprogress('B'); + + g_serial_ok = true; + + /* Do board initialization */ + + mpfs_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 + mpfs_userspace(); + showprogress('D'); +#endif + + /* Call nx_start() */ + + nx_start(); + + showprogress('a'); + + while (true) + { + asm("WFI"); + } +} diff --git a/arch/risc-v/src/mpfs/mpfs_timerisr.c b/arch/risc-v/src/mpfs/mpfs_timerisr.c new file mode 100755 index 0000000000..444a4c1ad6 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_timerisr.c @@ -0,0 +1,132 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_timerisr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "riscv_arch.h" + +#include "mpfs.h" +#include "mpfs_clockconfig.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define TICK_COUNT (MPFS_MSS_RTC_TOGGLE_CLK / TICK_PER_SEC) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static bool _b_tick_started = false; +static uint64_t *_mtime_cmp = 0L; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpfs_reload_mtimecmp + ****************************************************************************/ + +static void mpfs_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(MPFS_CLINT_MTIME); + } + else + { + current = getreg64(_mtime_cmp); + } + + uint64_t tick = TICK_COUNT; + next = current + tick; + + putreg64(next, _mtime_cmp); + + spin_unlock_irqrestore(NULL, flags); +} + +/**************************************************************************** + * Name: mpfs_timerisr + ****************************************************************************/ + +static int mpfs_timerisr(int irq, void *context, FAR void *arg) +{ + mpfs_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) +{ + /* what is our timecmp address for this hart */ + + uint64_t hart_id = READ_CSR(mhartid); + _mtime_cmp = (uint64_t *)MPFS_CLINT_MTIMECMP0 + hart_id; + + /* Attach timer interrupt handler */ + + irq_attach(MPFS_IRQ_MTIMER, mpfs_timerisr, NULL); + + /* Reload CLINT mtimecmp */ + + mpfs_reload_mtimecmp(); + + /* And enable the timer interrupt */ + + up_enable_irq(MPFS_IRQ_MTIMER); +} diff --git a/arch/risc-v/src/mpfs/mpfs_userspace.c b/arch/risc-v/src/mpfs/mpfs_userspace.c new file mode 100755 index 0000000000..eb3c5cd16d --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_userspace.c @@ -0,0 +1,127 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_userspace.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "mpfs_userspace.h" +#include "riscv_internal.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* TODO: get user space mem layout info from ld script or Configuration ? */ + +#ifndef CONFIG_NUTTX_USERSPACE_SIZE +# define CONFIG_NUTTX_USERSPACE_SIZE (0x00100000) +#endif + +#ifndef CONFIG_NUTTX_USERSPACE_RAM_START +# define CONFIG_NUTTX_USERSPACE_RAM_START (0x00100000) +#endif + +#ifndef CONFIG_NUTTX_USERSPACE_RAM_SIZE +# define CONFIG_NUTTX_USERSPACE_RAM_SIZE (0x00100000) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpfs_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 mpfs_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++; + } + + /* Configure the PMP to permit user-space access to its ROM and RAM. + * Now this is done by simply adding the whole memory area to PMP. + * 1. no access for the 1st 4KB + * 2. "RX" for the left space until 1MB + * 3. "RW" for the user RAM area + * TODO: more accurate memory size control. + */ + + riscv_config_pmp_region(0, PMPCFG_A_NAPOT, + 0, + 0x1000); + + riscv_config_pmp_region(1, PMPCFG_A_TOR | PMPCFG_X | PMPCFG_R, + 0 + CONFIG_NUTTX_USERSPACE_SIZE, + 0); + + riscv_config_pmp_region(2, PMPCFG_A_NAPOT | PMPCFG_W | PMPCFG_R, + CONFIG_NUTTX_USERSPACE_RAM_START, + CONFIG_NUTTX_USERSPACE_RAM_SIZE); +} + +#endif /* CONFIG_BUILD_PROTECTED */ diff --git a/arch/risc-v/src/mpfs/mpfs_userspace.h b/arch/risc-v/src/mpfs/mpfs_userspace.h new file mode 100755 index 0000000000..d59073a7d7 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_userspace.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_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_MPFS_MPFS_USERSPACE_H +#define __ARCH_RISCV_SRC_MPFS_MPFS_USERSPACE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: mpfs_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 mpfs_userspace(void); +#endif + +#endif /* __ARCH_RISCV_SRC_MPFS_MPFS_USERSPACE_H */ diff --git a/arch/risc-v/src/mpfs/mpfs_vectors.S b/arch/risc-v/src/mpfs/mpfs_vectors.S new file mode 100755 index 0000000000..94a7173fc6 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_vectors.S @@ -0,0 +1,53 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_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 + .global __start + +/**************************************************************************** + * Name: __reset_vec + * + * Description: + * Also __start symbol is defined to be on start of image. This is expected + * by some of Microchip tools, which can be used to e.g. flash the image + * + ****************************************************************************/ + +__start: +__reset_vec: + j __start_mpfs + +/**************************************************************************** + * Name: exception_common + * + * Description: + * All exceptions and interrupts will be handled from here. + * + ****************************************************************************/ + +__trap_vec: + j exception_common + nop diff --git a/boards/Kconfig b/boards/Kconfig index 7b97fb3f8f..ad482a9505 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -633,6 +633,14 @@ config ARCH_BOARD_SMARTL_C906 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_ICICLE_MPFS + bool "Polarfire Icicle evaluation board for MPFS" + depends on ARCH_CHIP_MPFS + select ARCH_HAVE_LEDS if !MPFS_WITH_QEMU + ---help--- + This is the board configuration for the port of NuttX to the + MicroChip icicle-mpfs board. This board features the RISC-V MPFS. + config ARCH_BOARD_MAX32660_EVSYS bool "Maxim Integrated MAX32660-EVSYS" depends on ARCH_CHIP_MAX32660 @@ -2329,6 +2337,7 @@ config ARCH_BOARD default "lx_cpu" if ARCH_BOARD_LX_CPU default "maix-bit" if ARCH_BOARD_MAIX_BIT default "smartl-c906" if ARCH_BOARD_SMARTL_C906 + default "icicle" if ARCH_BOARD_ICICLE_MPFS default "maple" if ARCH_BOARD_MAPLE default "makerlisp" if ARCH_BOARD_MAKERLISP default "max32660-evsys" if ARCH_BOARD_MAX32660_EVSYS @@ -3128,6 +3137,9 @@ endif if ARCH_BOARD_SMARTL_C906 source "boards/risc-v/c906/smartl-c906/Kconfig" endif +if ARCH_BOARD_ICICLE_MPFS +source "boards/risc-v/mpfs/icicle/Kconfig" +endif if ARCH_BOARD_ESP32C3_DEVKIT source "boards/risc-v/esp32c3/esp32c3-devkit/Kconfig" endif diff --git a/boards/risc-v/mpfs/icicle/Kconfig b/boards/risc-v/mpfs/icicle/Kconfig new file mode 100755 index 0000000000..6dba7cd4c9 --- /dev/null +++ b/boards/risc-v/mpfs/icicle/Kconfig @@ -0,0 +1,8 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# + +if ARCH_BOARD_ICICLE_MPFS + +endif diff --git a/boards/risc-v/mpfs/icicle/configs/nsh/defconfig b/boards/risc-v/mpfs/icicle/configs/nsh/defconfig new file mode 100644 index 0000000000..0df8eb81a1 --- /dev/null +++ b/boards/risc-v/mpfs/icicle/configs/nsh/defconfig @@ -0,0 +1,76 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_OS_API is not set +# CONFIG_NSH_DISABLE_LOSMART is not set +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="icicle" +CONFIG_ARCH_BOARD_ICICLE_MPFS=y +CONFIG_ARCH_CHIP="mpfs" +CONFIG_ARCH_CHIP_MPFS=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=54000 +CONFIG_BUILTIN=y +CONFIG_DEBUG_ASSERTIONS=y +CONFIG_DEBUG_ERROR=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_WARN=y +CONFIG_DEV_ZERO=y +CONFIG_EXPERIMENTAL=y +CONFIG_FS_PROCFS=y +CONFIG_FS_ROMFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_LIB_HOSTNAME="icicle" +CONFIG_MAX_TASKS=64 +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_MPFS_ENABLE_DPFPU=y +CONFIG_MPFS_UART1=y +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_LINELEN=160 +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=1048576 +CONFIG_RAM_START=0x80200000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SERIAL_NPOLLWAITERS=2 +CONFIG_STACK_COLORATION=y +CONFIG_START_MONTH=4 +CONFIG_START_YEAR=2021 +CONFIG_SYSLOG_COLOR_OUTPUT=y +CONFIG_SYSTEM_CLE_CMD_HISTORY=y +CONFIG_SYSTEM_COLOR_CLE=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_TIME64=y +CONFIG_TASK_NAME_SIZE=20 +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_TESTING_OSTEST_FPUSIZE=264 +CONFIG_UART1_SERIAL_CONSOLE=y +CONFIG_USERMAIN_STACKSIZE=3072 +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/boards/risc-v/mpfs/icicle/include/board.h b/boards/risc-v/mpfs/icicle/include/board.h new file mode 100755 index 0000000000..680915d27e --- /dev/null +++ b/boards/risc-v/mpfs/icicle/include/board.h @@ -0,0 +1,111 @@ +/**************************************************************************** + * boards/risc-v/mpfs/icicle/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_ICICLE_MPFS_INCLUDE_BOARD_H +#define __BOARDS_RISCV_ICICLE_MPFS_INCLUDE_BOARD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +#include "mpfs_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Clocking TODO: */ + +#define MPFS_MSS_EXT_SGMII_REF_CLK (125000000UL) +#define MPFS_MSS_COREPLEX_CPU_CLK (600000000UL) +#define MPFS_MSS_SYSTEM_CLK (600000000UL) +#define MPFS_MSS_RTC_TOGGLE_CLK (1000000UL) +#define MPFS_MSS_AXI_CLK (300000000UL) +#define MPFS_MSS_APB_AHB_CLK (150000000UL) + +/* LED definitions **********************************************************/ + +/* LED index values for use with board_userled() */ + +#define BOARD_LED1 0 +#define BOARD_LED2 1 +#define BOARD_LED3 2 +#define BOARD_LED4 3 +#define BOARD_NLEDS 4 + +#define BOARD_LED_ORANGE1 BOARD_LED1 +#define BOARD_LED_ORANGE2 BOARD_LED2 +#define BOARD_LED_RED1 BOARD_LED3 +#define BOARD_LED_RED2 BOARD_LED4 + +#define LED_STARTED 0 /* LED1 */ +#define LED_HEAPALLOCATE 1 /* LED2 */ +#define LED_IRQSENABLED 2 /* LED1 + LED2 */ +#define LED_STACKCREATED 3 /* LED3 */ +#define LED_INIRQ 4 /* LED3 + LED1 */ +#define LED_SIGNAL 5 /* LED3 + LED2 */ +#define LED_ASSERTION 6 /* LED3 + LED2 + LED1 */ +#define LED_PANIC 7 /* LED4 */ + +/* Button definitions *******************************************************/ + +/* The Icicle supports 3 buttons: */ + +#define BUTTON_USER1 0 +#define BUTTON_USER2 1 +#define BUTTON_USER3 2 +#define NUM_BUTTONS 3 +#define BUTTON_USER1_BIT (1 << BUTTON_USER1) +#define BUTTON_USER2_BIT (1 << BUTTON_USER2) +#define BUTTON_USER3_BIT (1 << BUTTON_USER3) + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: mpfs_boardinitialize + ****************************************************************************/ + +void mpfs_boardinitialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_RISCV_ICICLE_MPFS_INCLUDE_BOARD_H */ diff --git a/boards/risc-v/mpfs/icicle/kernel/Makefile b/boards/risc-v/mpfs/icicle/kernel/Makefile new file mode 100755 index 0000000000..919e2d9965 --- /dev/null +++ b/boards/risc-v/mpfs/icicle/kernel/Makefile @@ -0,0 +1,107 @@ +############################################################################ +# boards/risc-v/mpfs/icicle//kernel/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 + +# The entry point name (if none is provided in the .config file) + +CONFIG_USER_ENTRYPOINT ?= user_start +ENTRYPT = $(patsubst "%",%,$(CONFIG_USER_ENTRYPOINT)) + +# The memory layout + +MEM_LAYOUT = memory.ld + +# Get the paths to the libraries and the links script path in format that +# is appropriate for the host OS + +ifeq ($(CONFIG_CYGWIN_WINTOOL),y) + # Windows-native toolchains + USER_LIBPATHS = ${shell for path in $(USERLIBS); do dir=`dirname $(TOPDIR)$(DELIM)$$path`;echo "-L\"`cygpath -w $$dir`\"";done} + USER_LDSCRIPT = -T "${shell cygpath -w $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(MEM_LAYOUT)}" + USER_LDSCRIPT += -T "${shell cygpath -w $(BOARD_DIR)$(DELIM)scripts$(DELIM)user-space.ld}" + USER_HEXFILE += "${shell cygpath -w $(TOPDIR)$(DELIM)nuttx_user.hex}" + USER_SRECFILE += "${shell cygpath -w $(TOPDIR)$(DELIM)nuttx_user.srec}" + USER_BINFILE += "${shell cygpath -w $(TOPDIR)$(DELIM)nuttx_user.bin}" +else + # Linux/Cygwin-native toolchain + USER_LIBPATHS = $(addprefix -L$(TOPDIR)$(DELIM),$(dir $(USERLIBS))) + USER_LDSCRIPT = -T$(BOARD_DIR)$(DELIM)scripts$(DELIM)$(MEM_LAYOUT) + USER_LDSCRIPT += -T$(BOARD_DIR)$(DELIM)scripts$(DELIM)user-space.ld + USER_HEXFILE += "$(TOPDIR)$(DELIM)nuttx_user.hex" + USER_SRECFILE += "$(TOPDIR)$(DELIM)nuttx_user.srec" + USER_BINFILE += "$(TOPDIR)$(DELIM)nuttx_user.bin" +endif + +USER_LDFLAGS = --undefined=$(ENTRYPT) --entry=$(ENTRYPT) $(USER_LDSCRIPT) +USER_LDLIBS = $(patsubst lib%,-l%,$(basename $(notdir $(USERLIBS)))) +USER_LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}" + +# Source files + +CSRCS = mpfs_userspace.c +COBJS = $(CSRCS:.c=$(OBJEXT)) +OBJS = $(COBJS) + +# Targets: + +all: $(TOPDIR)$(DELIM)nuttx_user.elf $(TOPDIR)$(DELIM)User.map +.PHONY: nuttx_user.elf depend clean distclean + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +# Create the nuttx_user.elf file containing all of the user-mode code + +nuttx_user.elf: $(OBJS) + $(Q) $(LD) -o $@ $(USER_LDFLAGS) $(USER_LIBPATHS) $(OBJS) --start-group $(USER_LDLIBS) --end-group $(USER_LIBGCC) + +$(TOPDIR)$(DELIM)nuttx_user.elf: nuttx_user.elf + @echo "LD: nuttx_user.elf" + $(Q) cp -a nuttx_user.elf $(TOPDIR)$(DELIM)nuttx_user.elf +ifeq ($(CONFIG_INTELHEX_BINARY),y) + @echo "CP: nuttx_user.hex" + $(Q) $(OBJCOPY) $(OBJCOPYARGS) -O ihex nuttx_user.elf $(USER_HEXFILE) +endif +ifeq ($(CONFIG_MOTOROLA_SREC),y) + @echo "CP: nuttx_user.srec" + $(Q) $(OBJCOPY) $(OBJCOPYARGS) -O srec nuttx_user.elf $(USER_SRECFILE) +endif +ifeq ($(CONFIG_RAW_BINARY),y) + @echo "CP: nuttx_user.bin" + $(Q) $(OBJCOPY) $(OBJCOPYARGS) -O binary nuttx_user.elf $(USER_BINFILE) +endif + +$(TOPDIR)$(DELIM)User.map: nuttx_user.elf + @echo "MK: User.map" + $(Q) $(NM) -n nuttx_user.elf >$(TOPDIR)$(DELIM)User.map + $(Q) $(CROSSDEV)size nuttx_user.elf + +.depend: + +depend: .depend + +clean: + $(call DELFILE, nuttx_user.elf) + $(call DELFILE, "$(TOPDIR)$(DELIM)nuttx_user.*") + $(call DELFILE, "$(TOPDIR)$(DELIM)User.map") + $(call CLEAN) + +distclean: clean diff --git a/boards/risc-v/mpfs/icicle/kernel/mpfs_userspace.c b/boards/risc-v/mpfs/icicle/kernel/mpfs_userspace.c new file mode 100755 index 0000000000..6fda7b7c8f --- /dev/null +++ b/boards/risc-v/mpfs/icicle/kernel/mpfs_userspace.c @@ -0,0 +1,121 @@ +/**************************************************************************** + * boards/risc-v/mpfs/icicle/kernel/mpfs_userspace.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include + +#if defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifndef CONFIG_NUTTX_USERSPACE +# error "CONFIG_NUTTX_USERSPACE not defined" +#endif + +#if CONFIG_NUTTX_USERSPACE != 0x00001000 +# error "CONFIG_NUTTX_USERSPACE must match the value in memory.ld" +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* These 'addresses' of these values are setup by the linker script. + * They are not actual uint32_t storage locations! + * They are only used meaningfully in the following way: + * + * - The linker script defines, for example, the symbol_sdata. + * - The declaration extern uint32_t _sdata; makes C happy. C will believe + * that the value _sdata is the address of a uint32_t variable _data + * (it is not!). + * - We can recover the linker value then by simply taking the address of + * of _data. like: uint32_t *pdata = &_sdata; + */ + +extern uint32_t _stext; /* Start of .text */ +extern uint32_t _etext; /* End_1 of .text + .rodata */ +extern const uint32_t _eronly; /* End+1 of read only section */ +extern uint32_t _sdata; /* Start of .data */ +extern uint32_t _edata; /* End+1 of .data */ +extern uint32_t _sbss; /* Start of .bss */ +extern uint32_t _ebss; /* End+1 of .bss */ + +extern uintptr_t *__ld_usram_end; /* End+1 of user ram section */ + +/* This is the user space entry point */ + +int CONFIG_USER_ENTRYPOINT(int argc, char *argv[]); + +const struct userspace_s userspace __attribute__ ((section (".userspace"))) = +{ + /* General memory map */ + + .us_entrypoint = (main_t)CONFIG_USER_ENTRYPOINT, + .us_textstart = (uintptr_t)&_stext, + .us_textend = (uintptr_t)&_etext, + .us_datasource = (uintptr_t)&_eronly, + .us_datastart = (uintptr_t)&_sdata, + .us_dataend = (uintptr_t)&_edata, + .us_bssstart = (uintptr_t)&_sbss, + .us_bssend = (uintptr_t)&_ebss, + + .us_heapend = (uintptr_t)&__ld_usram_end, + + /* Memory manager heap structure */ + + .us_heap = &g_mmheap, + + /* Task/thread startup routines */ + + .task_startup = nxtask_startup, +#ifndef CONFIG_DISABLE_PTHREAD + .pthread_startup = pthread_startup, +#endif + + /* Signal handler trampoline */ + + .signal_handler = up_signal_handler, + + /* User-space work queue support (declared in include/nuttx/wqueue.h) */ + +#ifdef CONFIG_LIB_USRWORK + .work_usrstart = work_usrstart, +#endif +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* CONFIG_BUILD_PROTECTED && !__KERNEL__ */ diff --git a/boards/risc-v/mpfs/icicle/scripts/Make.defs b/boards/risc-v/mpfs/icicle/scripts/Make.defs new file mode 100755 index 0000000000..bdf6da11a5 --- /dev/null +++ b/boards/risc-v/mpfs/icicle/scripts/Make.defs @@ -0,0 +1,98 @@ +############################################################################ +# boards/risc-v/mpfs/icicle/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 + +LDSCRIPT = ld.script + +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 MPFS user guide. +# ARCHCPUFLAGS = -march=rv64gcxthead -mabi=lp64d -mcmodel=medany +# TODO: We are not going to enable this at this time for the CI compatiblity. + +ifeq ($(CONFIG_ARCH_HAVE_DPFPU),y) + ARCHCPUFLAGS = -march=rv64gc -mabi=lp64d -mcmodel=medany +else + ARCHCPUFLAGS = -march=rv64imac -mabi=lp64 -mcmodel=medany +endif + +ARCHCFLAGS = -fno-builtin -ffunction-sections -fdata-sections -fno-omit-frame-pointer +ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti +ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef +ARCHWARNINGSXX = -Wall -Wshadow -Wundef + +CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS) +CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +AFLAGS += $(CFLAGS) -D__ASSEMBLY__ $(ASARCHCPUFLAGS) + +# NXFLAT module definitions + +NXFLATLDFLAGS1 = -r -d -warn-common +NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections +LDNXFLATFLAGS = -e main -s 2048 + +# Loadable module definitions + +CMODULEFLAGS = $(CFLAGS) + +LDMODULEFLAGS = -r -e module_initialize +ifeq ($(CONFIG_CYGWIN_WINTOOL),y) + LDMODULEFLAGS += -T "${shell cygpath -w $(TOPDIR)/libs/libc/modlib/gnu-elf.ld}" +else + LDMODULEFLAGS += -T $(TOPDIR)/libs/libc/modlib/gnu-elf.ld +endif + +# ELF module definitions + +CELFFLAGS = $(CFLAGS) -fno-common +CXXELFFLAGS = $(CXXFLAGS) -fno-common + +LDELFFLAGS = -r -e main +ifeq ($(CONFIG_CYGWIN_WINTOOL),y) + LDELFFLAGS += -T "${shell cygpath -w $(BOARD_DIR)$(DELIM)scripts$(DELIM)gnu-elf.ld}" +else + LDELFFLAGS += -T $(BOARD_DIR)$(DELIM)scripts$(DELIM)gnu-elf.ld +endif + +# File extensions + +LDFLAGS += --gc-sections -melf64lriscv diff --git a/boards/risc-v/mpfs/icicle/scripts/gnu-elf.ld b/boards/risc-v/mpfs/icicle/scripts/gnu-elf.ld new file mode 100755 index 0000000000..b513bc6063 --- /dev/null +++ b/boards/risc-v/mpfs/icicle/scripts/gnu-elf.ld @@ -0,0 +1,115 @@ +/**************************************************************************** + * boards/risc-v/mpfs/icicle/scripts/gnu-elf.ld + * + * 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. + * + ****************************************************************************/ + +SECTIONS +{ + .text 0x00000000 : + { + _stext = . ; + *(.text) + *(.text.*) + *(.gnu.warning) + *(.stub) + *(.glue_7) + *(.glue_7t) + *(.jcr) + + /* C++ support: The .init and .fini sections contain specific logic + * to manage static constructors and destructors. + */ + + *(.gnu.linkonce.t.*) + *(.init) /* Old ABI */ + *(.fini) /* Old ABI */ + _etext = . ; + } + + .rodata : + { + _srodata = . ; + *(.rodata) + *(.rodata1) + *(.rodata.*) + *(.gnu.linkonce.r*) + _erodata = . ; + } + + .data : + { + _sdata = . ; + *(.data) + *(.data1) + *(.data.*) + *(.gnu.linkonce.d*) + . = ALIGN(4); + _edata = . ; + } + + /* C++ support. For each global and static local C++ object, + * GCC creates a small subroutine to construct the object. Pointers + * to these routines (not the routines themselves) are stored as + * simple, linear arrays in the .ctors section of the object file. + * Similarly, pointers to global/static destructor routines are + * stored in .dtors. + */ + + .ctors : + { + _sctors = . ; + *(.ctors) /* Old ABI: Unallocated */ + *(.init_array) /* New ABI: Allocated */ + _edtors = . ; + } + + .dtors : + { + _sdtors = . ; + *(.dtors) /* Old ABI: Unallocated */ + *(.fini_array) /* New ABI: Allocated */ + _edtors = . ; + } + + .bss : + { + _sbss = . ; + *(.bss) + *(.bss.*) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.b*) + *(COMMON) + _ebss = . ; + } + + /* Stabs debugging sections. */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/risc-v/mpfs/icicle/scripts/hss-nuttx.yml b/boards/risc-v/mpfs/icicle/scripts/hss-nuttx.yml new file mode 100644 index 0000000000..05b4214a02 --- /dev/null +++ b/boards/risc-v/mpfs/icicle/scripts/hss-nuttx.yml @@ -0,0 +1,12 @@ +# HSS Payload Generator + +# First, we can optionally set a name for our image, otherwise one will be created dynamically +set-name: 'PolarFire-SoC-HSS::nuttx' + +# Next, we'll define the entry point addresses for each hart, as follows: +hart-entry-points: {u54_1: '0x80000000', u54_2: '0x80000000', u54_3: '0x80000000', u54_4: '0x80000000'} + +# +payloads: + nuttx.bin: {exec-addr: '0x80000000', owner-hart: u54_1, priv-mode: prv_m} + diff --git a/boards/risc-v/mpfs/icicle/scripts/ld.script b/boards/risc-v/mpfs/icicle/scripts/ld.script new file mode 100755 index 0000000000..4fa073525a --- /dev/null +++ b/boards/risc-v/mpfs/icicle/scripts/ld.script @@ -0,0 +1,97 @@ +/**************************************************************************** + * boards/risc-v/mpfs/icicle/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 = 0x80000000, LENGTH = 2M /* w/ cache */ + sram (rwx) : ORIGIN = 0x80200000, LENGTH = 1M /* w/ cache */ +} + +OUTPUT_ARCH("riscv") + +ENTRY(_stext) +EXTERN(_vectors) +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.* .srodata .srodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > progmem + + .init_section : ALIGN(4) { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > progmem + + _eronly = ABSOLUTE(.); + + .data : ALIGN(4) { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.d.*) + *(.gnu.linkonce.s.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > sram AT > progmem + + PROVIDE(__global_pointer$ = _sdata + ((_edata - _sdata) / 2)); + + .bss : ALIGN(4) { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.sbss .sbss.*) + *(.gnu.linkonce.b.*) + *(.gnu.linkonce.sb.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + . = ALIGN(32); + _default_stack_limit = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/risc-v/mpfs/icicle/scripts/memory.ld b/boards/risc-v/mpfs/icicle/scripts/memory.ld new file mode 100755 index 0000000000..3b38cc4bbc --- /dev/null +++ b/boards/risc-v/mpfs/icicle/scripts/memory.ld @@ -0,0 +1,35 @@ +/**************************************************************************** + * boards/risc-v/mpfs/icicle/scripts/memory.ld + * + * 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. + * + ****************************************************************************/ + +/* Reg Access Start addr End addr Size + * QEMU CPU w/ cache 0x00000000 - 0x003fffff : 4MB + * QEMU CPU w/o cache 0x1f000000 - 0x1f01ffff : 128KB + */ + +MEMORY +{ + kflash (rx) : ORIGIN = 0x80000000, LENGTH = 256K /* w/ cache */ + uflash (rx) : ORIGIN = 0x80040000, LENGTH = 256K /* w/ cache */ + xflash (rx) : ORIGIN = 0x80080000, LENGTH = 256K /* w/o cache */ + + ksram (rwx) : ORIGIN = 0x800C0000, LENGTH = 256K /* w/ cache */ + usram (rwx) : ORIGIN = 0x80100000, LENGTH = 256K /* w/ cache */ + xsram (rwx) : ORIGIN = 0x80140000, LENGTH = 256K /* w/o cache */ +} diff --git a/boards/risc-v/mpfs/icicle/scripts/user-space.ld b/boards/risc-v/mpfs/icicle/scripts/user-space.ld new file mode 100755 index 0000000000..0e1204971c --- /dev/null +++ b/boards/risc-v/mpfs/icicle/scripts/user-space.ld @@ -0,0 +1,104 @@ +/**************************************************************************** + * boards/risc-v/mpfs/icicle/scripts/user-space.ld + * + * 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. + * + ****************************************************************************/ + +/* NOTE: This depends on the memory.ld script having been included prior to + * this script. + */ + +OUTPUT_ARCH("riscv") + +SECTIONS +{ + /* section info */ + + __ld_uflash_start = ORIGIN(uflash); + __ld_uflash_end = ORIGIN(uflash)+ LENGTH(uflash); + __ld_uflash_size = LENGTH(uflash); + + __ld_usram_start = ORIGIN(usram); + __ld_usram_end = ORIGIN(usram)+ LENGTH(usram); + __ld_usram_size = LENGTH(usram); + + .userspace : { + *(.userspace) + } > uflash + + .text : { + _stext = ABSOLUTE(.); + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > uflash + + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > uflash + + __exidx_start = ABSOLUTE(.); + + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > usram AT > uflash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.sbss .sbss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > usram + + /* Stabs debugging sections */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/risc-v/mpfs/icicle/src/Makefile b/boards/risc-v/mpfs/icicle/src/Makefile new file mode 100755 index 0000000000..3fcb0f558f --- /dev/null +++ b/boards/risc-v/mpfs/icicle/src/Makefile @@ -0,0 +1,37 @@ +############################################################################ +# boards/risc-v/mpfs/icicle/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 = mpfs_bringup.c mpfs_boot.c + +ifeq ($(CONFIG_LIB_BOARDCTL),y) +CSRCS += mpfs_appinit.c +endif + +ifeq ($(CONFIG_ARCH_LEDS),y) +CSRCS += mpfs_autoleds.c +endif + +ifeq ($(CONFIG_ARCH_FPU),y) +CSRCS += mpfs_ostest.c +endif + +include $(TOPDIR)/boards/Board.mk diff --git a/boards/risc-v/mpfs/icicle/src/mpfs_appinit.c b/boards/risc-v/mpfs/icicle/src/mpfs_appinit.c new file mode 100755 index 0000000000..c4a28c00be --- /dev/null +++ b/boards/risc-v/mpfs/icicle/src/mpfs_appinit.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * boards/risc-v/mpfs/icicle/src/mpfs_appinit.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "mpfs.h" +#include "mpfsicicle.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 mpfs_bringup(); +#endif +} diff --git a/boards/risc-v/mpfs/icicle/src/mpfs_autoleds.c b/boards/risc-v/mpfs/icicle/src/mpfs_autoleds.c new file mode 100755 index 0000000000..5bc8b3b544 --- /dev/null +++ b/boards/risc-v/mpfs/icicle/src/mpfs_autoleds.c @@ -0,0 +1,147 @@ +/**************************************************************************** + * boards/risc-v/mpfs/icicle/src/mpfs_autoleds.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include "mpfsicicle.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_autoled_initialize + * + * Description: + * Init the LEDs. + * + ****************************************************************************/ + +void board_autoled_initialize(void) +{ + mpfs_configgpio(ICICLE_GPIO_LED1); + mpfs_configgpio(ICICLE_GPIO_LED2); + mpfs_configgpio(ICICLE_GPIO_LED3); + mpfs_configgpio(ICICLE_GPIO_LED4); + mpfs_gpiowrite(ICICLE_GPIO_LED1, false); + mpfs_gpiowrite(ICICLE_GPIO_LED2, false); + mpfs_gpiowrite(ICICLE_GPIO_LED3, false); + mpfs_gpiowrite(ICICLE_GPIO_LED4, false); +} + +/**************************************************************************** + * 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) +{ + switch (led) + { + case LED_STARTED: + mpfs_gpiowrite(ICICLE_GPIO_LED1, true); + mpfs_gpiowrite(ICICLE_GPIO_LED2, false); + mpfs_gpiowrite(ICICLE_GPIO_LED3, false); + mpfs_gpiowrite(ICICLE_GPIO_LED4, false); + break; + case LED_HEAPALLOCATE: + mpfs_gpiowrite(ICICLE_GPIO_LED2, true); + break; + case LED_IRQSENABLED: + mpfs_gpiowrite(ICICLE_GPIO_LED1, true); + mpfs_gpiowrite(ICICLE_GPIO_LED2, true); + break; + case LED_STACKCREATED: + mpfs_gpiowrite(ICICLE_GPIO_LED3, true); + mpfs_gpiowrite(ICICLE_GPIO_LED1, false); + mpfs_gpiowrite(ICICLE_GPIO_LED2, false); + break; + case LED_INIRQ: + mpfs_gpiowrite(ICICLE_GPIO_LED1, true); + mpfs_gpiowrite(ICICLE_GPIO_LED2, false); + mpfs_gpiowrite(ICICLE_GPIO_LED3, false); + break; + case LED_SIGNAL: + mpfs_gpiowrite(ICICLE_GPIO_LED3, true); + mpfs_gpiowrite(ICICLE_GPIO_LED1, false); + mpfs_gpiowrite(ICICLE_GPIO_LED2, false); + break; + case LED_ASSERTION: + mpfs_gpiowrite(ICICLE_GPIO_LED3, true); + mpfs_gpiowrite(ICICLE_GPIO_LED2, true); + mpfs_gpiowrite(ICICLE_GPIO_LED1, true); + break; + case LED_PANIC: + mpfs_gpiowrite(ICICLE_GPIO_LED4, true); + break; + + default: + break; + } +} + +/**************************************************************************** + * 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) +{ + switch (led) + { + case LED_INIRQ: + mpfs_gpiowrite(ICICLE_GPIO_LED1, false); + break; + case LED_SIGNAL: + mpfs_gpiowrite(ICICLE_GPIO_LED3, false); + break; + case LED_ASSERTION: + mpfs_gpiowrite(ICICLE_GPIO_LED3, false); + mpfs_gpiowrite(ICICLE_GPIO_LED2, false); + mpfs_gpiowrite(ICICLE_GPIO_LED1, false); + break; + case LED_PANIC: + mpfs_gpiowrite(ICICLE_GPIO_LED4, false); + break; + + default: + break; + } +} diff --git a/boards/risc-v/mpfs/icicle/src/mpfs_boot.c b/boards/risc-v/mpfs/icicle/src/mpfs_boot.c new file mode 100755 index 0000000000..183ee9591a --- /dev/null +++ b/boards/risc-v/mpfs/icicle/src/mpfs_boot.c @@ -0,0 +1,58 @@ +/**************************************************************************** + * boards/risc-v/mpfs/icicle/src/mpfs_boot.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpfs_boardinitialize + * + * Description: + * All mpfs 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 mpfs_boardinitialize(void) +{ + board_autoled_initialize(); +} diff --git a/boards/risc-v/mpfs/icicle/src/mpfs_bringup.c b/boards/risc-v/mpfs/icicle/src/mpfs_bringup.c new file mode 100755 index 0000000000..559901b61c --- /dev/null +++ b/boards/risc-v/mpfs/icicle/src/mpfs_bringup.c @@ -0,0 +1,61 @@ +/**************************************************************************** + * boards/risc-v/mpfs/icicle/src/mpfs_bringup.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "mpfs.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpfs_bringup + ****************************************************************************/ + +int mpfs_bringup(void) +{ + int ret = OK; + +#ifdef CONFIG_FS_PROCFS + /* Mount the procfs file system */ + + ret = mount(NULL, "/proc", "procfs", 0, NULL); + if (ret < 0) + { + serr("ERROR: Failed to mount procfs at %s: %d\n", "/proc", ret); + } +#endif + + return ret; +} diff --git a/boards/risc-v/mpfs/icicle/src/mpfs_ostest.c b/boards/risc-v/mpfs/icicle/src/mpfs_ostest.c new file mode 100755 index 0000000000..715ccc6504 --- /dev/null +++ b/boards/risc-v/mpfs/icicle/src/mpfs_ostest.c @@ -0,0 +1,92 @@ +/**************************************************************************** + * boards/risc-v/mpfs/icicle/src/mpfs_ostest.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#undef HAVE_FPU +#if defined(CONFIG_ARCH_FPU) && \ + !defined(CONFIG_TESTING_OSTEST_FPUTESTDISABLE) && \ + defined(CONFIG_TESTING_OSTEST_FPUSIZE) && \ + defined(CONFIG_SCHED_WAITPID) +# define HAVE_FPU 1 +#endif + +#ifdef HAVE_FPU + +#if CONFIG_TESTING_OSTEST_FPUSIZE != (8 * FPU_XCPT_REGS) +# error "CONFIG_TESTING_OSTEST_FPUSIZE has the wrong size" +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint64_t g_saveregs[XCPTCONTEXT_REGS]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* Given an array of size CONFIG_TESTING_OSTEST_FPUSIZE, this function will + * return the current FPU registers. + */ + +void arch_getfpu(FAR uint32_t *fpusave) +{ + irqstate_t flags; + + /* Take a snapshot of the thread context right now */ + + flags = enter_critical_section(); + riscv_saveusercontext(g_saveregs); + + /* Return only the floating register values */ + + memcpy(fpusave, &g_saveregs[INT_XCPT_REGS], (8 * FPU_XCPT_REGS)); + leave_critical_section(flags); +} + +/* Given two arrays of size CONFIG_TESTING_OSTEST_FPUSIZE this function + * will compare them and return true if they are identical. + */ + +bool arch_cmpfpu(FAR const uint32_t *fpusave1, FAR const uint32_t *fpusave2) +{ + return memcmp(fpusave1, fpusave2, (8 * FPU_XCPT_REGS)) == 0; +} + +#endif /* HAVE_FPU */ diff --git a/boards/risc-v/mpfs/icicle/src/mpfsicicle.h b/boards/risc-v/mpfs/icicle/src/mpfsicicle.h new file mode 100755 index 0000000000..4bfbc5b815 --- /dev/null +++ b/boards/risc-v/mpfs/icicle/src/mpfsicicle.h @@ -0,0 +1,46 @@ +/**************************************************************************** + * boards/risc-v/mpfs/icicle/src/mpfsicicle.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_ICICLE_MPFS_SRC_MPFSICICLE_H +#define __BOARDS_RISCV_ICICLE_MPFS_SRC_MPFSICICLE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#define ICICLE_GPIO_LED1 (GPIO_BANK2 | GPIO_PIN19 | GPIO_OUTPUT) +#define ICICLE_GPIO_LED2 (GPIO_BANK2 | GPIO_PIN18 | GPIO_OUTPUT) +#define ICICLE_GPIO_LED3 (GPIO_BANK2 | GPIO_PIN17 | GPIO_OUTPUT) +#define ICICLE_GPIO_LED4 (GPIO_BANK2 | GPIO_PIN16 | GPIO_OUTPUT) + +/* note: button1 don't have gpio. Only irq */ + +#define ICICLE_GPIO_BUTTON2 (GPIO_BANK2 | GPIO_PIN30 | GPIO_INPUT | \ + GPIO_IRQ_ENABLE | GPIO_IRQ_EDGE_POS) +#define ICICLE_GPIO_BUTTON2_ALT (GPIO_BANK2 | GPIO_PIN26 | GPIO_OUTPUT) +#define ICICLE_GPIO_BUTTON3 (GPIO_BANK2 | GPIO_PIN31 | GPIO_INPUT | \ + GPIO_IRQ_ENABLE | GPIO_IRQ_EDGE_POS) +#define ICICLE_GPIO_BUTTON3_ALT (GPIO_BANK2 | GPIO_PIN27 | GPIO_OUTPUT) + +int mpfs_bringup(void); + +#endif /* __BOARDS_RISCV_ICICLE_MPFS_SRC_MPFSICICLE_H */