From fa3731397f8a67c7349f82ebd73ea36d31e5a863 Mon Sep 17 00:00:00 2001 From: MuChenger Date: Tue, 21 Oct 2025 14:55:25 +0800 Subject: [PATCH 1/4] =?UTF-8?q?[add]=20=E6=B7=BB=E5=8A=A0E901=20bsp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chip_riscv_dummy/gcc_flash_smartl_lite.ld | 268 ++++ .../gcc_flash_smartm_fixed.ld | 281 ++++ .../gcc_flash_smartm_flexible.ld | 273 ++++ .../chip_riscv_dummy/src/arch/e901/SConscript | 13 + .../chip_riscv_dummy/src/arch/e901/startup.S | 200 +++ .../chip_riscv_dummy/src/arch/e901/system.c | 105 ++ .../chip_riscv_dummy/src/arch/e901/trap_c.c | 67 + .../chip_riscv_dummy/src/arch/e901/vectors.S | 496 ++++++ .../chip_riscv_dummy/src/sys/SConscript | 1 + .../chip_riscv_dummy/src/sys/feature.c | 319 ++++ .../csi/csi2/include/core/core_rv32.h | 103 +- .../csi/csi2/include/core/core_rv64.h | 164 +- .../csi/csi2/include/core/csi_arm64_gcc.h | 74 +- .../csi/csi2/include/core/csi_gcc.h | 58 +- .../csi/csi2/include/core/csi_rv32_gcc.h | 531 +++++- .../csi/csi2/include/core/csi_rv64_gcc.h | 188 ++- .../csi/csi2/include/core/csi_rv_common.h | 62 +- .../csi/csi2/include/csi_core.h | 38 +- .../csi/csi2/include/syslog.h | 1 + bsp/xuantie/smartl/e901/.config | 1418 +++++++++++++++++ bsp/xuantie/smartl/e901/.cproject | 929 +++++++++++ bsp/xuantie/smartl/e901/.project | 27 + .../.settings/org.eclipse.core.runtime.prefs | 3 + bsp/xuantie/smartl/e901/.settings/projcfg.ini | 20 + bsp/xuantie/smartl/e901/Kconfig | 18 + bsp/xuantie/smartl/e901/README.md | 100 ++ bsp/xuantie/smartl/e901/SConscript | 19 + bsp/xuantie/smartl/e901/SConstruct | 54 + .../smartl/e901/applications/SConscript | 10 + bsp/xuantie/smartl/e901/applications/main.c | 19 + bsp/xuantie/smartl/e901/board/Kconfig | 30 + bsp/xuantie/smartl/e901/board/SConscript | 33 + bsp/xuantie/smartl/e901/board/board.c | 42 + bsp/xuantie/smartl/e901/board/board.h | 443 +++++ bsp/xuantie/smartl/e901/figures/1.env.png | Bin 0 -> 27810 bytes bsp/xuantie/smartl/e901/figures/2.scons.png | Bin 0 -> 50557 bytes bsp/xuantie/smartl/e901/figures/3.vscode.png | Bin 0 -> 168160 bytes bsp/xuantie/smartl/e901/objdump.bat | 8 + bsp/xuantie/smartl/e901/qemu.bat | 91 ++ bsp/xuantie/smartl/e901/rtconfig.h | 419 +++++ bsp/xuantie/smartl/e901/rtconfig.py | 98 ++ bsp/xuantie/smartl/e901/rtconfig_preinc.h | 29 + bsp/xuantie/smartl/e901/template.cdkproj | 250 +++ bsp/xuantie/smartl/e901/template.cdkws | 11 + bsp/xuantie/smartl/e901/utilities/gdb.init | 6 + 45 files changed, 7082 insertions(+), 237 deletions(-) create mode 100644 bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/gcc_flash_smartl_lite.ld create mode 100644 bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/gcc_flash_smartm_fixed.ld create mode 100644 bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/gcc_flash_smartm_flexible.ld create mode 100644 bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/SConscript create mode 100644 bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/startup.S create mode 100644 bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/system.c create mode 100644 bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/trap_c.c create mode 100644 bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/vectors.S create mode 100644 bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/sys/feature.c create mode 100644 bsp/xuantie/smartl/e901/.config create mode 100644 bsp/xuantie/smartl/e901/.cproject create mode 100644 bsp/xuantie/smartl/e901/.project create mode 100644 bsp/xuantie/smartl/e901/.settings/org.eclipse.core.runtime.prefs create mode 100644 bsp/xuantie/smartl/e901/.settings/projcfg.ini create mode 100644 bsp/xuantie/smartl/e901/Kconfig create mode 100644 bsp/xuantie/smartl/e901/README.md create mode 100644 bsp/xuantie/smartl/e901/SConscript create mode 100644 bsp/xuantie/smartl/e901/SConstruct create mode 100644 bsp/xuantie/smartl/e901/applications/SConscript create mode 100644 bsp/xuantie/smartl/e901/applications/main.c create mode 100644 bsp/xuantie/smartl/e901/board/Kconfig create mode 100644 bsp/xuantie/smartl/e901/board/SConscript create mode 100644 bsp/xuantie/smartl/e901/board/board.c create mode 100644 bsp/xuantie/smartl/e901/board/board.h create mode 100644 bsp/xuantie/smartl/e901/figures/1.env.png create mode 100644 bsp/xuantie/smartl/e901/figures/2.scons.png create mode 100644 bsp/xuantie/smartl/e901/figures/3.vscode.png create mode 100644 bsp/xuantie/smartl/e901/objdump.bat create mode 100644 bsp/xuantie/smartl/e901/qemu.bat create mode 100644 bsp/xuantie/smartl/e901/rtconfig.h create mode 100644 bsp/xuantie/smartl/e901/rtconfig.py create mode 100644 bsp/xuantie/smartl/e901/rtconfig_preinc.h create mode 100644 bsp/xuantie/smartl/e901/template.cdkproj create mode 100644 bsp/xuantie/smartl/e901/template.cdkws create mode 100644 bsp/xuantie/smartl/e901/utilities/gdb.init diff --git a/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/gcc_flash_smartl_lite.ld b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/gcc_flash_smartl_lite.ld new file mode 100644 index 00000000000..84b9963c516 --- /dev/null +++ b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/gcc_flash_smartl_lite.ld @@ -0,0 +1,268 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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. + */ + +/****************************************************************************** + * @file gcc_csky.ld + * @brief csky linker file + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +MEMORY +{ + ISRAM : ORIGIN = 0x00000000 , LENGTH = 0x20000 /* ISRAM 128KB*/ + DSRAM : ORIGIN = 0x20000000 , LENGTH = 0x80000 /* DSRAM 512KB*/ + SRAM : ORIGIN = 0x60000000 , LENGTH = 0x20000 /* SRAM 128KB, no cacheable*/ +} + +__min_heap_size = 0x200; +PROVIDE (__ram_end = 0x20080000); +PROVIDE (__heap_end = __ram_end); + +REGION_ALIAS("REGION_TEXT", ISRAM); +REGION_ALIAS("REGION_RODATA", ISRAM); +REGION_ALIAS("REGION_DATA", DSRAM); +REGION_ALIAS("REGION_BSS", DSRAM); + +ENTRY(Reset_Handler) +SECTIONS +{ + .text : { + . = ALIGN(0x4) ; + __stext = . ; + KEEP(*startup.o(*.text)) + KEEP(*startup.o(*.vectors)) + KEEP(*vectors.o(*.text)) + KEEP(*(.text.entry)) + *(.text*) + *(.gnu.warning) + *(.stub) + *(.gnu.linkonce.t*) + *(.glue_7t) + *(.glue_7) + *(.jcr) + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN (0x4) ; + PROVIDE(__ctbp = .); + *(.call_table_data) + *(.call_table_text) + . = ALIGN(0x10) ; + __etext = . ; + } > REGION_TEXT + .eh_frame_hdr : { + *(.eh_frame_hdr) + } > REGION_TEXT + .eh_frame : ONLY_IF_RO { + KEEP (*(.eh_frame)) + } > REGION_TEXT + .rodata : { + . = ALIGN(0x4) ; + __srodata = .; + *(.rdata) + *(.rdata*) + *(.rdata1) + *(.rdata.*) + *(.rodata*) + *(.srodata*) + . = ALIGN(0x4) ; + __init_array_start = .; + __ctors_start__ = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + __ctors_end__ = .; + + __fini_array_start = .; + __dtors_start__ = .; + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array)) + __fini_array_end = .; + __dtors_end__ = .; + . = ALIGN(0x4) ; + + __ctor_start__ = .; + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __ctor_end__ = .; + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __dtor_end__ = .; + . = ALIGN(0x4) ; +/*****************************************/ + /* section information for finsh shell */ + . = ALIGN(0x4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(0x4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(0x4); + + /* section information for initial. */ + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(0x4) ; + + /* section information for at utest */ + __rt_utest_tc_tab_start = .; + KEEP(*(UtestTcTab)) + __rt_utest_tc_tab_end = .; + . = ALIGN(0x4); + + /* section information for at server */ + . = ALIGN(0x4); + __rtatcmdtab_start = .; + KEEP(*(RtAtCmdTab)) + __rtatcmdtab_end = .; + . = ALIGN(0x4); + + /* section information for modules */ + . = ALIGN(0x4); + __rtmsymtab_start = .; + KEEP(*(RTMSymTab)) + __rtmsymtab_end = .; + + /* section information for uPRC */ + . = ALIGN(0x4); + __uRPCSvcTab_start = .; + KEEP(*(uRPCSvcTab)) + __uRPCSvcTab_end = .; + + /* section information for var export */ + . = ALIGN(0x4); + __ve_table_start = .; + KEEP(*(SORT(*.VarExpTab.*))) + __ve_table_end = .; +/*****************************************/ +/************** added drivers **************/ + _cli_region_begin = .; + KEEP(*(CliRegion)) + . = ALIGN(0x4); + _cli_region_end = .; + + __core_driver_start__ = .; + KEEP(*(.core_driver_entry)) + . = ALIGN(0x4); + __core_driver_end__ = .; + + __bus_driver_start__ = .; + KEEP(*(*.bus_driver_entry)) + __bus_driver_end__ = .; + + __early_driver_start__ = .; + KEEP(*(*.early_driver_entry)) + __early_driver_end__ = .; + + __vfs_driver_start__ = .; + KEEP(*(*.vfs_driver_entry)) + __vfs_driver_end__ = .; + + __level0_driver_start__ = .; + KEEP(*(*.level0_driver_entry)) + __level0_driver_end__ = .; + + __level1_driver_start__ = .; + KEEP(*(*.level1_driver_entry)) + __level1_driver_end__ = .; + + __level2_driver_start__ = .; + KEEP(*(*.level2_driver_entry)) + __level2_driver_end__ = .; + + __level3_driver_start__ = .; + KEEP(*(*.level3_driver_entry)) + __level3_driver_end__ = .; + + __post_driver_start__ = .; + KEEP(*(*.post_driver_entry)) + __post_driver_end__ = .; +/************** end of drivers *********/ + . = ALIGN(0x40) ; + __jvt_base$ = .; + KEEP(*(*.riscv.jvt)) + . = ALIGN(0x8) ; + __erodata = .; + __rodata_end__ = .; + } > REGION_RODATA + .data : { + . = ALIGN(0x4) ; + __sdata = . ; + __data_start__ = . ; + data_start = . ; + *(.got.plt) + *(.got) + *(.gnu.linkonce.r*) + *(.data*) + *(.gnu.linkonce.d*) + *(.gcc_except_table*) + __start_init_call = .; + *(.initcall.init) + __stop_init_call = .; + __start_cmd = .; + *(.bootloaddata.cmd) + . = ALIGN(0x4) ; + __stop_cmd = .; + __global_pointer$ = .; + *(.sdata) + *(.sdata.*) + *(.sdata2.*) + *(.gnu.linkonce.s.*) + *(__libc_atexit) + *(__libc_subinit) + *(__libc_subfreeres) + *(.note.ABI-tag) + . = ALIGN(0x4) ; + __edata = .; + __data_end__ = .; + } > REGION_DATA AT > REGION_RODATA + ._ram_code : { + . = ALIGN(0x4) ; + __ram_code_start__ = .; + *(.ram.code*) + . = ALIGN(0x4) ; + __ram_code_end__ = .; + } > REGION_DATA AT > REGION_RODATA + .bss : { + . = ALIGN(0x4) ; + __sbss = ALIGN(0x4) ; + __bss_start__ = . ; + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.scommon) + *(.dynbss) + *(.bss*) + *(COMMON) + . = ALIGN(0x4) ; + __ebss = . ; + __bss_end__ = .; + __end = . ; + end = . ; + } > REGION_BSS AT > REGION_BSS + ._user_heap (NOLOAD): { + . = ALIGN(0x4) ; + *(.stack*) + . = ALIGN(0x4) ; + __heap_start = .; + . += __min_heap_size; + . = ALIGN(0x4) ; + } > REGION_BSS AT > REGION_BSS +} \ No newline at end of file diff --git a/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/gcc_flash_smartm_fixed.ld b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/gcc_flash_smartm_fixed.ld new file mode 100644 index 00000000000..a41f23ee081 --- /dev/null +++ b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/gcc_flash_smartm_fixed.ld @@ -0,0 +1,281 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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. + */ + +/****************************************************************************** + * @file gcc_csky.ld + * @brief csky linker file + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +MEMORY +{ + ISRAM : ORIGIN = 0x00000000 , LENGTH = 0x20000 /* ISRAM 128KB*/ + DSRAM : ORIGIN = 0x00100000 , LENGTH = 0x80000 /* DSRAM 512KB*/ + SRAM : ORIGIN = 0x001D0000 , LENGTH = 0x20000 /* SRAM 128KB, no cacheable*/ +} + +__min_heap_size = 0x200; +PROVIDE (__ram_end = 0x00180000); +PROVIDE (__heap_end = __ram_end); + +REGION_ALIAS("REGION_TEXT", ISRAM); +REGION_ALIAS("REGION_RODATA", ISRAM); +REGION_ALIAS("REGION_DATA", DSRAM); +REGION_ALIAS("REGION_BSS", DSRAM); + +ENTRY(Reset_Handler) +SECTIONS +{ + .text : { + . = ALIGN(0x4) ; + __stext = . ; + KEEP(*startup.o(*.text)) + } > REGION_TEXT + .mtvec 0x40 : { + KEEP(*vectors.o(*.mtvec)) + } > REGION_TEXT + . = MAX(., 0x80); + .vectors 0x80 : { + KEEP(*startup.o(*.vectors)) + } > REGION_TEXT + . = MAX(., 0x300); + .text 0x300 : { + __jvt_base$ = .; + KEEP(*(*.riscv.jvt)) + . = ALIGN(0x4) ; + __jvt_end$ = .; + } > REGION_TEXT + .text : { + . = ALIGN(0x4) ; + KEEP(*vectors.o(*.text)) + KEEP(*(.text.entry)) + *(.text*) + *(.gnu.warning) + *(.stub) + *(.gnu.linkonce.t*) + *(.glue_7t) + *(.glue_7) + *(.jcr) + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN (0x4) ; + PROVIDE(__ctbp = .); + *(.call_table_data) + *(.call_table_text) + . = ALIGN(0x10) ; + __etext = . ; + } > REGION_TEXT + .eh_frame_hdr : { + *(.eh_frame_hdr) + } > REGION_TEXT + .eh_frame : ONLY_IF_RO { + KEEP (*(.eh_frame)) + } > REGION_TEXT + .rodata : { + . = ALIGN(0x4) ; + __srodata = .; + *(.rdata) + *(.rdata*) + *(.rdata1) + *(.rdata.*) + *(.rodata*) + *(.srodata*) + . = ALIGN(0x4) ; + __init_array_start = .; + __ctors_start__ = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + __ctors_end__ = .; + + __fini_array_start = .; + __dtors_start__ = .; + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array)) + __fini_array_end = .; + __dtors_end__ = .; + . = ALIGN(0x4) ; + + __ctor_start__ = .; + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __ctor_end__ = .; + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __dtor_end__ = .; + . = ALIGN(0x4) ; +/*****************************************/ + /* section information for finsh shell */ + . = ALIGN(0x4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(0x4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(0x4); + + /* section information for initial. */ + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(0x4) ; + + /* section information for at utest */ + __rt_utest_tc_tab_start = .; + KEEP(*(UtestTcTab)) + __rt_utest_tc_tab_end = .; + . = ALIGN(0x4); + + /* section information for at server */ + . = ALIGN(0x4); + __rtatcmdtab_start = .; + KEEP(*(RtAtCmdTab)) + __rtatcmdtab_end = .; + . = ALIGN(0x4); + + /* section information for modules */ + . = ALIGN(0x4); + __rtmsymtab_start = .; + KEEP(*(RTMSymTab)) + __rtmsymtab_end = .; + + /* section information for uPRC */ + . = ALIGN(0x4); + __uRPCSvcTab_start = .; + KEEP(*(uRPCSvcTab)) + __uRPCSvcTab_end = .; + + /* section information for var export */ + . = ALIGN(0x4); + __ve_table_start = .; + KEEP(*(SORT(*.VarExpTab.*))) + __ve_table_end = .; +/*****************************************/ +/************** added drivers **************/ + _cli_region_begin = .; + KEEP(*(CliRegion)) + . = ALIGN(0x4); + _cli_region_end = .; + + __core_driver_start__ = .; + KEEP(*(.core_driver_entry)) + . = ALIGN(0x4); + __core_driver_end__ = .; + + __bus_driver_start__ = .; + KEEP(*(*.bus_driver_entry)) + __bus_driver_end__ = .; + + __early_driver_start__ = .; + KEEP(*(*.early_driver_entry)) + __early_driver_end__ = .; + + __vfs_driver_start__ = .; + KEEP(*(*.vfs_driver_entry)) + __vfs_driver_end__ = .; + + __level0_driver_start__ = .; + KEEP(*(*.level0_driver_entry)) + __level0_driver_end__ = .; + + __level1_driver_start__ = .; + KEEP(*(*.level1_driver_entry)) + __level1_driver_end__ = .; + + __level2_driver_start__ = .; + KEEP(*(*.level2_driver_entry)) + __level2_driver_end__ = .; + + __level3_driver_start__ = .; + KEEP(*(*.level3_driver_entry)) + __level3_driver_end__ = .; + + __post_driver_start__ = .; + KEEP(*(*.post_driver_entry)) + __post_driver_end__ = .; +/************** end of drivers *********/ + . = ALIGN(0x8) ; + __erodata = .; + __rodata_end__ = .; + } > REGION_RODATA + .data : { + . = ALIGN(0x4) ; + __sdata = . ; + __data_start__ = . ; + data_start = . ; + *(.got.plt) + *(.got) + *(.gnu.linkonce.r*) + *(.data*) + *(.gnu.linkonce.d*) + *(.gcc_except_table*) + __start_init_call = .; + *(.initcall.init) + __stop_init_call = .; + __start_cmd = .; + *(.bootloaddata.cmd) + . = ALIGN(0x4) ; + __stop_cmd = .; + __global_pointer$ = .; + *(.sdata) + *(.sdata.*) + *(.sdata2.*) + *(.gnu.linkonce.s.*) + *(__libc_atexit) + *(__libc_subinit) + *(__libc_subfreeres) + *(.note.ABI-tag) + . = ALIGN(0x4) ; + __edata = .; + __data_end__ = .; + } > REGION_DATA AT > REGION_RODATA + ._ram_code : { + . = ALIGN(0x4) ; + __ram_code_start__ = .; + *(.ram.code*) + . = ALIGN(0x4) ; + __ram_code_end__ = .; + } > REGION_DATA AT > REGION_RODATA + .bss : { + . = ALIGN(0x4) ; + __sbss = ALIGN(0x4) ; + __bss_start__ = . ; + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.scommon) + *(.dynbss) + *(.bss*) + *(COMMON) + . = ALIGN(0x4) ; + __ebss = . ; + __bss_end__ = .; + __end = . ; + end = . ; + } > REGION_BSS AT > REGION_BSS + ._user_heap (NOLOAD): { + . = ALIGN(0x4) ; + *(.stack*) + . = ALIGN(0x4) ; + __heap_start = .; + . += __min_heap_size; + . = ALIGN(0x4) ; + } > REGION_BSS AT > REGION_BSS +} diff --git a/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/gcc_flash_smartm_flexible.ld b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/gcc_flash_smartm_flexible.ld new file mode 100644 index 00000000000..a7f985aa437 --- /dev/null +++ b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/gcc_flash_smartm_flexible.ld @@ -0,0 +1,273 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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. + */ + +/****************************************************************************** + * @file gcc_csky.ld + * @brief csky linker file + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +MEMORY +{ + ISRAM : ORIGIN = 0x00000000 , LENGTH = 0x20000 /* ISRAM 128KB*/ + DSRAM : ORIGIN = 0x00100000 , LENGTH = 0x80000 /* DSRAM 512KB*/ + SRAM : ORIGIN = 0x001D0000 , LENGTH = 0x20000 /* SRAM 128KB, no cacheable*/ +} + +__min_heap_size = 0x200; +PROVIDE (__ram_end = 0x00180000); +PROVIDE (__heap_end = __ram_end); + +REGION_ALIAS("REGION_TEXT", ISRAM); +REGION_ALIAS("REGION_RODATA", ISRAM); +REGION_ALIAS("REGION_DATA", DSRAM); +REGION_ALIAS("REGION_BSS", DSRAM); + +ENTRY(Reset_Handler) +SECTIONS +{ + .text : { + . = ALIGN(0x4) ; + __stext = . ; + KEEP(*startup.o(*.text)) + KEEP(*startup.o(*.vectors)) + . = ALIGN(0x40) ; + KEEP(*vectors.o(*.mtvec)) + } > REGION_TEXT + .text : { + . = ALIGN(0x4) ; + KEEP(*vectors.o(*.text)) + KEEP(*(.text.entry)) + *(.text*) + *(.gnu.warning) + *(.stub) + *(.gnu.linkonce.t*) + *(.glue_7t) + *(.glue_7) + *(.jcr) + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN (0x4) ; + PROVIDE(__ctbp = .); + *(.call_table_data) + *(.call_table_text) + . = ALIGN(0x10) ; + __etext = . ; + } > REGION_TEXT + .eh_frame_hdr : { + *(.eh_frame_hdr) + } > REGION_TEXT + .eh_frame : ONLY_IF_RO { + KEEP (*(.eh_frame)) + } > REGION_TEXT + .rodata : { + . = ALIGN(0x4) ; + __srodata = .; + *(.rdata) + *(.rdata*) + *(.rdata1) + *(.rdata.*) + *(.rodata*) + *(.srodata*) + . = ALIGN(0x4) ; + __init_array_start = .; + __ctors_start__ = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + __ctors_end__ = .; + + __fini_array_start = .; + __dtors_start__ = .; + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array)) + __fini_array_end = .; + __dtors_end__ = .; + . = ALIGN(0x4) ; + + __ctor_start__ = .; + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __ctor_end__ = .; + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __dtor_end__ = .; + . = ALIGN(0x4) ; +/*****************************************/ + /* section information for finsh shell */ + . = ALIGN(0x4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(0x4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(0x4); + + /* section information for initial. */ + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(0x4) ; + + /* section information for at utest */ + __rt_utest_tc_tab_start = .; + KEEP(*(UtestTcTab)) + __rt_utest_tc_tab_end = .; + . = ALIGN(0x4); + + /* section information for at server */ + . = ALIGN(0x4); + __rtatcmdtab_start = .; + KEEP(*(RtAtCmdTab)) + __rtatcmdtab_end = .; + . = ALIGN(0x4); + + /* section information for modules */ + . = ALIGN(0x4); + __rtmsymtab_start = .; + KEEP(*(RTMSymTab)) + __rtmsymtab_end = .; + + /* section information for uPRC */ + . = ALIGN(0x4); + __uRPCSvcTab_start = .; + KEEP(*(uRPCSvcTab)) + __uRPCSvcTab_end = .; + + /* section information for var export */ + . = ALIGN(0x4); + __ve_table_start = .; + KEEP(*(SORT(*.VarExpTab.*))) + __ve_table_end = .; +/*****************************************/ +/************** added drivers **************/ + _cli_region_begin = .; + KEEP(*(CliRegion)) + . = ALIGN(0x4); + _cli_region_end = .; + + __core_driver_start__ = .; + KEEP(*(.core_driver_entry)) + . = ALIGN(0x4); + __core_driver_end__ = .; + + __bus_driver_start__ = .; + KEEP(*(*.bus_driver_entry)) + __bus_driver_end__ = .; + + __early_driver_start__ = .; + KEEP(*(*.early_driver_entry)) + __early_driver_end__ = .; + + __vfs_driver_start__ = .; + KEEP(*(*.vfs_driver_entry)) + __vfs_driver_end__ = .; + + __level0_driver_start__ = .; + KEEP(*(*.level0_driver_entry)) + __level0_driver_end__ = .; + + __level1_driver_start__ = .; + KEEP(*(*.level1_driver_entry)) + __level1_driver_end__ = .; + + __level2_driver_start__ = .; + KEEP(*(*.level2_driver_entry)) + __level2_driver_end__ = .; + + __level3_driver_start__ = .; + KEEP(*(*.level3_driver_entry)) + __level3_driver_end__ = .; + + __post_driver_start__ = .; + KEEP(*(*.post_driver_entry)) + __post_driver_end__ = .; +/************** end of drivers *********/ + . = ALIGN(0x40) ; + __jvt_base$ = .; + KEEP(*(*.riscv.jvt)) + . = ALIGN(0x8) ; + __erodata = .; + __rodata_end__ = .; + } > REGION_RODATA + .data : { + . = ALIGN(0x4) ; + __sdata = . ; + __data_start__ = . ; + data_start = . ; + *(.got.plt) + *(.got) + *(.gnu.linkonce.r*) + *(.data*) + *(.gnu.linkonce.d*) + *(.gcc_except_table*) + __start_init_call = .; + *(.initcall.init) + __stop_init_call = .; + __start_cmd = .; + *(.bootloaddata.cmd) + . = ALIGN(0x4) ; + __stop_cmd = .; + __global_pointer$ = .; + *(.sdata) + *(.sdata.*) + *(.sdata2.*) + *(.gnu.linkonce.s.*) + *(__libc_atexit) + *(__libc_subinit) + *(__libc_subfreeres) + *(.note.ABI-tag) + . = ALIGN(0x4) ; + __edata = .; + __data_end__ = .; + } > REGION_DATA AT > REGION_RODATA + ._ram_code : { + . = ALIGN(0x4) ; + __ram_code_start__ = .; + *(.ram.code*) + . = ALIGN(0x4) ; + __ram_code_end__ = .; + } > REGION_DATA AT > REGION_RODATA + .bss : { + . = ALIGN(0x4) ; + __sbss = ALIGN(0x4) ; + __bss_start__ = . ; + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.scommon) + *(.dynbss) + *(.bss*) + *(COMMON) + . = ALIGN(0x4) ; + __ebss = . ; + __bss_end__ = .; + __end = . ; + end = . ; + } > REGION_BSS AT > REGION_BSS + ._user_heap (NOLOAD): { + . = ALIGN(0x4) ; + *(.stack*) + . = ALIGN(0x4) ; + __heap_start = .; + . += __min_heap_size; + . = ALIGN(0x4) ; + } > REGION_BSS AT > REGION_BSS +} diff --git a/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/SConscript b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/SConscript new file mode 100644 index 00000000000..7c13ee46652 --- /dev/null +++ b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/SConscript @@ -0,0 +1,13 @@ +from building import * +import os + +cwd = GetCurrentDir() +CPPPATH = [cwd] +src = ['startup.S'] +src += ['system.c'] +src += ['trap_c.c'] +src += ['vectors.S'] + +group = DefineGroup('sys', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/startup.S b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/startup.S new file mode 100644 index 00000000000..e22ef51e435 --- /dev/null +++ b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/startup.S @@ -0,0 +1,200 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 +.global __rt_rvstack +#ifndef CONFIG_SUPPORT_NON_VECTOR_IRQ +.section .vectors, "aw", @progbits + .align 6 + .globl __Vectors + .type __Vectors, @object +__Vectors: + .long Default_Handler + .long Default_Handler + .long Default_Handler + .long tspend_handler + .long Default_Handler + .long Default_Handler + .long Default_Handler + .long Default_IRQHandler + .long Default_Handler + .long Default_Handler + .long Default_Handler + .long Default_Handler + .long Default_Handler + .long Default_Handler + .long Default_Handler + .long Default_Handler + + /* External interrupts */ + .long Default_IRQHandler +#if CONFIG_IRQ_LATENCY + .long IRQ_LATENCY_IRQHandler +#else + .long Default_IRQHandler +#endif + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler +#else +.section .vectors, "aw", @progbits + .align 6 + .globl __Vectors + .type __Vectors, @object +__Vectors: + .long do_irq + .long do_irq + .long do_irq + .long tspend_handler + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + + /* External interrupts */ + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq +#endif + + .text + .align 2 + j Reset_Handler + .align 2 + .long 0x594B5343 /* CSKY ASCII */ + .long 0x594B5343 /* CSKY ASCII */ + .align 2 +_start: + .text + .globl Reset_Handler + .align 2 + .type Reset_Handler, %function +Reset_Handler: +.option push +.option norelax + la gp, __global_pointer$ + la a0, __jvt_base$ + csrw jvt, a0 +.option pop + la a0, Default_Handler + ori a0, a0, 3 + csrw mtvec, a0 + + la a0, __Vectors + csrw mtvt, a0 + + la sp, g_top_irqstack + csrw mscratch, sp +#ifdef CONFIG_KERNEL_NONE + la sp, g_top_mainstack +#endif + +#ifndef __NO_SYSTEM_INIT + jal SystemInit +#endif + + jal rtthread_startup + + .size Reset_Handler, . - Reset_Handler + +__exit: + j __exit + +.section .stack, "aw", @nobits + .align 3 + .global g_base_irqstack + .global g_top_irqstack +g_base_irqstack: + .space CONFIG_ARCH_INTERRUPTSTACK +g_top_irqstack: +__rt_rvstack: +#ifdef CONFIG_KERNEL_NONE + .align 3 + .global g_base_mainstack + .global g_top_mainstack +g_base_mainstack: + .space CONFIG_ARCH_MAINSTACK +g_top_mainstack: +#endif + +.section .data + .weak __jvt_base$ + .long 0 diff --git a/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/system.c b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/system.c new file mode 100644 index 00000000000..41dcf7f64c1 --- /dev/null +++ b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/system.c @@ -0,0 +1,105 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 +#include +#include +#include +#include +#include +#include +#include +#include "riscv_csr.h" + +#if (defined(CONFIG_KERNEL_RHINO) || defined(CONFIG_KERNEL_FREERTOS) || defined(CONFIG_KERNEL_RTTHREAD)) && defined(CONFIG_KERNEL_NONE) +#error "Please check the current system is baremetal or not!!!" +#endif + +extern void section_data_copy(void); +extern void section_ram_code_copy(void); +extern void section_bss_clear(void); + +static void cache_init(void) +{ + csi_icache_enable(); +} + +static void section_init(void) +{ +#if CONFIG_XIP + section_data_copy(); + section_ram_code_copy(); +#endif + + section_bss_clear(); +} + +static void clic_init(void) +{ + int i; + + /* get interrupt level from info */ + CLIC->CLICCFG = (((CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos) << CLIC_CLICCFG_NLBIT_Pos); + + for (i = 0; i < 64; i++) + { + CLIC->CLICINT[i].IP = 0; +#ifndef CONFIG_SUPPORT_NON_VECTOR_IRQ + CLIC->CLICINT[i].ATTR = 1; /* use vector interrupt */ +#else + CLIC->CLICINT[i].ATTR = 0; /* use non-vector interrupt */ +#endif + csi_vic_set_prio(i, 3); + } + /* tspend use vector&positive interrupt */ + CLIC->CLICINT[Machine_Software_IRQn].ATTR = 0x3; + csi_vic_set_prio(Machine_Software_IRQn, 1); + csi_irq_enable(Machine_Software_IRQn); +} + +static void interrupt_init(void) +{ + clic_init(); +#ifdef CONFIG_KERNEL_NONE + __enable_excp_irq(); +#endif +} + +/** + * @brief initialize the system + * Initialize the psr and vbr. + * @param None + * @return None + */ +void SystemInit(void) +{ + extern int cpu_features_init(void); + cpu_features_init(); + + /* enable XUANTIEISAEE & COPINSTEE */ + uint32_t status = __get_MXSTATUS(); + status |= (1 << 22) | (1 << 24); + __set_MXSTATUS(status); + + cache_init(); + section_init(); + interrupt_init(); + soc_set_sys_freq(20000000); + csi_tick_init(); +} + diff --git a/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/trap_c.c b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/trap_c.c new file mode 100644 index 00000000000..8a0942f17f3 --- /dev/null +++ b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/trap_c.c @@ -0,0 +1,67 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 +#include +#include +#include +#if defined(AOS_COMP_DEBUG) && (AOS_COMP_DEBUG > 0) +#include +#else +#define printk printf +#endif + +void (*trap_c_callback)(void); + +void trap_c(uintptr_t *regs) +{ + int i; + unsigned long vec = 0; + + vec = __get_MCAUSE(); + + printk("CPU Exception(mcause);: NO.0x%lx", vec); + printk("\n"); + + for (i = 0; i < 15; i++) + { + printk("x%d: %p\t", i + 1, (void *)regs[i]); + + if ((i % 4) == 3) + { + printk("\n"); + } + } + + printk("\n"); + printk("mepc : %p\n", (void *)regs[15]); + printk("mstatus: %p\n", (void *)regs[16]); + + if (trap_c_callback) + { + trap_c_callback(); + } + + while (1); +} + +__attribute__((weak)) void exceptionHandler(void *context) +{ + trap_c((uintptr_t *)context); +} + diff --git a/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/vectors.S b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/vectors.S new file mode 100644 index 00000000000..7ca7f9c13ed --- /dev/null +++ b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/arch/e901/vectors.S @@ -0,0 +1,496 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 "riscv_asm_macro.h" + +#define RISCV_MCAUSE_IRQ_POS 31 +#define MSTATUS_IEN 8 + +.section .stack, "aw", @nobits + .align 2 + .global g_trapstackbase + .global g_top_trapstack +g_trapstackbase: + .space CONFIG_ARCH_INTERRUPTSTACK +g_top_trapstack: + +#if CONFIG_SUPPORT_IRQ_NESTED +#define IRQ_NESTED_MAX (6) +.section .bss + .align 2 + irq_nested_level: + .long 0 + + irq_nested_mcause: + .long 0, 0, 0, 0, 0, 0 +#endif + +/* for interrupt tail-chaining debug */ +#if CONFIG_DEBUG_TAIL_CHAINING + .global g_irq_tailchain_loops +g_irq_tailchain_loops: + .long 0 +#endif + +.text + +#if !CONFIG_SUPPORT_IRQ_NESTED + .align 2 + .weak Default_IRQHandler + .type Default_IRQHandler, %function +Default_IRQHandler: +#if CONFIG_PROFILING_PERF && CONFIG_PERF_BACKTRACE_USE_FP + addi sp, sp, -4 + sw s0, (sp) +#endif + csrw mscratch, sp + la sp, g_top_irqstack + addi sp, sp, -52 + sw t0, 4(sp) + sw t1, 8(sp) + sw t2, 12(sp) + csrr t0, mepc + csrr t1, mcause + csrr t2, mstatus + sw t1, 40(sp) + sw t0, 44(sp) + sw t2, 48(sp) + + sw ra, 0(sp) + sw a0, 16(sp) + sw a1, 20(sp) + sw a2, 24(sp) + sw a3, 28(sp) + sw a4, 32(sp) + sw a5, 36(sp) + + la t0, do_irq + jalr t0 + + lw a1, 40(sp) + andi a0, a1, 0x3FF + slli a0, a0, 2 + + /* clear pending */ + li a2, 0xE0801000 + add a2, a2, a0 + lb a3, 0(a2) + li a4, 1 + not a4, a4 + and a5, a4, a3 + sb a5, 0(a2) + + csrw mcause, a1 + + lw t0, 44(sp) + lw t1, 48(sp) + csrw mepc, t0 + csrw mstatus, t1 + lw ra, 0(sp) + lw t0, 4(sp) + lw t1, 8(sp) + lw t2, 12(sp) + lw a0, 16(sp) + lw a1, 20(sp) + lw a2, 24(sp) + lw a3, 28(sp) + lw a4, 32(sp) + lw a5, 36(sp) + + addi sp, sp, 52 + csrr sp, mscratch + +#if CONFIG_PROFILING_PERF && CONFIG_PERF_BACKTRACE_USE_FP + addi sp, sp, 4 +#endif + + mret +#else + .align 2 + .weak Default_IRQHandler + .type Default_IRQHandler, %function +Default_IRQHandler: + addi sp, sp, -8 + sw t0, 0(sp) + sw t1, 4(sp) + + la t0, irq_nested_level + lw t1, (t0) + addi t1, t1, 1 + sw t1, (t0) + + li t0, IRQ_NESTED_MAX + /* nested too deeply, may be error happens */ + bgt t1, t0, Default_Handler + + addi t1, t1, -1 + la t0, irq_nested_mcause + slli t1, t1, 2 + add t0, t0, t1 + csrr t1, mcause + sw t1, (t0) + + la t0, irq_nested_level + lw t1, (t0) + li t0, 1 + bgt t1, t0, .Lnested1 + +#if CONFIG_PROFILING_PERF && CONFIG_PERF_BACKTRACE_USE_FP + addi sp, sp, -8 + sw s0, (sp) + csrr t0, mepc + sw t0, 4(sp) +#endif + + csrw mscratch, sp + la sp, g_top_irqstack + j .Lnested2 +.Lnested1: + lw t0, 0(sp) + lw t1, 4(sp) + addi sp, sp, 8 +.Lnested2: + addi sp, sp, -52 + sw t0, 4(sp) + sw t1, 8(sp) + sw t2, 12(sp) + csrr t0, mepc + csrr t1, mcause + csrr t2, mstatus + sw t1, 40(sp) + sw t0, 44(sp) + sw t2, 48(sp) + + csrs mstatus, 8 + + sw ra, 0(sp) + sw a0, 16(sp) + sw a1, 20(sp) + sw a2, 24(sp) + sw a3, 28(sp) + sw a4, 32(sp) + sw a5, 36(sp) + + la t0, do_irq + jalr t0 + + csrc mstatus, 8 + + lw a1, 40(sp) + andi a0, a1, 0x3FF + slli a0, a0, 2 + + /* clear pending */ + li a2, 0xE0801000 + add a2, a2, a0 + lb a3, 0(a2) + li a4, 1 + not a4, a4 + and a5, a4, a3 + sb a5, 0(a2) + + la t0, irq_nested_level + lw t1, (t0) + addi t1, t1, -1 + sw t1, (t0) + bgt t1, zero, .Lnested3 + + csrw mcause, a1 + + lw t0, 44(sp) + lw t1, 48(sp) + csrw mepc, t0 + csrw mstatus, t1 + lw ra, 0(sp) + lw t0, 4(sp) + lw t1, 8(sp) + lw t2, 12(sp) + lw a0, 16(sp) + lw a1, 20(sp) + lw a2, 24(sp) + lw a3, 28(sp) + lw a4, 32(sp) + lw a5, 36(sp) + + addi sp, sp, 52 + csrr sp, mscratch +#if CONFIG_PROFILING_PERF && CONFIG_PERF_BACKTRACE_USE_FP + addi sp, sp, 8 +#endif + lw t0, 0(sp) + lw t1, 4(sp) + addi sp, sp, 8 + mret + +.Lnested3: + /* keep mpil in current mcause & load exception code before */ + addi t1, t1, -1 + la t0, irq_nested_mcause + slli t1, t1, 2 + add t1, t0, t1 + lw t0, (t1) + andi t0, t0, 0x3FF + andi a0, a1, 0xFFFFFC00 + or t0, a0, t0 + csrw mcause, t0 + lw t0, 44(sp) + lw t1, 48(sp) + csrw mepc, t0 + csrw mstatus, t1 + + lw ra, 0(sp) + lw t0, 4(sp) + lw t1, 8(sp) + lw t2, 12(sp) + lw a0, 16(sp) + lw a1, 20(sp) + lw a2, 24(sp) + lw a3, 28(sp) + lw a4, 32(sp) + lw a5, 36(sp) + + addi sp, sp, 52 + mret +#endif + + .size Default_IRQHandler, . - Default_IRQHandler + +/****************************************************************************** + * Functions: + * void trap(void); + * default exception handler + ******************************************************************************/ + .align 2 + .global trap + .type trap, %function +trap: + csrw mscratch, sp + la sp, g_top_trapstack + addi sp, sp, -76 + sw x1, (0 )(sp) + sw x3, (8 )(sp) + sw x4, (12)(sp) + sw x5, (16)(sp) + sw x6, (20)(sp) + sw x7, (24)(sp) + sw x8, (28)(sp) + sw x9, (32)(sp) + sw x10,(36)(sp) + sw x11,(40)(sp) + sw x12,(44)(sp) + sw x13,(48)(sp) + sw x14,(52)(sp) + sw x15,(56)(sp) + csrr a0, mepc + sw a0, (60)(sp) + csrr a0, mstatus + sw a0, (64)(sp) + csrr a0, mcause + sw a0, (68)(sp) + csrr a0, mtval + sw a0, (72)(sp) + csrr a0, mscratch + sw a0, (4 )(sp) + + mv a0, sp + la a1, exceptionHandler + jalr a1 + + .size trap, . - trap + + .align 6 + .weak Default_Handler + .type Default_Handler, %function +Default_Handler: + /* Check for nmi */ + addi sp, sp, -8 + sw t0, 0x0(sp) + sw t1, 0x4(sp) + csrr t0, mcause +#if (CONFIG_SUPPORT_NON_VECTOR_IRQ) && (!CONFIG_SUPPORT_IRQ_NESTED) + srli t1, t0, RISCV_MCAUSE_IRQ_POS + bnez t1, is_interrupt +#endif + andi t0, t0, 0x3FF + li t1, 24 + beq t0, t1, .NMI_Handler + lw t0, 0x0(sp) + lw t1, 0x4(sp) + addi sp, sp, 8 + j trap +#if (CONFIG_SUPPORT_NON_VECTOR_IRQ) && (!CONFIG_SUPPORT_IRQ_NESTED) +is_interrupt: + lw t0, 0x0(sp) + lw t1, 0x4(sp) + addi sp, sp, 8 + csrw mscratch, sp + la sp, g_top_irqstack + addi sp, sp, -52 + sw t0, 4(sp) + sw t1, 8(sp) + sw t2, 12(sp) + csrr t0, mepc + csrr t1, mcause + csrr t2, mstatus + sw t1, 40(sp) + sw t0, 44(sp) + sw t2, 48(sp) + + sw ra, 0(sp) + sw a0, 16(sp) + sw a1, 20(sp) + sw a2, 24(sp) + sw a3, 28(sp) + sw a4, 32(sp) + sw a5, 36(sp) + +#if CONFIG_DEBUG_TAIL_CHAINING + li t2, 0 + la t1, g_irq_tailchain_loops + sw t2, 0(t1) +#endif + + csrrsi t0, mnxti, MSTATUS_IEN + beqz t0, irq_done + +irq_loop: +#if CONFIG_DEBUG_TAIL_CHAINING + la t2, g_irq_tailchain_loops + lw t1, 0(t2) + addi t1, t1, 1 + sw t1, 0(t2) +#endif + lw t1, 0(t0) + jalr t1 + csrrsi t0, mnxti, MSTATUS_IEN + bnez t0, irq_loop + +#if CONFIG_DEBUG_TAIL_CHAINING + li t2, 0 + la a1, g_irq_tailchain_loops + sw t2, 0(a1) +#endif + +irq_done: + lw t0, 40(sp) + lw t1, 44(sp) + lw t2, 48(sp) + csrw mcause, t0 + csrw mepc, t1 + csrw mstatus, t2 + + lw ra, 0(sp) + lw t0, 4(sp) + lw t1, 8(sp) + lw t2, 12(sp) + lw a0, 16(sp) + lw a1, 20(sp) + lw a2, 24(sp) + lw a3, 28(sp) + lw a4, 32(sp) + lw a5, 36(sp) + + addi sp, sp, 52 + csrr sp, mscratch + mret +#endif /* (CONFIG_SUPPORT_NON_VECTOR_IRQ) && (!CONFIG_SUPPORT_IRQ_NESTED) */ +.NMI_Handler: + /* mscratch may be used before */ + addi sp, sp, -4 + csrr t0, mscratch + sw t0, 0x0(sp) + + csrw mscratch, sp + la sp, g_top_trapstack + addi sp, sp, -52 + sw t0, 4(sp) + sw t1, 8(sp) + sw t2, 12(sp) + csrr t0, mepc + csrr t1, mcause + csrr t2, mstatus + sw t1, 40(sp) + sw t0, 44(sp) + sw t2, 48(sp) + + sw ra, 0(sp) + sw a0, 16(sp) + sw a1, 20(sp) + sw a2, 24(sp) + sw a3, 28(sp) + sw a4, 32(sp) + sw a5, 36(sp) + + la t0, handle_nmi_exception + jalr t0 + + lw a1, 40(sp) + andi a0, a1, 0x3FF + slli a0, a0, 2 + + /* clear pending */ + li a2, 0xE0801000 + add a2, a2, a0 + lb a3, 0(a2) + li a4, 1 + not a4, a4 + and a5, a4, a3 + sb a5, 0(a2) + + csrw mcause, a1 + + lw t0, 44(sp) + lw t1, 48(sp) + csrw mepc, t0 + csrw mstatus, t1 + lw ra, 0(sp) + lw t0, 4(sp) + lw t1, 8(sp) + lw t2, 12(sp) + lw a0, 16(sp) + lw a1, 20(sp) + lw a2, 24(sp) + lw a3, 28(sp) + lw a4, 32(sp) + lw a5, 36(sp) + + addi sp, sp, 52 + csrr sp, mscratch + + /* restore mscratch */ + lw t0, 0x0(sp) + csrw mscratch, t0 + addi sp, sp, 4 + + lw t0, 0x0(sp) + lw t1, 0x4(sp) + addi sp, sp, 8 + + mret + + .size Default_Handler, . - Default_Handler + +/* Macro to define default handlers. Default handler + * will be weak symbol and just dead loops. They can be + * overwritten by other handlers */ + .macro def_irq_handler handler_name + .weak \handler_name + .set \handler_name, Default_Handler + .endm + + def_irq_handler tspend_handler diff --git a/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/sys/SConscript b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/sys/SConscript index 49d56d78e3d..6e0a767655c 100644 --- a/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/sys/SConscript +++ b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/sys/SConscript @@ -9,6 +9,7 @@ src += ['sys_clk.c'] src += ['tick.c'] src += ['target_get.c'] src += ['devices.c'] +src += ['feature.c'] group = DefineGroup('sys', src, depend = [''], CPPPATH = CPPPATH) diff --git a/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/sys/feature.c b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/sys/feature.c new file mode 100644 index 00000000000..bb505316466 --- /dev/null +++ b/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/sys/feature.c @@ -0,0 +1,319 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + +/* I/D Cache will enable in cache_init */ +void cpu_features_init(void) +{ +#if CONFIG_CPU_XUANTIE_E901PLUS_CP || CONFIG_CPU_XUANTIE_E901PLUS_B_CP || CONFIG_CPU_XUANTIE_E901PLUS_M_CP || CONFIG_CPU_XUANTIE_E901PLUS_BM_CP + return; +#endif + +#if CONFIG_CPU_XUANTIE_E901_CP || CONFIG_CPU_XUANTIE_E901_B_CP || CONFIG_CPU_XUANTIE_E901_ZM_CP || CONFIG_CPU_XUANTIE_E901_BZM_CP + return; +#endif + +#if CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT + return; +#endif + +#if CONFIG_CPU_XUANTIE_E906 || CONFIG_CPU_XUANTIE_E906F || CONFIG_CPU_XUANTIE_E906FD || CONFIG_CPU_XUANTIE_E906P || CONFIG_CPU_XUANTIE_E906FP || CONFIG_CPU_XUANTIE_E906FDP + rv_csr_write(CSR_MXSTATUS, 0x440800); + rv_csr_write(CSR_MHCR, 0x103f & (~0x3)); + return; +#endif + +#if CONFIG_CPU_XUANTIE_E907 || CONFIG_CPU_XUANTIE_E907F || CONFIG_CPU_XUANTIE_E907FD || CONFIG_CPU_XUANTIE_E907P || CONFIG_CPU_XUANTIE_E907FP || CONFIG_CPU_XUANTIE_E907FDP + rv_csr_write(CSR_MXSTATUS, 0x440800); + rv_csr_write(CSR_MHINT, 0x600c); + rv_csr_write(CSR_MHCR, 0x103f & (~0x3)); + return; +#endif + + volatile unsigned int i, cpu_type, cpu_ver, cpu_tnmodel; + unsigned long version[8]; + + /* As CPUID is a fifo register, try to find + * the CPUID[0] whose index(bit[31:28]) == 0 */ + for (i = 0; i < 8; i++) + { + version[0] = rv_csr_read(CSR_MCPUID); + if (((version[0]&0xf0000000) >> 28) == 0) + break; + } + + for (i = 1; i < 8; i++) + version[i] = rv_csr_read(CSR_MCPUID); + + cpu_type = (version[0] >> 18) & 0xf; + cpu_tnmodel = (version[0] >> 14) & 0x1; + cpu_ver = (version[1] >> 12) & 0xffff; + + rv_csr_write(CSR_MCOR, 0x70013); + + /* + * Warning: CSR_MCCR2 contains an L2 cache latency setting, + * you need to confirm it by your own soc design. + */ + switch (cpu_type) + { + case 0x1: + if (cpu_ver >= 0x0) + { + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe249000b); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0x1ee30c); + rv_csr_write(CSR_MHCR, 0x11ff & (~0x3)); + rv_csr_write(CSR_MHINT2,0x180); + } else { + while(1); + } + break; + case 0x2: + if (cpu_ver >= 0x0) + { + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xa042000a); + rv_csr_write(CSR_MXSTATUS, 0x438100); + rv_csr_write(CSR_MHINT, 0x21aa10c); + rv_csr_write(CSR_MHCR, 0x10011ff & (~0x3)); + rv_csr_write(CSR_MHINT4, 0x10000080); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else { + while(1); + } + break; + case 0x3: + if (cpu_ver >= 0x1080 && cpu_ver <= 0x10bf) + { /* 1.2.0~1.2.x */ + rv_csr_write(CSR_MCCR2, 0xe0010009); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0x6e30c); + rv_csr_write(CSR_MHCR, 0x1ff & (~0x3)); + } else if (cpu_ver == 0x10ca) + { /* 1.3.10 */ + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe2490009); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0x66e30c); + rv_csr_write(CSR_MHCR, 0x17f & (~0x3)); + rv_csr_write(CSR_MHINT2, 0x420000); + rv_csr_write(CSR_MHINT4, 0x410); + } else if (cpu_ver >= 0x1100 && cpu_ver <= 0x113f) + { /* 1.4.0~1.4.x */ + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe2490009); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0x16e30c); + rv_csr_write(CSR_MHCR, 0x1ff & (~0x3)); + } else if (cpu_ver >= 0x1140 && cpu_ver <= 0x117f) + { /* 1.5.0~1.5.x */ + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe2490009); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0xe6e30c); + rv_csr_write(CSR_MHINT2, 0x180); + rv_csr_write(CSR_MHCR, 0x1ff & (~0x3)); + } else if (cpu_ver >= 0x1180 && cpu_ver <= 0x1183) + { /* 1.6.0~1.6.3 */ + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe249000b); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0x1ee30c); + rv_csr_write(CSR_MHINT2, 0x180); + rv_csr_write(CSR_MHCR, 0x1ff & (~0x3)); + } else if (cpu_ver >= 0x1184 && cpu_ver <= 0x123f) + { /* 1.6.4~1.8.x */ + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe249000b); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0x1ee30c); + rv_csr_write(CSR_MHINT2, 0x180); + rv_csr_write(CSR_MHCR, 0x11ff & (~0x3)); + } else if (cpu_ver >= 0x2000 && cpu_ver <= 0x200e) + { /* 2.0.0~2.0.14 */ + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe249000b); + rv_csr_write(CSR_MXSTATUS, 0x438000); + rv_csr_write(CSR_MHINT, 0x31ea32c); + rv_csr_write(CSR_MHINT2, 0x180); + rv_csr_write(CSR_MHCR, 0x11ff & (~0x3)); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else if (cpu_ver >= 0x200f && cpu_ver <= 0x2045) + { /* 2.0.15~2.1.5 */ + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe249000b); + rv_csr_write(CSR_MXSTATUS, 0x438000); + rv_csr_write(CSR_MHINT, 0x11ea32c); + rv_csr_write(CSR_MHINT2, 0x180); + rv_csr_write(CSR_MHCR, 0x11ff & (~0x3)); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else if (cpu_ver >= 0x2046 && cpu_ver <= 0x20c3) + { /* 2.1.6~2.3.3 */ + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe249000b); + rv_csr_write(CSR_MXSTATUS, 0x438000); + rv_csr_write(CSR_MHINT, 0x31ea32c); + rv_csr_write(CSR_MHINT2, 0x180); + rv_csr_write(CSR_MHCR, 0x11ff & (~0x3)); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else if (cpu_ver >= 0x20c4 && cpu_ver <= 0x2fff) + { /* 2.3.4~2.x.x */ + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe249000b); + rv_csr_write(CSR_MXSTATUS, 0x438100); + rv_csr_write(CSR_MHINT, 0x31ea32c); + rv_csr_write(CSR_MHINT2, 0x180); + rv_csr_write(CSR_MHCR, 0x11ff & (~0x3)); + rv_csr_write(CSR_MHINT4, 0x2080); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else if (cpu_ver >= 0x3000 && cpu_ver <= 0x3fff) + { /* 3.0.0~3.x.x */ + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe249000b); + rv_csr_write(CSR_MXSTATUS, 0x438100); + rv_csr_write(CSR_MHINT, 0x31ea32c); + rv_csr_write(CSR_MHINT2, 0x180); + rv_csr_write(CSR_MHCR, 0x11ff & (~0x3)); + rv_csr_write(CSR_MHINT4, 0x2080); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else { + while(1); + } + break; + case 0x4: + if (cpu_ver >= 0x1002 && cpu_ver <= 0xffff) + { + rv_csr_write(CSR_MHCR, 0x17f & (~0x3)); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0x650c); + } else { + while(1); + } + break; + case 0x5: + if(cpu_tnmodel == 0) + { /* c908 */ + if (cpu_ver >= 0x0000 && cpu_ver <= 0x0007) + { /* 0.0.0~0.0.7 */ + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe0420008); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0x2c50c); + rv_csr_write(CSR_MHCR, 0x11ff & (~0x3)); + } else if (cpu_ver >= 0x0040 && cpu_ver <= 0x1002) + { /* 0.1.0~1.0.2 */ + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xa042000a); + rv_csr_write(CSR_MXSTATUS, 0x438000); + rv_csr_write(CSR_MHINT, 0x21aa10c); + rv_csr_write(CSR_MHCR, 0x10011ff & (~0x3)); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else if (cpu_ver >= 0x1003 && cpu_ver <= 0x100b) + { /* 1.0.3~1.0.11 */ + + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xa042000a); + rv_csr_write(CSR_MXSTATUS, 0x438000); + rv_csr_write(CSR_MHINT, 0x1aa10c); + rv_csr_write(CSR_MHCR, 0x10011ff & (~0x3)); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else if (cpu_ver >= 0x100c && cpu_ver <= 0x1fff) + { /* 1.0.12~ */ + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xa042000a); + rv_csr_write(CSR_MXSTATUS, 0x438100); + rv_csr_write(CSR_MHINT, 0x21aa10c); + rv_csr_write(CSR_MHCR, 0x10011ff & (~0x3)); + rv_csr_write(CSR_MHINT4, 0x10000080); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else if (cpu_ver >= 0x2000 && cpu_ver <= 0xffff) + { /* 2.0.0~ */ + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xa042000a); + rv_csr_write(CSR_MXSTATUS, 0x438100); + rv_csr_write(CSR_MHINT, 0x21aa10c); + rv_csr_write(CSR_MHCR, 0x10011ff & (~0x3)); + rv_csr_write(CSR_MHINT4, 0x10000080); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else { + while(1); + } + } else if (cpu_tnmodel == 1) + { + if (cpu_ver >= 0x0) + { + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xA0420002); + rv_csr_write(CSR_MXSTATUS, 0x438100); + rv_csr_write(CSR_MHINT, 0x21AA10C); + rv_csr_write(CSR_MHCR, 0x10011FF & (~0x3)); + rv_csr_write(CSR_MHINT4, 0x10000080); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else { + while(1); + } + } else { + while(1); + } + break; + case 0x6: + if (cpu_ver >= 0x0) + { + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xA0420002); + rv_csr_write(CSR_MXSTATUS, 0x438000); + rv_csr_write(CSR_MHINT, 0x3A1AA10C); + rv_csr_write(CSR_MHCR, 0x10011BF & (~0x3)); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else { + while(1); + } + break; + default: + /* FIXME: maybe qemu */ + break; + } +} + diff --git a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/core_rv32.h b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/core_rv32.h index 17920e1dd74..aa353cb4a40 100644 --- a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/core_rv32.h +++ b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/core_rv32.h @@ -295,7 +295,13 @@ typedef struct { #define CACHE_MHCR_IE_Pos 0U /*!< CACHE MHCR: IE Position */ #define CACHE_MHCR_IE_Msk (0x1UL << CACHE_MHCR_IE_Pos) /*!< CACHE MHCR: IE Mask */ +#if CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT \ + || CONFIG_CPU_XUANTIE_E901PLUS_CP || CONFIG_CPU_XUANTIE_E901PLUS_B_CP || CONFIG_CPU_XUANTIE_E901PLUS_M_CP || CONFIG_CPU_XUANTIE_E901PLUS_BM_CP \ + || CONFIG_CPU_XUANTIE_E901_CP || CONFIG_CPU_XUANTIE_E901_B_CP || CONFIG_CPU_XUANTIE_E901_ZM_CP || CONFIG_CPU_XUANTIE_E901_BZM_CP +#define CACHE_INV_ADDR_Pos 4U +#else #define CACHE_INV_ADDR_Pos 5U +#endif #define CACHE_INV_ADDR_Msk (0xFFFFFFFFUL << CACHE_INV_ADDR_Pos) /*@} end of group CSI_CACHE */ @@ -433,8 +439,12 @@ typedef struct { */ /* Memory mapping of THEAD CPU */ -#define CORET_BASE (0xE0004000UL) /*!< CORET Base Address */ -#define CLIC_BASE (0xE0800000UL) /*!< CLIC Base Address */ +#ifndef CONFIG_TCIP_BASE +#define CONFIG_TCIP_BASE 0xE0000000UL +#endif +#define CORET_BASE (CONFIG_TCIP_BASE + 0x4000UL) /*!< CORET Base Address */ +#define CLIC_BASE (CONFIG_TCIP_BASE + 0x800000UL) /*!< CLIC Base Address */ + #define SYSMAP_BASE (0xEFFFF000UL) /*!< SYSMAP Base Address */ #define CORET ((CORET_Type *) CORET_BASE ) /*!< SysTick configuration struct */ @@ -471,11 +481,12 @@ __STATIC_INLINE int csi_get_cpu_id(void) */ __STATIC_INLINE int csi_get_cache_line_size(void) { -#if CONFIG_CPU_XUANTIE_E906 || CONFIG_CPU_XUANTIE_E906F || CONFIG_CPU_XUANTIE_E906FD || CONFIG_CPU_XUANTIE_E906P || CONFIG_CPU_XUANTIE_E906FP || CONFIG_CPU_XUANTIE_E906FDP \ - || CONFIG_CPU_XUANTIE_E907 || CONFIG_CPU_XUANTIE_E907F || CONFIG_CPU_XUANTIE_E907FD || CONFIG_CPU_XUANTIE_E907P || CONFIG_CPU_XUANTIE_E907FP || CONFIG_CPU_XUANTIE_E907FDP - return 8; +#if CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT \ + || CONFIG_CPU_XUANTIE_E901PLUS_CP || CONFIG_CPU_XUANTIE_E901PLUS_B_CP || CONFIG_CPU_XUANTIE_E901PLUS_M_CP || CONFIG_CPU_XUANTIE_E901PLUS_BM_CP \ + || CONFIG_CPU_XUANTIE_E901_CP || CONFIG_CPU_XUANTIE_E901_B_CP || CONFIG_CPU_XUANTIE_E901_ZM_CP || CONFIG_CPU_XUANTIE_E901_BZM_CP + return 16; #else - return 4; + return 32; #endif } @@ -546,6 +557,7 @@ __STATIC_INLINE uint32_t csi_vic_get_pending_irq(int32_t IRQn) __STATIC_INLINE void csi_vic_set_pending_irq(int32_t IRQn) { CLIC->CLICINT[IRQn].IP |= CLIC_INTIP_IP_Msk; + __DSB(); } /** @@ -556,6 +568,7 @@ __STATIC_INLINE void csi_vic_set_pending_irq(int32_t IRQn) __STATIC_INLINE void csi_vic_clear_pending_irq(int32_t IRQn) { CLIC->CLICINT[IRQn].IP &= ~CLIC_INTIP_IP_Msk; + __DSB(); } /** @@ -568,7 +581,10 @@ __STATIC_INLINE void csi_vic_clear_pending_irq(int32_t IRQn) __STATIC_INLINE void csi_vic_set_prio(int32_t IRQn, uint32_t priority) { uint8_t nlbits = (CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos; - CLIC->CLICINT[IRQn].CTL = (CLIC->CLICINT[IRQn].CTL & (~CLIC_INTCFG_PRIO_Msk)) | (priority << (8 - nlbits)); + uint8_t ctl = CLIC->CLICINT[IRQn].CTL; + ctl <<= nlbits; + ctl >>= nlbits; + CLIC->CLICINT[IRQn].CTL = ctl | (priority << (8 - nlbits)); __DSB(); } @@ -614,6 +630,7 @@ __STATIC_INLINE uint32_t csi_vic_set_thresh(uint32_t thresh) CLIC->MINTTHRESH = 0xff << 24; CLIC->MINTTHRESH = thresh << 24; + __DSB(); return temp; } @@ -642,18 +659,22 @@ __STATIC_INLINE void csi_mpu_config_region(uint32_t idx, uint32_t base_addr, reg uint8_t pmpxcfg = 0; uint32_t addr = 0; - if (idx > 15) { + if (idx > 15) + { return; } - if (!enable) { + if (!enable) + { attr.a = (address_matching_e)0; } - if (attr.a == ADDRESS_MATCHING_TOR) { + if (attr.a == ADDRESS_MATCHING_TOR) + { addr = base_addr >> 2; } else { - if (size == REGION_SIZE_4B) { + if (size == REGION_SIZE_4B) + { addr = base_addr >> 2; attr.a = (address_matching_e)2; } else { @@ -693,7 +714,8 @@ __STATIC_INLINE void csi_mpu_disable_region(uint32_t idx) __STATIC_INLINE uint32_t _csi_coret_config(unsigned long coret_base, uint32_t ticks, int32_t IRQn) { CORET_Type *coret = (CORET_Type *)coret_base; - if ((coret->MTIMECMP != 0) && (coret->MTIMECMP != 0xffffffffffffffff)) { + if ((coret->MTIMECMP != 0) && (coret->MTIMECMP != 0xFFFFFFFFFFFFFFFFULL)) + { coret->MTIMECMP = coret->MTIMECMP + ticks; } else { coret->MTIMECMP = coret->MTIME + ticks; @@ -814,7 +836,8 @@ __ALWAYS_STATIC_INLINE void csi_coret_irq_disable(void) */ __STATIC_INLINE uint8_t __get_SYSMAPCFGx(uint32_t idx) { - switch (idx) { + switch (idx) + { case 0: return SYSMAP->SYSMAPCFG0; case 1: @@ -844,7 +867,8 @@ __STATIC_INLINE uint8_t __get_SYSMAPCFGx(uint32_t idx) */ __STATIC_INLINE void __set_SYSMAPCFGx(uint32_t idx, uint32_t sysmapxcfg) { - switch (idx) { + switch (idx) + { case 0: SYSMAP->SYSMAPCFG0 = sysmapxcfg; break; @@ -882,7 +906,8 @@ __STATIC_INLINE void __set_SYSMAPCFGx(uint32_t idx, uint32_t sysmapxcfg) */ __STATIC_INLINE uint32_t __get_SYSMAPADDRx(uint32_t idx) { - switch(idx) { + switch(idx) + { case 0: return SYSMAP->SYSMAPADDR0; case 1: @@ -912,7 +937,8 @@ __STATIC_INLINE uint32_t __get_SYSMAPADDRx(uint32_t idx) */ __STATIC_INLINE void __set_SYSMAPADDRx(uint32_t idx, uint32_t sysmapxaddr) { - switch (idx) { + switch (idx) + { case 0: SYSMAP->SYSMAPADDR0 = sysmapxaddr; break; @@ -953,7 +979,8 @@ __STATIC_INLINE void csi_sysmap_config_region(uint32_t idx, uint32_t base_addr, { uint32_t addr = 0; - if (idx > 7) { + if (idx > 7) + { return; } @@ -990,16 +1017,15 @@ __STATIC_INLINE int csi_icache_is_enable() __STATIC_INLINE void csi_icache_enable (void) { #if (__ICACHE_PRESENT == 1U) - if (!csi_icache_is_enable()) { + if (!csi_icache_is_enable()) + { uint32_t cache; __DSB(); - __ISB(); __ICACHE_IALL(); cache = __get_MHCR(); cache |= CACHE_MHCR_IE_Msk; __set_MHCR(cache); __DSB(); - __ISB(); } #endif } @@ -1012,16 +1038,15 @@ __STATIC_INLINE void csi_icache_enable (void) __STATIC_INLINE void csi_icache_disable (void) { #if (__ICACHE_PRESENT == 1U) - if (csi_icache_is_enable()) { + if (csi_icache_is_enable()) + { uint32_t cache; __DSB(); - __ISB(); cache = __get_MHCR(); cache &= ~CACHE_MHCR_IE_Msk; /* disable icache */ __set_MHCR(cache); __ICACHE_IALL(); /* invalidate all icache */ __DSB(); - __ISB(); } #endif } @@ -1035,10 +1060,8 @@ __STATIC_INLINE void csi_icache_invalid (void) { #if (__ICACHE_PRESENT == 1U) __DSB(); - __ISB(); __ICACHE_IALL(); /* invalidate all icache */ __DSB(); - __ISB(); #endif } @@ -1058,17 +1081,16 @@ __STATIC_INLINE int csi_dcache_is_enable() __STATIC_INLINE void csi_dcache_enable (void) { #if (__DCACHE_PRESENT == 1U) - if (!csi_dcache_is_enable()) { + if (!csi_dcache_is_enable()) + { uint32_t cache; __DSB(); - __ISB(); __DCACHE_IALL(); /* invalidate all dcache */ cache = __get_MHCR(); cache |= CACHE_MHCR_DE_Msk; /* enable dcache */ __set_MHCR(cache); __DSB(); - __ISB(); } #endif } @@ -1081,16 +1103,15 @@ __STATIC_INLINE void csi_dcache_enable (void) __STATIC_INLINE void csi_dcache_disable (void) { #if (__DCACHE_PRESENT == 1U) - if (csi_dcache_is_enable()) { + if (csi_dcache_is_enable()) + { uint32_t cache; __DSB(); - __ISB(); cache = __get_MHCR(); cache &= ~(uint32_t)CACHE_MHCR_DE_Msk; /* disable all Cache */ __set_MHCR(cache); __DCACHE_IALL(); /* invalidate all Cache */ __DSB(); - __ISB(); } #endif } @@ -1104,10 +1125,8 @@ __STATIC_INLINE void csi_dcache_invalid (void) { #if (__DCACHE_PRESENT == 1U) __DSB(); - __ISB(); __DCACHE_IALL(); /* invalidate all Cache */ __DSB(); - __ISB(); #endif } @@ -1120,10 +1139,8 @@ __STATIC_INLINE void csi_dcache_clean (void) { #if (__DCACHE_PRESENT == 1U) __DSB(); - __ISB(); __DCACHE_CALL(); /* clean all Cache */ __DSB(); - __ISB(); #endif } @@ -1136,10 +1153,8 @@ __STATIC_INLINE void csi_dcache_clean_invalid (void) { #if (__DCACHE_PRESENT == 1U) __DSB(); - __ISB(); __DCACHE_CIALL(); /* clean and inv all Cache */ __DSB(); - __ISB(); #endif } @@ -1155,11 +1170,12 @@ __STATIC_INLINE void csi_dcache_invalid_range (unsigned long *addr, size_t dsize #if (__DCACHE_PRESENT == 1U) int linesize = csi_get_cache_line_size(); long op_size = dsize + (unsigned long)addr % linesize; - unsigned long op_addr = (unsigned long)addr; + unsigned long op_addr = (unsigned long)addr & CACHE_INV_ADDR_Msk; __DSB(); - while (op_size > 0) { + while (op_size > 0) + { __DCACHE_IPA(op_addr); op_addr += linesize; op_size -= linesize; @@ -1186,7 +1202,8 @@ __STATIC_INLINE void csi_dcache_clean_range (unsigned long *addr, size_t dsize) __DSB(); - while (op_size > 0) { + while (op_size > 0) + { __DCACHE_CPA(op_addr); op_addr += linesize; op_size -= linesize; @@ -1209,11 +1226,12 @@ __STATIC_INLINE void csi_dcache_clean_invalid_range (unsigned long *addr, size_t #if (__DCACHE_PRESENT == 1U) int linesize = csi_get_cache_line_size(); long op_size = dsize + (unsigned long)addr % linesize; - unsigned long op_addr = (unsigned long) addr; + unsigned long op_addr = (unsigned long) addr & CACHE_INV_ADDR_Msk; __DSB(); - while (op_size > 0) { + while (op_size > 0) + { __DCACHE_CIPA(op_addr); op_addr += linesize; op_size -= linesize; @@ -1449,3 +1467,4 @@ __STATIC_INLINE void csi_irq_restore(uint32_t irq_state) #endif /* __CORE_RV32_H_DEPENDANT */ #endif /* __CSI_GENERIC */ + diff --git a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/core_rv64.h b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/core_rv64.h index 109a397b3db..f2a6d1ac691 100644 --- a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/core_rv64.h +++ b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/core_rv64.h @@ -219,7 +219,7 @@ typedef struct { */ typedef struct { - uint32_t RESERVED0; /*!< Offset: 0x000 (R/W) CLINT configure register */ + uint32_t RESERVED0; __IOM uint32_t PLIC_PRIO[1023]; __IOM uint32_t PLIC_IP[32]; uint32_t RESERVED1[3972 / 4 - 1]; @@ -403,7 +403,9 @@ typedef struct { #define CACHE_MHCR_IE_Msk (0x1UL << CACHE_MHCR_IE_Pos) /*!< CACHE MHCR: IE Mask */ #if CONFIG_CPU_XUANTIE_R908 || CONFIG_CPU_XUANTIE_R908FD || CONFIG_CPU_XUANTIE_R908FDV \ - || CONFIG_CPU_XUANTIE_R908_CP || CONFIG_CPU_XUANTIE_R908FD_CP || CONFIG_CPU_XUANTIE_R908FDV_CP + || CONFIG_CPU_XUANTIE_R908_CP || CONFIG_CPU_XUANTIE_R908FD_CP || CONFIG_CPU_XUANTIE_R908FDV_CP \ + || CONFIG_CPU_XUANTIE_R908_CP_XT || CONFIG_CPU_XUANTIE_R908FD_CP_XT || CONFIG_CPU_XUANTIE_R908FDV_CP_XT \ + || CONFIG_CPU_XUANTIE_C908X || CONFIG_CPU_XUANTIE_C908X_CP || CONFIG_CPU_XUANTIE_C908X_CP_XT #define MCER_ECC_FATAL_Pos 34U #define MCER_ECC_FATAL_Msk (0x1ULL << MCER_ECC_FATAL_Pos) @@ -440,7 +442,7 @@ typedef struct { #define CACHE_MCER2H_RAMID_Msk (0x3ULL << CACHE_MCER2H_RAMID_Pos) #define CACHE_INV_ADDR_Pos 6U -#define CACHE_INV_ADDR_Msk (0xFFFFFFFFULL << CACHE_INV_ADDR_Pos) +#define CACHE_INV_ADDR_Msk (~((0x1ULL << CACHE_INV_ADDR_Pos) - 1)) enum MCER_FAULT_RAMID { /* L1 Cache, JTLB and TCM (RAMID of MCER)*/ @@ -462,19 +464,19 @@ enum MCER2_FAULT_RAMID { /*@} end of group CSI_CACHE */ -// MSTATUS Register -#define MSTATUS_TVM_MASK (1L << 20) // mstatus.TVM [20] -#define MSTATUS_MPP_MASK (3L << 11) // mstatus.SPP [11:12] +/* MSTATUS Register */ +#define MSTATUS_TVM_MASK (1L << 20) /* mstatus.TVM [20] */ +#define MSTATUS_MPP_MASK (3L << 11) /* mstatus.SPP [11:12] */ #ifndef MSTATUS_MPP_M -#define MSTATUS_MPP_M (3L << 11) // Machine mode 11 +#define MSTATUS_MPP_M (3L << 11) /* Machine mode 11 */ #endif -#define MSTATUS_MPP_S (1L << 11) // Supervisor mode 01 -#define MSTATUS_MPP_U (0L << 11) // User mode 00 +#define MSTATUS_MPP_S (1L << 11) /* Supervisor mode 01 */ +#define MSTATUS_MPP_U (0L << 11) /* User mode 00 */ -// SSTATUS Register -#define SSTATUS_SPP_MASK (3L << 8) // sstatus.SPP [8:9] -#define SSTATUS_SPP_S (1L << 8) // Supervisor mode 01 -#define SSTATUS_SPP_U (0L << 8) // User mode 00 +/* SSTATUS Register */ +#define SSTATUS_SPP_MASK (3L << 8) /* sstatus.SPP [8:9] */ +#define SSTATUS_SPP_S (1L << 8) /* Supervisor mode 01 */ +#define SSTATUS_SPP_U (0L << 8) /* User mode 00 */ typedef enum { USER_MODE = 0, @@ -675,7 +677,8 @@ __STATIC_INLINE void csi_vic_enable_irq(int32_t IRQn) PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE; #if CONFIG_INTC_CLIC_PLIC - if (IRQn > PLIC_IRQ_OFFSET) { + if (IRQn > PLIC_IRQ_OFFSET) + { IRQn -= PLIC_IRQ_OFFSET; } else { CLIC->CLICINT[IRQn].IE |= CLIC_INTIE_IE_Msk; @@ -719,7 +722,8 @@ __STATIC_INLINE void csi_vic_disable_irq(int32_t IRQn) PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE; #if CONFIG_INTC_CLIC_PLIC - if (IRQn > PLIC_IRQ_OFFSET) { + if (IRQn > PLIC_IRQ_OFFSET) + { IRQn -= PLIC_IRQ_OFFSET; } else { CLIC->CLICINT[IRQn].IE &= ~CLIC_INTIE_IE_Msk; @@ -765,7 +769,8 @@ __STATIC_INLINE uint32_t csi_vic_get_enabled_irq(int32_t IRQn) PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE; #if CONFIG_INTC_CLIC_PLIC - if (IRQn > PLIC_IRQ_OFFSET) { + if (IRQn > PLIC_IRQ_OFFSET) + { IRQn -= PLIC_IRQ_OFFSET; } else { return (uint32_t)(CLIC->CLICINT[IRQn].IE & CLIC_INTIE_IE_Msk); @@ -808,7 +813,8 @@ __STATIC_INLINE uint32_t csi_vic_get_pending_irq(int32_t IRQn) { PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE; #if CONFIG_INTC_CLIC_PLIC - if (IRQn > PLIC_IRQ_OFFSET) { + if (IRQn > PLIC_IRQ_OFFSET) + { IRQn -= PLIC_IRQ_OFFSET; } else { return (uint32_t)(CLIC->CLICINT[IRQn].IP & CLIC_INTIP_IP_Msk); @@ -826,14 +832,17 @@ __STATIC_INLINE void csi_vic_set_pending_irq(int32_t IRQn) { PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE; #if CONFIG_INTC_CLIC_PLIC - if (IRQn > PLIC_IRQ_OFFSET) { + if (IRQn > PLIC_IRQ_OFFSET) + { IRQn -= PLIC_IRQ_OFFSET; } else { CLIC->CLICINT[IRQn].IP |= CLIC_INTIP_IP_Msk; + __DSB(); return; } #endif plic->PLIC_IP[IRQn/32] = plic->PLIC_IP[IRQn/32] | (0x1 << (IRQn%32)); + __DSB(); } /** @@ -845,14 +854,17 @@ __STATIC_INLINE void csi_vic_clear_pending_irq(int32_t IRQn) { PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE; #if CONFIG_INTC_CLIC_PLIC - if (IRQn > PLIC_IRQ_OFFSET) { + if (IRQn > PLIC_IRQ_OFFSET) + { IRQn -= PLIC_IRQ_OFFSET; } else { CLIC->CLICINT[IRQn].IP &= ~CLIC_INTIP_IP_Msk; + __DSB(); return; } #endif plic->PLIC_H0_SCLAIM = IRQn; + __DSB(); } /** @@ -901,16 +913,21 @@ __STATIC_INLINE void csi_vic_set_prio(int32_t IRQn, uint32_t priority) { PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE; #if CONFIG_INTC_CLIC_PLIC - if (IRQn > PLIC_IRQ_OFFSET) { + if (IRQn > PLIC_IRQ_OFFSET) + { IRQn -= PLIC_IRQ_OFFSET; } else { uint8_t nlbits = (CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos; - CLIC->CLICINT[IRQn].CTL = (CLIC->CLICINT[IRQn].CTL & (~CLIC_INTCFG_PRIO_Msk)) | (priority << (8 - nlbits)); + uint8_t ctl = CLIC->CLICINT[IRQn].CTL; + ctl <<= nlbits; + ctl >>= nlbits; + CLIC->CLICINT[IRQn].CTL = ctl | (priority << (8 - nlbits)); __DSB(); return; } #endif plic->PLIC_PRIO[IRQn - 1] = priority; + __DSB(); } /** @@ -926,7 +943,8 @@ __STATIC_INLINE uint32_t csi_vic_get_prio(int32_t IRQn) { PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE; #if CONFIG_INTC_CLIC_PLIC - if (IRQn > PLIC_IRQ_OFFSET) { + if (IRQn > PLIC_IRQ_OFFSET) + { IRQn -= PLIC_IRQ_OFFSET; } else { uint8_t nlbits = (CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos; @@ -991,18 +1009,22 @@ __STATIC_INLINE void csi_mpu_config_region(uint32_t idx, uint32_t base_addr, reg uint8_t pmpxcfg = 0; uint32_t addr = 0; - if (idx > 15) { + if (idx > 15) + { return; } - if (!enable) { + if (!enable) + { attr.a = (address_matching_e)0; } - if (attr.a == ADDRESS_MATCHING_TOR) { + if (attr.a == ADDRESS_MATCHING_TOR) + { addr = base_addr >> 2; } else { - if (size == REGION_SIZE_4B) { + if (size == REGION_SIZE_4B) + { addr = base_addr >> 2; attr.a = (address_matching_e)2; } else { @@ -1049,7 +1071,8 @@ __STATIC_INLINE uint32_t _csi_clint_config2(unsigned long coret_base, uint16_t h uint64_t value = (((uint64_t)(CLINT_TIMECMPn_VAL(&clint->STIMECMPH0, hartid))) << 32) + \ (uint64_t)(CLINT_TIMECMPn_VAL(&clint->STIMECMPL0, hartid)); - if ((value != 0) && (value != 0xffffffffffffffff)) { + if ((value != 0) && (value != 0xffffffffffffffff)) + { value = value + (uint64_t)ticks; } else { value = __get_MTIME() + ticks; @@ -1060,7 +1083,8 @@ __STATIC_INLINE uint32_t _csi_clint_config2(unsigned long coret_base, uint16_t h uint64_t value = (((uint64_t)(CLINT_TIMECMPn_VAL(&clint->MTIMECMPH0, hartid))) << 32) + \ (uint64_t)(CLINT_TIMECMPn_VAL(&clint->MTIMECMPL0, hartid)); - if ((value != 0) && (value != 0xffffffffffffffff)) { + if ((value != 0) && (value != 0xffffffffffffffff)) + { value = value + (uint64_t)ticks; } else { value = __get_MTIME() + ticks; @@ -1274,16 +1298,15 @@ __STATIC_INLINE int csi_icache_is_enable() __STATIC_INLINE void csi_icache_enable(void) { #if (__ICACHE_PRESENT == 1U) - if (!csi_icache_is_enable()) { + if (!csi_icache_is_enable()) + { uint32_t cache; __DSB(); - __ISB(); __ICACHE_IALL(); cache = __get_MHCR(); cache |= CACHE_MHCR_IE_Msk; __set_MHCR(cache); __DSB(); - __ISB(); } #endif } @@ -1296,16 +1319,15 @@ __STATIC_INLINE void csi_icache_enable(void) __STATIC_INLINE void csi_icache_disable(void) { #if (__ICACHE_PRESENT == 1U) - if (csi_icache_is_enable()) { + if (csi_icache_is_enable()) + { uint32_t cache; __DSB(); - __ISB(); cache = __get_MHCR(); cache &= ~CACHE_MHCR_IE_Msk; /* disable icache */ __set_MHCR(cache); __ICACHE_IALL(); /* invalidate all icache */ __DSB(); - __ISB(); } #endif } @@ -1319,10 +1341,8 @@ __STATIC_INLINE void csi_icache_invalid(void) { #if (__ICACHE_PRESENT == 1U) __DSB(); - __ISB(); __ICACHE_IALL(); /* invalidate all icache */ __DSB(); - __ISB(); #endif } @@ -1342,17 +1362,16 @@ __STATIC_INLINE int csi_dcache_is_enable() __STATIC_INLINE void csi_dcache_enable(void) { #if (__DCACHE_PRESENT == 1U) - if (!csi_dcache_is_enable()) { + if (!csi_dcache_is_enable()) + { uint32_t cache; __DSB(); - __ISB(); __DCACHE_IALL(); /* invalidate all dcache */ cache = __get_MHCR(); cache |= CACHE_MHCR_DE_Msk; /* enable dcache */ __set_MHCR(cache); __DSB(); - __ISB(); } #endif } @@ -1365,16 +1384,15 @@ __STATIC_INLINE void csi_dcache_enable(void) __STATIC_INLINE void csi_dcache_disable(void) { #if (__DCACHE_PRESENT == 1U) - if (csi_dcache_is_enable()) { + if (csi_dcache_is_enable()) + { uint32_t cache; __DSB(); - __ISB(); cache = __get_MHCR(); cache &= ~(uint32_t)CACHE_MHCR_DE_Msk; /* disable all Cache */ __set_MHCR(cache); __DCACHE_IALL(); /* invalidate all Cache */ __DSB(); - __ISB(); } #endif } @@ -1387,10 +1405,8 @@ __STATIC_INLINE void csi_dcache_invalid(void) { #if (__DCACHE_PRESENT == 1U) __DSB(); - __ISB(); __DCACHE_IALL(); /* invalidate all Cache */ __DSB(); - __ISB(); #endif } @@ -1403,10 +1419,8 @@ __STATIC_INLINE void csi_dcache_clean(void) { #if (__DCACHE_PRESENT == 1U) __DSB(); - __ISB(); __DCACHE_CALL(); /* clean all Cache */ __DSB(); - __ISB(); #endif } @@ -1419,10 +1433,8 @@ __STATIC_INLINE void csi_dcache_clean_invalid(void) { #if (__DCACHE_PRESENT == 1U) __DSB(); - __ISB(); __DCACHE_CIALL(); /* clean and inv all Cache */ __DSB(); - __ISB(); #endif } @@ -1437,11 +1449,12 @@ __STATIC_INLINE void csi_dcache_invalid_range(unsigned long *addr, size_t dsize) #if (__DCACHE_PRESENT == 1U) int linesize = csi_get_cache_line_size(); long op_size = dsize + (unsigned long)addr % linesize; - unsigned long op_addr = (unsigned long)addr; + unsigned long op_addr = (unsigned long)addr & CACHE_INV_ADDR_Msk; __DSB(); #if CBO_INSN_SUPPORT - while (op_size > 0) { + while (op_size > 0) + { __CBO_INVAL(op_addr); op_addr += linesize; op_size -= linesize; @@ -1450,14 +1463,18 @@ __STATIC_INLINE void csi_dcache_invalid_range(unsigned long *addr, size_t dsize) cpu_work_mode_t cpu_work_mode; cpu_work_mode = (cpu_work_mode_t)__get_CPU_WORK_MODE(); - if (cpu_work_mode == MACHINE_MODE) { - while (op_size > 0) { + if (cpu_work_mode == MACHINE_MODE) + { + while (op_size > 0) + { __DCACHE_IPA(op_addr); op_addr += linesize; op_size -= linesize; } - } else if (cpu_work_mode == SUPERVISOR_MODE) { - while (op_size > 0) { + } else if (cpu_work_mode == SUPERVISOR_MODE) + { + while (op_size > 0) + { __DCACHE_IVA(op_addr); op_addr += linesize; op_size -= linesize; @@ -1487,7 +1504,8 @@ __STATIC_INLINE void csi_dcache_clean_range(unsigned long *addr, size_t dsize) __DSB(); #if CBO_INSN_SUPPORT - while (op_size > 0) { + while (op_size > 0) + { __CBO_CLEAN(op_addr); op_addr += linesize; op_size -= linesize; @@ -1496,14 +1514,18 @@ __STATIC_INLINE void csi_dcache_clean_range(unsigned long *addr, size_t dsize) cpu_work_mode_t cpu_work_mode; cpu_work_mode = (cpu_work_mode_t)__get_CPU_WORK_MODE(); - if (cpu_work_mode == MACHINE_MODE) { - while (op_size > 0) { + if (cpu_work_mode == MACHINE_MODE) + { + while (op_size > 0) + { __DCACHE_CPA(op_addr); op_addr += linesize; op_size -= linesize; } - } else if (cpu_work_mode == SUPERVISOR_MODE) { - while (op_size > 0) { + } else if (cpu_work_mode == SUPERVISOR_MODE) + { + while (op_size > 0) + { __DCACHE_CVA(op_addr); op_addr += linesize; op_size -= linesize; @@ -1528,11 +1550,12 @@ __STATIC_INLINE void csi_dcache_clean_invalid_range(unsigned long *addr, size_t #if (__DCACHE_PRESENT == 1U) int linesize = csi_get_cache_line_size(); long op_size = dsize + (unsigned long)addr % linesize; - unsigned long op_addr = (unsigned long) addr; + unsigned long op_addr = (unsigned long) addr & CACHE_INV_ADDR_Msk; __DSB(); #if CBO_INSN_SUPPORT - while (op_size > 0) { + while (op_size > 0) + { __CBO_FLUSH(op_addr); op_addr += linesize; op_size -= linesize; @@ -1541,14 +1564,18 @@ __STATIC_INLINE void csi_dcache_clean_invalid_range(unsigned long *addr, size_t cpu_work_mode_t cpu_work_mode; cpu_work_mode = (cpu_work_mode_t)__get_CPU_WORK_MODE(); - if (cpu_work_mode == MACHINE_MODE) { - while (op_size > 0) { + if (cpu_work_mode == MACHINE_MODE) + { + while (op_size > 0) + { __DCACHE_CIPA(op_addr); op_addr += linesize; op_size -= linesize; } - } else if (cpu_work_mode == SUPERVISOR_MODE) { - while (op_size > 0) { + } else if (cpu_work_mode == SUPERVISOR_MODE) + { + while (op_size > 0) + { __DCACHE_CIVA(op_addr); op_addr += linesize; op_size -= linesize; @@ -1709,10 +1736,14 @@ __STATIC_INLINE void csi_mmu_invalid_tlb_all(void) #if CONFIG_CPU_XUANTIE_C907 || CONFIG_CPU_XUANTIE_C907FD || CONFIG_CPU_XUANTIE_C907FDV || CONFIG_CPU_XUANTIE_C907FDVM \ || CONFIG_CPU_XUANTIE_C908 || CONFIG_CPU_XUANTIE_C908V || CONFIG_CPU_XUANTIE_C908I \ + || CONFIG_CPU_XUANTIE_C908X || CONFIG_CPU_XUANTIE_C908X_CP || CONFIG_CPU_XUANTIE_C908X_CP_XT \ || CONFIG_CPU_XUANTIE_C910V2 || CONFIG_CPU_XUANTIE_C920V2 \ - || CONFIG_CPU_XUANTIE_C910V3 || CONFIG_CPU_XUANTIE_C910V3_CP || CONFIG_CPU_XUANTIE_C920V3 || CONFIG_CPU_XUANTIE_C920V3_CP \ + || CONFIG_CPU_XUANTIE_C910V3 || CONFIG_CPU_XUANTIE_C920V3 \ + || CONFIG_CPU_XUANTIE_C910V3_CP || CONFIG_CPU_XUANTIE_C920V3_CP \ + || CONFIG_CPU_XUANTIE_C910V3_CP_XT || CONFIG_CPU_XUANTIE_C920V3_CP_XT \ || CONFIG_CPU_XUANTIE_R908 || CONFIG_CPU_XUANTIE_R908FD || CONFIG_CPU_XUANTIE_R908FDV \ || CONFIG_CPU_XUANTIE_R908_CP || CONFIG_CPU_XUANTIE_R908FD_CP || CONFIG_CPU_XUANTIE_R908FDV_CP \ + || CONFIG_CPU_XUANTIE_R908_CP_XT || CONFIG_CPU_XUANTIE_R908FD_CP_XT || CONFIG_CPU_XUANTIE_R908FDV_CP_XT \ || CONFIG_CPU_XUANTIE_R910 || CONFIG_CPU_XUANTIE_R920 /** \ingroup CSI_tcm_register @@ -2001,3 +2032,4 @@ __STATIC_INLINE int csi_xmlenb_get_value(void) #endif /* __CORE_RV32_H_DEPENDANT */ #endif /* __CSI_GENERIC */ + diff --git a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_arm64_gcc.h b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_arm64_gcc.h index b62de27b929..3569bd3b9cb 100644 --- a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_arm64_gcc.h +++ b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_arm64_gcc.h @@ -704,15 +704,19 @@ __STATIC_INLINE uint8_t __get_PMPxCFG(unsigned long idx) { unsigned long pmpcfgx = 0; - if (idx < 4) { + if (idx < 4) + { pmpcfgx = __get_PMPCFG0(); - } else if (idx >= 4 && idx < 8) { + } else if (idx >= 4 && idx < 8) + { idx -= 4; pmpcfgx = __get_PMPCFG1(); - } else if (idx >= 8 && idx < 12) { + } else if (idx >= 8 && idx < 12) + { idx -= 8; pmpcfgx = __get_PMPCFG2(); - } else if (idx >= 12 && idx < 16) { + } else if (idx >= 12 && idx < 16) + { idx -= 12; pmpcfgx = __get_PMPCFG3(); } else { @@ -757,21 +761,25 @@ __STATIC_INLINE void __set_PMPxCFG(unsigned long idx, uint8_t pmpxcfg) { unsigned long pmpcfgx = 0; - if (idx < 4) { + if (idx < 4) + { pmpcfgx = __get_PMPCFG0(); pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3)); __set_PMPCFG0(pmpcfgx); - } else if (idx >= 4 && idx < 8) { + } else if (idx >= 4 && idx < 8) + { idx -= 4; pmpcfgx = __get_PMPCFG1(); pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3)); __set_PMPCFG1(pmpcfgx); - } else if (idx >= 8 && idx < 12) { + } else if (idx >= 8 && idx < 12) + { idx -= 8; pmpcfgx = __get_PMPCFG2(); pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3)); __set_PMPCFG2(pmpcfgx); - } else if (idx >= 12 && idx < 16) { + } else if (idx >= 12 && idx < 16) + { idx -= 12; pmpcfgx = __get_PMPCFG3(); pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3)); @@ -922,7 +930,8 @@ __ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR15(void) */ __STATIC_INLINE unsigned long __get_PMPADDRx(unsigned long idx) { - switch (idx) { + switch (idx) + { case 0: return __get_PMPADDR0(); @@ -1069,7 +1078,8 @@ __ALWAYS_STATIC_INLINE void __set_PMPADDR15(unsigned long pmpaddr) */ __STATIC_INLINE void __set_PMPADDRx(unsigned long idx, unsigned long pmpaddr) { - switch (idx) { + switch (idx) + { case 0: __set_PMPADDR0(pmpaddr); break; @@ -1627,7 +1637,8 @@ __ALWAYS_STATIC_INLINE uint32_t __RBIT(uint32_t value) result = value; /* r will be reversed bits of v; first get LSB of v */ - for (value >>= 1U; value; value >>= 1U) { + for (value >>= 1U; value; value >>= 1U) + { result <<= 1U; result |= value & 1U; s--; @@ -1659,26 +1670,30 @@ __ALWAYS_STATIC_INLINE int32_t __SSAT(int32_t x, uint32_t y) posMax = 1; - for (i = 0; i < (y - 1); i++) { + for (i = 0; i < (y - 1); i++) + { posMax = posMax * 2; } - if (x > 0) { + if (x > 0) + { posMax = (posMax - 1); - if (x > posMax) { + if (x > posMax) + { x = posMax; } -// x &= (posMax * 2 + 1); +/* x &= (posMax * 2 + 1); */ } else { negMin = -posMax; - if (x < negMin) { + if (x < negMin) + { x = negMin; } -// x &= (posMax * 2 - 1); +/* x &= (posMax * 2 - 1); */ } return (x); @@ -1695,7 +1710,8 @@ __ALWAYS_STATIC_INLINE uint32_t __USAT(uint32_t value, uint32_t sat) { uint32_t result; - if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) + { result = 0xFFFFFFFF >> (32 - sat); } else { result = value; @@ -1715,9 +1731,11 @@ __ALWAYS_STATIC_INLINE uint32_t __IUSAT(uint32_t value, uint32_t sat) { uint32_t result; - if (value & 0x80000000) { /* only overflow set bit-31 */ + if (value & 0x80000000) + { /* only overflow set bit-31 */ result = 0; - } else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + } else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) + { result = 0xFFFFFFFF >> (32 - sat); } else { result = value; @@ -2943,14 +2961,17 @@ __ALWAYS_STATIC_INLINE int32_t __QADD(int32_t x, int32_t y) { int32_t result; - if (y >= 0) { - if ((int32_t)((uint32_t)x + (uint32_t)y) >= x) { + if (y >= 0) + { + if ((int32_t)((uint32_t)x + (uint32_t)y) >= x) + { result = x + y; } else { result = 0x7FFFFFFF; } } else { - if ((int32_t)((uint32_t)x + (uint32_t)y) < x) { + if ((int32_t)((uint32_t)x + (uint32_t)y) < x) + { result = x + y; } else { result = 0x80000000; @@ -2976,9 +2997,11 @@ __ALWAYS_STATIC_INLINE int32_t __QSUB(int32_t x, int32_t y) tmp = (long)x - (long)y; - if (tmp > 0x7fffffff) { + if (tmp > 0x7fffffff) + { tmp = 0x7fffffff; - } else if (tmp < (-2147483647 - 1)) { + } else if (tmp < (-2147483647 - 1)) + { tmp = -2147483647 - 1; } @@ -3284,3 +3307,4 @@ __ALWAYS_STATIC_INLINE uint32_t __UXTB16(uint32_t x) #endif #endif /* _CSI_RV32_GCC_H_ */ + diff --git a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_gcc.h b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_gcc.h index 75b42742655..76156b8c4a9 100644 --- a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_gcc.h +++ b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_gcc.h @@ -1589,7 +1589,8 @@ __ALWAYS_STATIC_INLINE uint32_t __RBIT(uint32_t value) result = value; /* r will be reversed bits of v; first get LSB of v */ - for (value >>= 1U; value; value >>= 1U) { + for (value >>= 1U; value; value >>= 1U) + { result <<= 1U; result |= value & 1U; s--; @@ -1621,26 +1622,30 @@ __ALWAYS_STATIC_INLINE int32_t __SSAT(int32_t x, uint32_t y) posMax = 1; - for (i = 0; i < (y - 1); i++) { + for (i = 0; i < (y - 1); i++) + { posMax = posMax * 2; } - if (x > 0) { + if (x > 0) + { posMax = (posMax - 1); - if (x > posMax) { + if (x > posMax) + { x = posMax; } -// x &= (posMax * 2 + 1); +/* x &= (posMax * 2 + 1); */ } else { negMin = -posMax; - if (x < negMin) { + if (x < negMin) + { x = negMin; } -// x &= (posMax * 2 - 1); +/* x &= (posMax * 2 - 1); */ } return (x); @@ -1657,7 +1662,8 @@ __ALWAYS_STATIC_INLINE uint32_t __USAT(uint32_t value, uint32_t sat) { uint32_t result; - if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) + { result = 0xFFFFFFFF >> (32 - sat); } else { result = value; @@ -1677,9 +1683,11 @@ __ALWAYS_STATIC_INLINE uint32_t __IUSAT(uint32_t value, uint32_t sat) { uint32_t result; - if (value & 0x80000000) { /* only overflow set bit-31 */ + if (value & 0x80000000) + { /* only overflow set bit-31 */ result = 0; - } else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + } else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) + { result = 0xFFFFFFFF >> (32 - sat); } else { result = value; @@ -1729,7 +1737,7 @@ __ALWAYS_STATIC_INLINE uint32_t __RRX(uint32_t op1) __ALWAYS_STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr) { uint32_t result; -//#warning "__LDRBT" +/* #warning "__LDRBT" */ __ASM volatile("ldb %0, (%1, 0)" : "=r"(result) : "r"(addr)); return ((uint8_t) result); /* Add explicit type cast here */ } @@ -1745,7 +1753,7 @@ __ALWAYS_STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr) { uint32_t result; -//#warning "__LDRHT" +/* #warning "__LDRHT" */ __ASM volatile("ldh %0, (%1, 0)" : "=r"(result) : "r"(addr)); return ((uint16_t) result); /* Add explicit type cast here */ } @@ -1761,7 +1769,7 @@ __ALWAYS_STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr) { uint32_t result; -//#warning "__LDRT" +/* #warning "__LDRT" */ __ASM volatile("ldw %0, (%1, 0)" : "=r"(result) : "r"(addr)); return (result); } @@ -1775,7 +1783,7 @@ __ALWAYS_STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr) */ __ALWAYS_STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr) { -//#warning "__STRBT" +/* #warning "__STRBT" */ __ASM volatile("stb %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory"); } @@ -1788,7 +1796,7 @@ __ALWAYS_STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr) */ __ALWAYS_STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr) { -//#warning "__STRHT" +/* #warning "__STRHT" */ __ASM volatile("sth %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory"); } @@ -1801,7 +1809,7 @@ __ALWAYS_STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr) */ __ALWAYS_STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr) { -//#warning "__STRT" +/* #warning "__STRT" */ __ASM volatile("stw %1, (%0, 0)" :: "r"(addr), "r"(value) : "memory"); } @@ -1826,7 +1834,7 @@ __ALWAYS_STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr) */ __ALWAYS_STATIC_INLINE uint32_t __get_FPUType(void) { -//FIXME: +/* FIXME: */ return 0; } @@ -2951,14 +2959,17 @@ __ALWAYS_STATIC_INLINE int32_t __QADD(int32_t x, int32_t y) { int32_t result; - if (y >= 0) { - if (x + y >= x) { + if (y >= 0) + { + if (x + y >= x) + { result = x + y; } else { result = 0x7FFFFFFF; } } else { - if (x + y < x) { + if (x + y < x) + { result = x + y; } else { result = 0x80000000; @@ -2984,9 +2995,11 @@ __ALWAYS_STATIC_INLINE int32_t __QSUB(int32_t x, int32_t y) tmp = (int64_t)x - (int64_t)y; - if (tmp > 0x7fffffff) { + if (tmp > 0x7fffffff) + { tmp = 0x7fffffff; - } else if (tmp < (-2147483647 - 1)) { + } else if (tmp < (-2147483647 - 1)) + { tmp = -2147483647 - 1; } @@ -3291,3 +3304,4 @@ __ALWAYS_STATIC_INLINE uint32_t __UXTB16(uint32_t x) } #endif /* _CSI_GCC_H_ */ + diff --git a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_rv32_gcc.h b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_rv32_gcc.h index 395a1aa9934..a6096f5d415 100644 --- a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_rv32_gcc.h +++ b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_rv32_gcc.h @@ -31,7 +31,9 @@ #if CONFIG_CPU_XUANTIE_E906 || CONFIG_CPU_XUANTIE_E906F || CONFIG_CPU_XUANTIE_E906FD || CONFIG_CPU_XUANTIE_E906P || CONFIG_CPU_XUANTIE_E906FP || CONFIG_CPU_XUANTIE_E906FDP \ || CONFIG_CPU_XUANTIE_E907 || CONFIG_CPU_XUANTIE_E907F || CONFIG_CPU_XUANTIE_E907FD || CONFIG_CPU_XUANTIE_E907P || CONFIG_CPU_XUANTIE_E907FP || CONFIG_CPU_XUANTIE_E907FDP \ - || CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT + || CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT \ + || CONFIG_CPU_XUANTIE_E901PLUS_CP || CONFIG_CPU_XUANTIE_E901PLUS_B_CP || CONFIG_CPU_XUANTIE_E901PLUS_M_CP || CONFIG_CPU_XUANTIE_E901PLUS_BM_CP \ + || CONFIG_CPU_XUANTIE_E901_CP || CONFIG_CPU_XUANTIE_E901_B_CP || CONFIG_CPU_XUANTIE_E901_ZM_CP || CONFIG_CPU_XUANTIE_E901_BZM_CP #define CONFIG_CPU_XUANTIE_E9XX 1 #endif @@ -305,6 +307,30 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MTVT(void) return (result); } +/** + \brief Get MTIME + \details Returns the content of the MTIME Register. + \return MTIME Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MTIME(void) +{ + unsigned long result; + __ASM volatile("rdtime %0" : "=r"(result)); + return (result); +} + +/** + \brief Get MTIMEH + \details Returns the content of the MTIME Register. + \return MTIME Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MTIMEH(void) +{ + unsigned long result; + __ASM volatile("rdtimeh %0" : "=r"(result)); + return (result); +} + /** \brief Get SP \details Returns the content of the SP Register. @@ -472,6 +498,16 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MCYCLE(void) return (result); } +/** + \brief Set MCYCLE + \details Write MCYCLE Register + \param [in] value MCYCLE Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCYCLE(unsigned long value) +{ + __ASM volatile("csrw mcycle, %0" : : "r"(value)); +} + /** \brief Get MCYCLEH Register \details Returns the content of the MCYCLEH Register. @@ -485,6 +521,16 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MCYCLEH(void) return (result); } +/** + \brief Set MCYCLEH + \details Write MCYCLEH Register + \param [in] value MCYCLEH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCYCLEH(unsigned long value) +{ + __ASM volatile("csrw mcycleh, %0" : : "r"(value)); +} + /** \brief Get MINSTRET Register \details Returns the content of the MINSTRET Register. @@ -498,6 +544,16 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MINSTRET(void) return (result); } +/** + \brief Set MINSTRET + \details Write MINSTRET Register + \param [in] value MINSTRET Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MINSTRET(unsigned long value) +{ + __ASM volatile("csrw minstret, %0" : : "r"(value)); +} + /** \brief Get MINSTRETH Register \details Returns the content of the MINSTRETH Register. @@ -511,6 +567,16 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MINSTRETH(void) return (result); } +/** + \brief Set MINSTRETH + \details Write MINSTRETH Register + \param [in] value MINSTRETH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MINSTRETH(unsigned long value) +{ + __ASM volatile("csrw minstreth, %0" : : "r"(value)); +} + #if (CONFIG_CPU_XUANTIE_E907 || CONFIG_CPU_XUANTIE_E907F || CONFIG_CPU_XUANTIE_E907FD || CONFIG_CPU_XUANTIE_E907P || CONFIG_CPU_XUANTIE_E907FP || CONFIG_CPU_XUANTIE_E907FDP) /** \brief Get MITCMCR @@ -558,6 +624,375 @@ __ALWAYS_STATIC_INLINE void __set_MDTCMCR(unsigned long mdtcmcr) } #endif /* end e907xx */ +/** + \brief Set MCOUNTINHIBIT + \details Write MCOUNTINHIBIT Register. + \param [in] value MCOUNTINHIBIT Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCOUNTINHIBIT(uint32_t value) +{ + __ASM volatile("csrw mcountinhibit, %0" : : "r"(value)); +} + +/** + \brief Get MCOUNTINHIBIT + \details Read MCOUNTINHIBIT Register + \return MCOUNTINHIBIT Register value + */ +__ALWAYS_STATIC_INLINE unsigned int __get_MCOUNTINHIBIT(void) +{ + uint32_t result; + __ASM volatile("csrr %0, mcountinhibit" : "=r"(result)); + return result; +} + +/** + \brief Set MHPMEVENT + \details Write MHPMEVENT Register + \param [in] idx Index of MHPMEVENT Register + \param [in] value MHPMEVENT Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHPMEVENT(unsigned long idx, unsigned long value) +{ + switch (idx) + { + case 0: rv_csr_write(0x7E0, value); break; + case 2: rv_csr_write(0x7E1, value); break; + case 3: rv_csr_write(0x323, value); break; + case 4: rv_csr_write(0x324, value); break; + case 5: rv_csr_write(0x325, value); break; + case 6: rv_csr_write(0x326, value); break; + case 7: rv_csr_write(0x327, value); break; + case 8: rv_csr_write(0x328, value); break; + case 9: rv_csr_write(0x329, value); break; + case 10: rv_csr_write(0x32a, value); break; + case 11: rv_csr_write(0x32b, value); break; + case 12: rv_csr_write(0x32c, value); break; + case 13: rv_csr_write(0x32d, value); break; + case 14: rv_csr_write(0x32e, value); break; + case 15: rv_csr_write(0x32f, value); break; + case 16: rv_csr_write(0x330, value); break; + case 17: rv_csr_write(0x331, value); break; + case 18: rv_csr_write(0x332, value); break; + case 19: rv_csr_write(0x333, value); break; + case 20: rv_csr_write(0x334, value); break; + case 21: rv_csr_write(0x335, value); break; + case 22: rv_csr_write(0x336, value); break; + case 23: rv_csr_write(0x337, value); break; + case 24: rv_csr_write(0x338, value); break; + case 25: rv_csr_write(0x339, value); break; + case 26: rv_csr_write(0x33a, value); break; + case 27: rv_csr_write(0x33b, value); break; + case 28: rv_csr_write(0x33c, value); break; + case 29: rv_csr_write(0x33d, value); break; + case 30: rv_csr_write(0x33e, value); break; + case 31: rv_csr_write(0x33F, value); break; + default: break; + } +} + +/** + \brief Get MHPMEVENT + \details Read MHPMEVENT Register. + \param [in] idx Index of MHPMEVENT Register to read. + \return MHPMEVENT Register Value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHPMEVENT(unsigned long idx) +{ + switch (idx) + { + case 0: return rv_csr_read(0x7E0); + case 2: return rv_csr_read(0x7E1); + case 3: return rv_csr_read(0x323); + case 4: return rv_csr_read(0x324); + case 5: return rv_csr_read(0x325); + case 6: return rv_csr_read(0x326); + case 7: return rv_csr_read(0x327); + case 8: return rv_csr_read(0x328); + case 9: return rv_csr_read(0x329); + case 10: return rv_csr_read(0x32a); + case 11: return rv_csr_read(0x32b); + case 12: return rv_csr_read(0x32c); + case 13: return rv_csr_read(0x32d); + case 14: return rv_csr_read(0x32e); + case 15: return rv_csr_read(0x32f); + case 16: return rv_csr_read(0x330); + case 17: return rv_csr_read(0x331); + case 18: return rv_csr_read(0x332); + case 19: return rv_csr_read(0x333); + case 20: return rv_csr_read(0x334); + case 21: return rv_csr_read(0x335); + case 22: return rv_csr_read(0x336); + case 23: return rv_csr_read(0x337); + case 24: return rv_csr_read(0x338); + case 25: return rv_csr_read(0x339); + case 26: return rv_csr_read(0x33a); + case 27: return rv_csr_read(0x33b); + case 28: return rv_csr_read(0x33c); + case 29: return rv_csr_read(0x33d); + case 30: return rv_csr_read(0x33e); + case 31: return rv_csr_read(0x33F); + default: return 0; + } +} + +/** + \brief Set MHPMEVENTH + \details Write MHPMEVENTH Register + \param [in] idx Index of MHPMEVENT Register + \param [in] value MHPMEVENTH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHPMEVENTH(unsigned long idx, unsigned long value) +{ + switch (idx) + { + case 3: rv_csr_write(0x723, value); break; + case 4: rv_csr_write(0x724, value); break; + case 5: rv_csr_write(0x725, value); break; + case 6: rv_csr_write(0x726, value); break; + case 7: rv_csr_write(0x727, value); break; + case 8: rv_csr_write(0x728, value); break; + case 9: rv_csr_write(0x729, value); break; + case 10: rv_csr_write(0x72A, value); break; + case 11: rv_csr_write(0x72B, value); break; + case 12: rv_csr_write(0x72C, value); break; + case 13: rv_csr_write(0x72D, value); break; + case 14: rv_csr_write(0x72E, value); break; + case 15: rv_csr_write(0x72F, value); break; + case 16: rv_csr_write(0x730, value); break; + case 17: rv_csr_write(0x731, value); break; + case 18: rv_csr_write(0x732, value); break; + case 19: rv_csr_write(0x733, value); break; + case 20: rv_csr_write(0x734, value); break; + case 21: rv_csr_write(0x735, value); break; + case 22: rv_csr_write(0x736, value); break; + case 23: rv_csr_write(0x737, value); break; + case 24: rv_csr_write(0x738, value); break; + case 25: rv_csr_write(0x739, value); break; + case 26: rv_csr_write(0x73A, value); break; + case 27: rv_csr_write(0x73B, value); break; + case 28: rv_csr_write(0x73C, value); break; + case 29: rv_csr_write(0x73D, value); break; + case 30: rv_csr_write(0x73E, value); break; + case 31: rv_csr_write(0x73F, value); break; + default: break; + } +} + +/** + \brief Get MHPMEVENTH + \details Read MHPMEVENTH Register. + \param [in] idx Index of MHPMEVENTH Register to read. + \return MHPMEVENTH Register Value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHPMEVENTH(unsigned long idx) +{ + switch (idx) + { + case 3: return rv_csr_read(0x723); + case 4: return rv_csr_read(0x724); + case 5: return rv_csr_read(0x725); + case 6: return rv_csr_read(0x726); + case 7: return rv_csr_read(0x727); + case 8: return rv_csr_read(0x728); + case 9: return rv_csr_read(0x729); + case 10: return rv_csr_read(0x72A); + case 11: return rv_csr_read(0x72B); + case 12: return rv_csr_read(0x72C); + case 13: return rv_csr_read(0x72D); + case 14: return rv_csr_read(0x72E); + case 15: return rv_csr_read(0x72F); + case 16: return rv_csr_read(0x730); + case 17: return rv_csr_read(0x731); + case 18: return rv_csr_read(0x732); + case 19: return rv_csr_read(0x733); + case 20: return rv_csr_read(0x734); + case 21: return rv_csr_read(0x735); + case 22: return rv_csr_read(0x736); + case 23: return rv_csr_read(0x737); + case 24: return rv_csr_read(0x738); + case 25: return rv_csr_read(0x739); + case 26: return rv_csr_read(0x73A); + case 27: return rv_csr_read(0x73B); + case 28: return rv_csr_read(0x73C); + case 29: return rv_csr_read(0x73D); + case 30: return rv_csr_read(0x73E); + case 31: return rv_csr_read(0x73F); + default: return 0; + } +} + +/** + \brief Set MHPMCOUNTER + \details Write MHPMCOUNTER Register + \param [in] idx Index of MHPMCOUNTER Register + \param [in] value MHPMCOUNTER Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHPMCOUNTER(unsigned long idx, unsigned long value) +{ + switch (idx) + { + case 3: rv_csr_write(0xB03, (value)); break; + case 4: rv_csr_write(0xB04, (value)); break; + case 5: rv_csr_write(0xB05, (value)); break; + case 6: rv_csr_write(0xB06, (value)); break; + case 7: rv_csr_write(0xB07, (value)); break; + case 8: rv_csr_write(0xB08, (value)); break; + case 9: rv_csr_write(0xB09, (value)); break; + case 10: rv_csr_write(0xB0A, (value)); break; + case 11: rv_csr_write(0xB0B, (value)); break; + case 12: rv_csr_write(0xB0C, (value)); break; + case 13: rv_csr_write(0xB0D, (value)); break; + case 14: rv_csr_write(0xB0E, (value)); break; + case 15: rv_csr_write(0xB0F, (value)); break; + case 16: rv_csr_write(0xB10, (value)); break; + case 17: rv_csr_write(0xB11, (value)); break; + case 18: rv_csr_write(0xB12, (value)); break; + case 19: rv_csr_write(0xB13, (value)); break; + case 20: rv_csr_write(0xB14, (value)); break; + case 21: rv_csr_write(0xB15, (value)); break; + case 22: rv_csr_write(0xB16, (value)); break; + case 23: rv_csr_write(0xB17, (value)); break; + case 24: rv_csr_write(0xB18, (value)); break; + case 25: rv_csr_write(0xB19, (value)); break; + case 26: rv_csr_write(0xB1A, (value)); break; + case 27: rv_csr_write(0xB1B, (value)); break; + case 28: rv_csr_write(0xB1C, (value)); break; + case 29: rv_csr_write(0xB1D, (value)); break; + case 30: rv_csr_write(0xB1E, (value)); break; + case 31: rv_csr_write(0xB1F, (value)); break; + default: break; + } +} + +/** + \brief Get MHPMCOUNTER + \details Write MHPMCOUNTER Register. + \param [in] idx Index of MHPMCOUNTER Register + \return MHPMCOUNTER Register Value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHPMCOUNTER(unsigned long idx) +{ + switch (idx) + { + case 3: return rv_csr_read(0xB03); + case 4: return rv_csr_read(0xB04); + case 5: return rv_csr_read(0xB05); + case 6: return rv_csr_read(0xB06); + case 7: return rv_csr_read(0xB07); + case 8: return rv_csr_read(0xB08); + case 9: return rv_csr_read(0xB09); + case 10: return rv_csr_read(0xB0A); + case 11: return rv_csr_read(0xB0B); + case 12: return rv_csr_read(0xB0C); + case 13: return rv_csr_read(0xB0D); + case 14: return rv_csr_read(0xB0E); + case 15: return rv_csr_read(0xB0F); + case 16: return rv_csr_read(0xB10); + case 17: return rv_csr_read(0xB11); + case 18: return rv_csr_read(0xB12); + case 19: return rv_csr_read(0xB13); + case 20: return rv_csr_read(0xB14); + case 21: return rv_csr_read(0xB15); + case 22: return rv_csr_read(0xB16); + case 23: return rv_csr_read(0xB17); + case 24: return rv_csr_read(0xB18); + case 25: return rv_csr_read(0xB19); + case 26: return rv_csr_read(0xB1A); + case 27: return rv_csr_read(0xB1B); + case 28: return rv_csr_read(0xB1C); + case 29: return rv_csr_read(0xB1D); + case 30: return rv_csr_read(0xB1E); + case 31: return rv_csr_read(0xB1F); + default: return 0; + } +} + +/** + \brief Set MHPMCOUNTERH + \details Write MHPMCOUNTERH Register + \param [in] idx Index of MHPMCOUNTERH Register + \param [in] value MHPMCOUNTERH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHPMCOUNTERH(unsigned long idx, unsigned long value) +{ + switch (idx) + { + case 3: rv_csr_write(0xB83, (value)); break; + case 4: rv_csr_write(0xB84, (value)); break; + case 5: rv_csr_write(0xB85, (value)); break; + case 6: rv_csr_write(0xB86, (value)); break; + case 7: rv_csr_write(0xB87, (value)); break; + case 8: rv_csr_write(0xB88, (value)); break; + case 9: rv_csr_write(0xB89, (value)); break; + case 10: rv_csr_write(0xB8A, (value)); break; + case 11: rv_csr_write(0xB8B, (value)); break; + case 12: rv_csr_write(0xB8C, (value)); break; + case 13: rv_csr_write(0xB8D, (value)); break; + case 14: rv_csr_write(0xB8E, (value)); break; + case 15: rv_csr_write(0xB8F, (value)); break; + case 16: rv_csr_write(0xB90, (value)); break; + case 17: rv_csr_write(0xB91, (value)); break; + case 18: rv_csr_write(0xB92, (value)); break; + case 19: rv_csr_write(0xB93, (value)); break; + case 20: rv_csr_write(0xB94, (value)); break; + case 21: rv_csr_write(0xB95, (value)); break; + case 22: rv_csr_write(0xB96, (value)); break; + case 23: rv_csr_write(0xB97, (value)); break; + case 24: rv_csr_write(0xB98, (value)); break; + case 25: rv_csr_write(0xB99, (value)); break; + case 26: rv_csr_write(0xB9A, (value)); break; + case 27: rv_csr_write(0xB9B, (value)); break; + case 28: rv_csr_write(0xB9C, (value)); break; + case 29: rv_csr_write(0xB9D, (value)); break; + case 30: rv_csr_write(0xB9E, (value)); break; + case 31: rv_csr_write(0xB9F, (value)); break; + default: break; + } +} + +/** + \brief Get MHPMCOUNTERH + \details Write MHPMCOUNTERH Register. + \param [in] idx Index of MHPMCOUNTERH Register + \return MHPMCOUNTERH Register Value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHPMCOUNTERH(unsigned long idx) +{ + switch (idx) + { + case 3: return rv_csr_read(0xB83); + case 4: return rv_csr_read(0xB84); + case 5: return rv_csr_read(0xB85); + case 6: return rv_csr_read(0xB86); + case 7: return rv_csr_read(0xB87); + case 8: return rv_csr_read(0xB88); + case 9: return rv_csr_read(0xB89); + case 10: return rv_csr_read(0xB8A); + case 11: return rv_csr_read(0xB8B); + case 12: return rv_csr_read(0xB8C); + case 13: return rv_csr_read(0xB8D); + case 14: return rv_csr_read(0xB8E); + case 15: return rv_csr_read(0xB8F); + case 16: return rv_csr_read(0xB90); + case 17: return rv_csr_read(0xB91); + case 18: return rv_csr_read(0xB92); + case 19: return rv_csr_read(0xB93); + case 20: return rv_csr_read(0xB94); + case 21: return rv_csr_read(0xB95); + case 22: return rv_csr_read(0xB96); + case 23: return rv_csr_read(0xB97); + case 24: return rv_csr_read(0xB98); + case 25: return rv_csr_read(0xB99); + case 26: return rv_csr_read(0xB9A); + case 27: return rv_csr_read(0xB9B); + case 28: return rv_csr_read(0xB9C); + case 29: return rv_csr_read(0xB9D); + case 30: return rv_csr_read(0xB9E); + case 31: return rv_csr_read(0xB9F); + default: return 0; + } +} /** \brief Get MVENDORID Register @@ -658,15 +1093,19 @@ __STATIC_INLINE uint8_t __get_PMPxCFG(unsigned long idx) { unsigned long pmpcfgx = 0; - if (idx < 4) { + if (idx < 4) + { pmpcfgx = __get_PMPCFG0(); - } else if (idx >=4 && idx < 8) { + } else if (idx >=4 && idx < 8) + { idx -= 4; pmpcfgx = __get_PMPCFG1(); - } else if (idx >=8 && idx < 12) { + } else if (idx >=8 && idx < 12) + { idx -= 8; pmpcfgx = __get_PMPCFG2(); - } else if (idx >=12 && idx < 16) { + } else if (idx >=12 && idx < 16) + { idx -= 12; pmpcfgx = __get_PMPCFG3(); } else { @@ -711,21 +1150,25 @@ __STATIC_INLINE void __set_PMPxCFG(unsigned long idx, uint8_t pmpxcfg) { unsigned long pmpcfgx = 0; - if (idx < 4) { + if (idx < 4) + { pmpcfgx = __get_PMPCFG0(); pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | (pmpxcfg << (idx << 3)); __set_PMPCFG0(pmpcfgx); - } else if (idx >=4 && idx < 8) { + } else if (idx >=4 && idx < 8) + { idx -= 4; pmpcfgx = __get_PMPCFG1(); pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | (pmpxcfg << (idx << 3)); __set_PMPCFG1(pmpcfgx); - } else if (idx >=8 && idx < 12) { + } else if (idx >=8 && idx < 12) + { idx -= 8; pmpcfgx = __get_PMPCFG2(); pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | (pmpxcfg << (idx << 3)); __set_PMPCFG2(pmpcfgx); - } else if (idx >=12 && idx < 16) { + } else if (idx >=12 && idx < 16) + { idx -= 12; pmpcfgx = __get_PMPCFG3(); pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | (pmpxcfg << (idx << 3)); @@ -876,7 +1319,8 @@ __ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR15(void) */ __STATIC_INLINE unsigned long __get_PMPADDRx(unsigned long idx) { - switch (idx) { + switch (idx) + { case 0: return __get_PMPADDR0(); case 1: return __get_PMPADDR1(); case 2: return __get_PMPADDR2(); @@ -990,7 +1434,8 @@ __ALWAYS_STATIC_INLINE void __set_PMPADDR15(unsigned long pmpaddr) */ __STATIC_INLINE void __set_PMPADDRx(unsigned long idx, unsigned long pmpaddr) { - switch (idx) { + switch (idx) + { case 0: __set_PMPADDR0(pmpaddr); break; case 1: __set_PMPADDR1(pmpaddr); break; case 2: __set_PMPADDR2(pmpaddr); break; @@ -1101,7 +1546,7 @@ __ALWAYS_STATIC_INLINE void __ISB(void) __ALWAYS_STATIC_INLINE void __DSB(void) { __ASM volatile("fence iorw, iorw"); -#ifndef __riscv_xtheadse +#if __riscv_xtheadsync __ASM volatile("sync"); #endif } @@ -1112,7 +1557,9 @@ __ALWAYS_STATIC_INLINE void __DSB(void) */ __ALWAYS_STATIC_INLINE void __ICACHE_IALL(void) { +#if __riscv_xtheadcmo __ASM volatile("icache.iall"); +#endif } /** @@ -1122,7 +1569,9 @@ __ALWAYS_STATIC_INLINE void __ICACHE_IALL(void) */ __ALWAYS_STATIC_INLINE void __ICACHE_IPA(unsigned long addr) { +#if __riscv_xtheadcmo __ASM volatile("icache.ipa %0" : : "r"(addr)); +#endif } /** @@ -1131,7 +1580,7 @@ __ALWAYS_STATIC_INLINE void __ICACHE_IPA(unsigned long addr) */ __ALWAYS_STATIC_INLINE void __DCACHE_IALL(void) { -#ifndef __riscv_xtheadse +#if __riscv_xtheadcmo __ASM volatile("dcache.iall"); #endif } @@ -1142,7 +1591,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_IALL(void) */ __ALWAYS_STATIC_INLINE void __DCACHE_CALL(void) { -#ifndef __riscv_xtheadse +#if __riscv_xtheadcmo __ASM volatile("dcache.call"); #endif } @@ -1153,7 +1602,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CALL(void) */ __ALWAYS_STATIC_INLINE void __DCACHE_CIALL(void) { -#ifndef __riscv_xtheadse +#if __riscv_xtheadcmo __ASM volatile("dcache.ciall"); #endif } @@ -1165,7 +1614,9 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CIALL(void) */ __ALWAYS_STATIC_INLINE void __DCACHE_IPA(unsigned long addr) { +#if __riscv_xtheadcmo __ASM volatile("dcache.ipa %0" : : "r"(addr)); +#endif } /** @@ -1175,7 +1626,9 @@ __ALWAYS_STATIC_INLINE void __DCACHE_IPA(unsigned long addr) */ __ALWAYS_STATIC_INLINE void __DCACHE_CPA(unsigned long addr) { +#if __riscv_xtheadcmo __ASM volatile("dcache.cpa %0" : : "r"(addr)); +#endif } /** @@ -1185,7 +1638,9 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CPA(unsigned long addr) */ __ALWAYS_STATIC_INLINE void __DCACHE_CIPA(unsigned long addr) { +#if __riscv_xtheadcmo __ASM volatile("dcache.cipa %0" : : "r"(addr)); +#endif } @@ -1277,7 +1732,8 @@ __ALWAYS_STATIC_INLINE unsigned long __RBIT(unsigned long value) result = value; /* r will be reversed bits of v; first get LSB of v */ - for (value >>= 1U; value; value >>= 1U) { + for (value >>= 1U; value; value >>= 1U) + { result <<= 1U; result |= value & 1U; s--; @@ -1309,26 +1765,30 @@ __ALWAYS_STATIC_INLINE int32_t __SSAT(int32_t x, unsigned long y) posMax = 1; - for (i = 0; i < (y - 1); i++) { + for (i = 0; i < (y - 1); i++) + { posMax = posMax * 2; } - if (x > 0) { + if (x > 0) + { posMax = (posMax - 1); - if (x > posMax) { + if (x > posMax) + { x = posMax; } -// x &= (posMax * 2 + 1); +/* x &= (posMax * 2 + 1); */ } else { negMin = -posMax; - if (x < negMin) { + if (x < negMin) + { x = negMin; } -// x &= (posMax * 2 - 1); +/* x &= (posMax * 2 - 1); */ } return (x); @@ -1345,7 +1805,8 @@ __ALWAYS_STATIC_INLINE unsigned long __USAT(unsigned long value, unsigned long s { unsigned long result; - if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) + { result = 0xFFFFFFFF >> (32 - sat); } else { result = value; @@ -1365,9 +1826,11 @@ __ALWAYS_STATIC_INLINE unsigned long __IUSAT(unsigned long value, unsigned long { unsigned long result; - if (value & 0x80000000) { /* only overflow set bit-31 */ + if (value & 0x80000000) + { /* only overflow set bit-31 */ result = 0; - } else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + } else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) + { result = 0xFFFFFFFF >> (32 - sat); } else { result = value; @@ -1814,6 +2277,7 @@ __ALWAYS_STATIC_INLINE unsigned long __USAD8(unsigned long x, unsigned long y) return (u + t + s + r); } +#if 0 /** \brief Unsigned sum of quad 8-bit unsigned absolute difference with 32-bit accumulate. \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values @@ -1851,6 +2315,7 @@ __ALWAYS_STATIC_INLINE unsigned long __USADA8(unsigned long x, unsigned long y, #endif return (u + t + s + r + sum); } +#endif /** \brief Dual 16-bit saturating addition. @@ -2593,14 +3058,17 @@ __ALWAYS_STATIC_INLINE int32_t __QADD(int32_t x, int32_t y) { int32_t result; - if (y >= 0) { - if ((int32_t)((unsigned long)x + (unsigned long)y) >= x) { + if (y >= 0) + { + if ((int32_t)((unsigned long)x + (unsigned long)y) >= x) + { result = x + y; } else { result = 0x7FFFFFFF; } } else { - if ((int32_t)((unsigned long)x + (unsigned long)y) < x) { + if ((int32_t)((unsigned long)x + (unsigned long)y) < x) + { result = x + y; } else { result = 0x80000000; @@ -2626,9 +3094,11 @@ __ALWAYS_STATIC_INLINE int32_t __QSUB(int32_t x, int32_t y) tmp = (int64_t)x - (int64_t)y; - if (tmp > 0x7fffffff) { + if (tmp > 0x7fffffff) + { tmp = 0x7fffffff; - } else if (tmp < (-2147483647 - 1)) { + } else if (tmp < (-2147483647 - 1)) + { tmp = -2147483647 - 1; } @@ -2933,3 +3403,4 @@ __ALWAYS_STATIC_INLINE unsigned long __UXTB16(unsigned long x) } #endif /* _CSI_RV32_GCC_H_ */ + diff --git a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_rv64_gcc.h b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_rv64_gcc.h index f9872d772ba..7739e7a0afe 100644 --- a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_rv64_gcc.h +++ b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_rv64_gcc.h @@ -32,10 +32,14 @@ #if CONFIG_CPU_XUANTIE_C907 || CONFIG_CPU_XUANTIE_C907FD || CONFIG_CPU_XUANTIE_C907FDV || CONFIG_CPU_XUANTIE_C907FDVM \ || CONFIG_CPU_XUANTIE_C907_RV32 || CONFIG_CPU_XUANTIE_C907FD_RV32 || CONFIG_CPU_XUANTIE_C907FDV_RV32 || CONFIG_CPU_XUANTIE_C907FDVM_RV32 \ || CONFIG_CPU_XUANTIE_C908 || CONFIG_CPU_XUANTIE_C908V || CONFIG_CPU_XUANTIE_C908I \ - || CONFIG_CPU_XUANTIE_C910V2 || CONFIG_CPU_XUANTIE_C910V3 || CONFIG_CPU_XUANTIE_C910V3_CP \ - || CONFIG_CPU_XUANTIE_C920V2 || CONFIG_CPU_XUANTIE_C920V3 || CONFIG_CPU_XUANTIE_C920V3_CP \ + || CONFIG_CPU_XUANTIE_C908X || CONFIG_CPU_XUANTIE_C908X_CP || CONFIG_CPU_XUANTIE_C908X_CP_XT \ + || CONFIG_CPU_XUANTIE_C910V2 || CONFIG_CPU_XUANTIE_C920V2 \ + || CONFIG_CPU_XUANTIE_C910V3 || CONFIG_CPU_XUANTIE_C920V3 \ + || CONFIG_CPU_XUANTIE_C910V3_CP || CONFIG_CPU_XUANTIE_C920V3_CP \ + || CONFIG_CPU_XUANTIE_C910V3_CP_XT || CONFIG_CPU_XUANTIE_C920V3_CP_XT \ || CONFIG_CPU_XUANTIE_R908 || CONFIG_CPU_XUANTIE_R908FD || CONFIG_CPU_XUANTIE_R908FDV \ - || CONFIG_CPU_XUANTIE_R908_CP || CONFIG_CPU_XUANTIE_R908FD_CP || CONFIG_CPU_XUANTIE_R908FDV_CP + || CONFIG_CPU_XUANTIE_R908_CP || CONFIG_CPU_XUANTIE_R908FD_CP || CONFIG_CPU_XUANTIE_R908FDV_CP \ + || CONFIG_CPU_XUANTIE_R908_CP_XT || CONFIG_CPU_XUANTIE_R908FD_CP_XT || CONFIG_CPU_XUANTIE_R908FDV_CP_XT #define CBO_INSN_SUPPORT 1 #endif @@ -494,7 +498,19 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MTIME(void) unsigned long result; __ASM volatile("rdtime %0" : "=r"(result)); - //__ASM volatile("csrr %0, 0xc01" : "=r"(result)); + /* __ASM volatile("csrr %0, 0xc01" : "=r"(result)); */ + return (result); +} + +/** + \brief Get MTIMEH + \details Returns the content of the MTIME Register. + \return MTIME Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MTIMEH(void) +{ + unsigned long result; + __ASM volatile("rdtimeh %0" : "=r"(result)); return (result); } @@ -838,24 +854,30 @@ __STATIC_INLINE uint8_t __get_PMPxCFG(unsigned long idx) unsigned long pmpcfgx = 0; #if __riscv_xlen == 32 - if (idx < 4) { + if (idx < 4) + { pmpcfgx = __get_PMPCFG0(); - } else if (idx >= 4 && idx < 8) { + } else if (idx >= 4 && idx < 8) + { idx -= 4; pmpcfgx = __get_PMPCFG1(); - } else if (idx >= 8 && idx < 12) { + } else if (idx >= 8 && idx < 12) + { idx -= 8; pmpcfgx = __get_PMPCFG2(); - } else if (idx >= 12 && idx < 16) { + } else if (idx >= 12 && idx < 16) + { idx -= 12; pmpcfgx = __get_PMPCFG3(); } else { return 0; } #else - if (idx < 8) { + if (idx < 8) + { pmpcfgx = __get_PMPCFG0(); - } else if (idx >= 8 && idx < 16) { + } else if (idx >= 8 && idx < 16) + { idx -= 8; pmpcfgx = __get_PMPCFG2(); } else { @@ -906,21 +928,25 @@ __STATIC_INLINE void __set_PMPxCFG(unsigned long idx, uint8_t pmpxcfg) unsigned long pmpcfgx = 0; #if __riscv_xlen == 32 - if (idx < 4) { + if (idx < 4) + { pmpcfgx = __get_PMPCFG0(); pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3)); __set_PMPCFG0(pmpcfgx); - } else if (idx >= 4 && idx < 8) { + } else if (idx >= 4 && idx < 8) + { idx -= 4; pmpcfgx = __get_PMPCFG1(); pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3)); __set_PMPCFG1(pmpcfgx); - } else if (idx >= 8 && idx < 12) { + } else if (idx >= 8 && idx < 12) + { idx -= 8; pmpcfgx = __get_PMPCFG2(); pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3)); __set_PMPCFG2(pmpcfgx); - } else if (idx >= 12 && idx < 16) { + } else if (idx >= 12 && idx < 16) + { idx -= 12; pmpcfgx = __get_PMPCFG3(); pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3)); @@ -929,11 +955,13 @@ __STATIC_INLINE void __set_PMPxCFG(unsigned long idx, uint8_t pmpxcfg) return; } #else - if (idx < 8) { + if (idx < 8) + { pmpcfgx = __get_PMPCFG0(); pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3)); __set_PMPCFG0(pmpcfgx); - } else if (idx >= 8 && idx < 16) { + } else if (idx >= 8 && idx < 16) + { idx -= 8; pmpcfgx = __get_PMPCFG2(); pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3)); @@ -1085,7 +1113,8 @@ __ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR15(void) */ __STATIC_INLINE unsigned long __get_PMPADDRx(unsigned long idx) { - switch (idx) { + switch (idx) + { case 0: return __get_PMPADDR0(); @@ -1232,7 +1261,8 @@ __ALWAYS_STATIC_INLINE void __set_PMPADDR15(unsigned long pmpaddr) */ __STATIC_INLINE void __set_PMPADDRx(unsigned long idx, unsigned long pmpaddr) { - switch (idx) { + switch (idx) + { case 0: __set_PMPADDR0(pmpaddr); break; @@ -1588,7 +1618,9 @@ __ALWAYS_STATIC_INLINE void __ISB(void) __ALWAYS_STATIC_INLINE void __DSB(void) { __ASM volatile("fence iorw, iorw"); +#if __riscv_xtheadsync __ASM volatile("sync"); +#endif } /** @@ -1608,7 +1640,9 @@ __ALWAYS_STATIC_INLINE void __DMB(void) */ __ALWAYS_STATIC_INLINE void __SYNC_IS(void) { +#if __riscv_xtheadsync __ASM volatile("sync.is"); +#endif } /** @@ -1617,7 +1651,9 @@ __ALWAYS_STATIC_INLINE void __SYNC_IS(void) */ __ALWAYS_STATIC_INLINE void __ICACHE_IALL(void) { +#if __riscv_xtheadcmo __ASM volatile("icache.iall"); +#endif } /** @@ -1626,7 +1662,9 @@ __ALWAYS_STATIC_INLINE void __ICACHE_IALL(void) */ __ALWAYS_STATIC_INLINE void __ICACHE_IALLS(void) { +#if __riscv_xtheadcmo __ASM volatile("icache.ialls"); +#endif } /** @@ -1636,7 +1674,9 @@ __ALWAYS_STATIC_INLINE void __ICACHE_IALLS(void) */ __ALWAYS_STATIC_INLINE void __ICACHE_IPA(unsigned long addr) { +#if __riscv_xtheadcmo __ASM volatile("icache.ipa %0" : : "r"(addr)); +#endif } /** @@ -1646,7 +1686,9 @@ __ALWAYS_STATIC_INLINE void __ICACHE_IPA(unsigned long addr) */ __ALWAYS_STATIC_INLINE void __ICACHE_IVA(unsigned long addr) { +#if __riscv_xtheadcmo __ASM volatile("icache.iva %0" : : "r"(addr)); +#endif } /** @@ -1655,7 +1697,9 @@ __ALWAYS_STATIC_INLINE void __ICACHE_IVA(unsigned long addr) */ __ALWAYS_STATIC_INLINE void __DCACHE_IALL(void) { +#if __riscv_xtheadcmo __ASM volatile("dcache.iall"); +#endif } /** @@ -1664,7 +1708,9 @@ __ALWAYS_STATIC_INLINE void __DCACHE_IALL(void) */ __ALWAYS_STATIC_INLINE void __DCACHE_CALL(void) { +#if __riscv_xtheadcmo __ASM volatile("dcache.call"); +#endif } /** @@ -1673,7 +1719,9 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CALL(void) */ __ALWAYS_STATIC_INLINE void __DCACHE_CIALL(void) { +#if __riscv_xtheadcmo __ASM volatile("dcache.ciall"); +#endif } /** @@ -1683,7 +1731,9 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CIALL(void) */ __ALWAYS_STATIC_INLINE void __DCACHE_CISW(unsigned long wayset) { +#if __riscv_xtheadcmo __ASM volatile("dcache.cisw %0" : : "r"(wayset)); +#endif } #if CBO_INSN_SUPPORT @@ -1734,7 +1784,9 @@ __ALWAYS_STATIC_INLINE void __CBO_ZERO(unsigned long addr) */ __ALWAYS_STATIC_INLINE void __DCACHE_CPA(unsigned long addr) { +#if __riscv_xtheadcmo __ASM volatile("dcache.cpa %0" : : "r"(addr)); +#endif } /** @@ -1744,7 +1796,9 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CPA(unsigned long addr) */ __ALWAYS_STATIC_INLINE void __DCACHE_CVA(unsigned long addr) { +#if __riscv_xtheadcmo __ASM volatile("dcache.cva %0" : : "r"(addr)); +#endif } /** @@ -1754,7 +1808,9 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CVA(unsigned long addr) */ __ALWAYS_STATIC_INLINE void __DCACHE_CIPA(unsigned long addr) { +#if __riscv_xtheadcmo __ASM volatile("dcache.cipa %0" : : "r"(addr)); +#endif } /** @@ -1764,7 +1820,9 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CIPA(unsigned long addr) */ __ALWAYS_STATIC_INLINE void __DCACHE_CIVA(unsigned long addr) { +#if __riscv_xtheadcmo __ASM volatile("dcache.civa %0" : : "r"(addr)); +#endif } /** @@ -1774,7 +1832,9 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CIVA(unsigned long addr) */ __ALWAYS_STATIC_INLINE void __DCACHE_IPA(unsigned long addr) { +#if __riscv_xtheadcmo __ASM volatile("dcache.ipa %0" : : "r"(addr)); +#endif } /** @@ -1784,7 +1844,9 @@ __ALWAYS_STATIC_INLINE void __DCACHE_IPA(unsigned long addr) */ __ALWAYS_STATIC_INLINE void __DCACHE_IVA(unsigned long addr) { +#if __riscv_xtheadcmo __ASM volatile("dcache.iva %0" : : "r"(addr)); +#endif } #endif @@ -1796,7 +1858,9 @@ __ALWAYS_STATIC_INLINE void __DCACHE_IVA(unsigned long addr) */ __ALWAYS_STATIC_INLINE void __DCACHE_CPAL1(unsigned long addr) { +#if __riscv_xtheadcmo __ASM volatile("dcache.cpal1 %0" : : "r"(addr)); +#endif } /** @@ -1806,7 +1870,9 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CPAL1(unsigned long addr) */ __ALWAYS_STATIC_INLINE void __DCACHE_CVAL1(unsigned long addr) { +#if __riscv_xtheadcmo __ASM volatile("dcache.cval1 %0" : : "r"(addr)); +#endif } /** @@ -1816,7 +1882,9 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CVAL1(unsigned long addr) */ __ALWAYS_STATIC_INLINE void __DCACHE_ISW(unsigned long wayset) { +#if __riscv_xtheadcmo __ASM volatile("dcache.isw %0" : : "r"(wayset)); +#endif } #if (__L2CACHE_PRESENT == 1U) @@ -1948,7 +2016,7 @@ __ALWAYS_STATIC_INLINE void __set_MCER2H(unsigned long mcer2h) __ALWAYS_STATIC_INLINE unsigned long __get_SSBEPA2(void) { register unsigned long result; - //__ASM volatile("csrr %0, ssbepa2" : "=r"(result)); + /* __ASM volatile("csrr %0, ssbepa2" : "=r"(result)); */ __ASM volatile("csrr %0, 0x5d2" : "=r"(result)); return (result); } @@ -1960,7 +2028,7 @@ __ALWAYS_STATIC_INLINE unsigned long __get_SSBEPA2(void) */ __ALWAYS_STATIC_INLINE void __set_SSBEPA2(unsigned long ssbepa2) { - //__ASM volatile("csrw ssbepa2, %0" : : "r"(ssbepa2)); + /* __ASM volatile("csrw ssbepa2, %0" : : "r"(ssbepa2)); */ __ASM volatile("csrw 0x5d2, %0" : : "r"(ssbepa2)); } @@ -1972,7 +2040,7 @@ __ALWAYS_STATIC_INLINE void __set_SSBEPA2(unsigned long ssbepa2) __ALWAYS_STATIC_INLINE unsigned long __get_MSBEPA2(void) { register unsigned long result; - //__ASM volatile("csrr %0, msbepa2" : "=r"(result)); + /* __ASM volatile("csrr %0, msbepa2" : "=r"(result)); */ __ASM volatile("csrr %0, 0x7fc" : "=r"(result)); return (result); } @@ -1984,7 +2052,7 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MSBEPA2(void) */ __ALWAYS_STATIC_INLINE void __set_MSBEPA2(unsigned long msbepa2) { - //__ASM volatile("csrw msbepa2, %0" : : "r"(msbepa2)); + /* __ASM volatile("csrw msbepa2, %0" : : "r"(msbepa2)); */ __ASM volatile("csrw 0x7fc, %0" : : "r"(msbepa2)); } @@ -2064,7 +2132,7 @@ __ALWAYS_STATIC_INLINE void __set_MCERH(unsigned long mcerh) __ALWAYS_STATIC_INLINE unsigned long __get_SSBEPA(void) { register unsigned long result; - //__ASM volatile("csrr %0, ssbepa" : "=r"(result)); + /* __ASM volatile("csrr %0, ssbepa" : "=r"(result)); */ __ASM volatile("csrr %0, 0x5d1" : "=r"(result)); return (result); } @@ -2076,7 +2144,7 @@ __ALWAYS_STATIC_INLINE unsigned long __get_SSBEPA(void) */ __ALWAYS_STATIC_INLINE void __set_SSBEPA(unsigned long ssbepa) { - //__ASM volatile("csrw ssbepa, %0" : : "r"(ssbepa)); + /* __ASM volatile("csrw ssbepa, %0" : : "r"(ssbepa)); */ __ASM volatile("csrw 0x5d1, %0" : : "r"(ssbepa)); } @@ -2088,7 +2156,7 @@ __ALWAYS_STATIC_INLINE void __set_SSBEPA(unsigned long ssbepa) __ALWAYS_STATIC_INLINE unsigned long __get_MSBEPA(void) { register unsigned long result; - //__ASM volatile("csrr %0, msbepa" : "=r"(result)); + /* __ASM volatile("csrr %0, msbepa" : "=r"(result)); */ __ASM volatile("csrr %0, 0x7fb" : "=r"(result)); return (result); } @@ -2100,7 +2168,7 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MSBEPA(void) */ __ALWAYS_STATIC_INLINE void __set_MSBEPA(unsigned long msbepa) { - //__ASM volatile("csrw msbepa, %0" : : "r"(msbepa)); + /* __ASM volatile("csrw msbepa, %0" : : "r"(msbepa)); */ __ASM volatile("csrw 0x7fb, %0" : : "r"(msbepa)); } @@ -2259,7 +2327,8 @@ __ALWAYS_STATIC_INLINE unsigned int __get_MCOUNTINHIBIT(void) */ __ALWAYS_STATIC_INLINE void __set_MHPMEVENT(unsigned long idx, unsigned long value) { - switch (idx) { + switch (idx) + { case 0: rv_csr_write(0x7E0, value); break; case 2: rv_csr_write(0x7E1, value); break; case 3: rv_csr_write(0x323, value); break; @@ -2303,7 +2372,8 @@ __ALWAYS_STATIC_INLINE void __set_MHPMEVENT(unsigned long idx, unsigned long val */ __ALWAYS_STATIC_INLINE unsigned long __get_MHPMEVENT(unsigned long idx) { - switch (idx) { + switch (idx) + { case 0: return rv_csr_read(0x7E0); case 2: return rv_csr_read(0x7E1); case 3: return rv_csr_read(0x323); @@ -2347,7 +2417,8 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MHPMEVENT(unsigned long idx) */ __ALWAYS_STATIC_INLINE void __set_MHPMEVENTH(unsigned long idx, unsigned long value) { - switch (idx) { + switch (idx) + { case 3: rv_csr_write(0x723, value); break; case 4: rv_csr_write(0x724, value); break; case 5: rv_csr_write(0x725, value); break; @@ -2389,7 +2460,8 @@ __ALWAYS_STATIC_INLINE void __set_MHPMEVENTH(unsigned long idx, unsigned long va */ __ALWAYS_STATIC_INLINE unsigned long __get_MHPMEVENTH(unsigned long idx) { - switch (idx) { + switch (idx) + { case 3: return rv_csr_read(0x723); case 4: return rv_csr_read(0x724); case 5: return rv_csr_read(0x725); @@ -2431,7 +2503,8 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MHPMEVENTH(unsigned long idx) */ __ALWAYS_STATIC_INLINE void __set_MHPMCOUNTER(unsigned long idx, unsigned long value) { - switch (idx) { + switch (idx) + { case 3: rv_csr_write(0xB03, (value)); break; case 4: rv_csr_write(0xB04, (value)); break; case 5: rv_csr_write(0xB05, (value)); break; @@ -2473,7 +2546,8 @@ __ALWAYS_STATIC_INLINE void __set_MHPMCOUNTER(unsigned long idx, unsigned long v */ __ALWAYS_STATIC_INLINE unsigned long __get_MHPMCOUNTER(unsigned long idx) { - switch (idx) { + switch (idx) + { case 3: return rv_csr_read(0xB03); case 4: return rv_csr_read(0xB04); case 5: return rv_csr_read(0xB05); @@ -2515,7 +2589,8 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MHPMCOUNTER(unsigned long idx) */ __ALWAYS_STATIC_INLINE void __set_MHPMCOUNTERH(unsigned long idx, unsigned long value) { - switch (idx) { + switch (idx) + { case 3: rv_csr_write(0xB83, (value)); break; case 4: rv_csr_write(0xB84, (value)); break; case 5: rv_csr_write(0xB85, (value)); break; @@ -2557,7 +2632,8 @@ __ALWAYS_STATIC_INLINE void __set_MHPMCOUNTERH(unsigned long idx, unsigned long */ __ALWAYS_STATIC_INLINE unsigned long __get_MHPMCOUNTERH(unsigned long idx) { - switch (idx) { + switch (idx) + { case 3: return rv_csr_read(0xB83); case 4: return rv_csr_read(0xB84); case 5: return rv_csr_read(0xB85); @@ -2670,7 +2746,8 @@ __ALWAYS_STATIC_INLINE uint32_t __RBIT(uint32_t value) result = value; /* r will be reversed bits of v; first get LSB of v */ - for (value >>= 1U; value; value >>= 1U) { + for (value >>= 1U; value; value >>= 1U) + { result <<= 1U; result |= value & 1U; s--; @@ -2702,26 +2779,30 @@ __ALWAYS_STATIC_INLINE int32_t __SSAT(int32_t x, uint32_t y) posMax = 1; - for (i = 0; i < (y - 1); i++) { + for (i = 0; i < (y - 1); i++) + { posMax = posMax * 2; } - if (x > 0) { + if (x > 0) + { posMax = (posMax - 1); - if (x > posMax) { + if (x > posMax) + { x = posMax; } -// x &= (posMax * 2 + 1); +/* x &= (posMax * 2 + 1); */ } else { negMin = -posMax; - if (x < negMin) { + if (x < negMin) + { x = negMin; } -// x &= (posMax * 2 - 1); +/* x &= (posMax * 2 - 1); */ } return (x); @@ -2738,7 +2819,8 @@ __ALWAYS_STATIC_INLINE uint32_t __USAT(uint32_t value, uint32_t sat) { uint32_t result; - if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) + { result = 0xFFFFFFFF >> (32 - sat); } else { result = value; @@ -2758,9 +2840,11 @@ __ALWAYS_STATIC_INLINE uint32_t __IUSAT(uint32_t value, uint32_t sat) { uint32_t result; - if (value & 0x80000000) { /* only overflow set bit-31 */ + if (value & 0x80000000) + { /* only overflow set bit-31 */ result = 0; - } else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + } else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) + { result = 0xFFFFFFFF >> (32 - sat); } else { result = value; @@ -3986,14 +4070,17 @@ __ALWAYS_STATIC_INLINE int32_t __QADD(int32_t x, int32_t y) { int32_t result; - if (y >= 0) { - if ((int32_t)((uint32_t)x + (uint32_t)y) >= x) { + if (y >= 0) + { + if ((int32_t)((uint32_t)x + (uint32_t)y) >= x) + { result = x + y; } else { result = 0x7FFFFFFF; } } else { - if ((int32_t)((uint32_t)x + (uint32_t)y) < x) { + if ((int32_t)((uint32_t)x + (uint32_t)y) < x) + { result = x + y; } else { result = 0x80000000; @@ -4019,9 +4106,11 @@ __ALWAYS_STATIC_INLINE int32_t __QSUB(int32_t x, int32_t y) tmp = (long)x - (long)y; - if (tmp > 0x7fffffff) { + if (tmp > 0x7fffffff) + { tmp = 0x7fffffff; - } else if (tmp < (-2147483647 - 1)) { + } else if (tmp < (-2147483647 - 1)) + { tmp = -2147483647 - 1; } @@ -4327,3 +4416,4 @@ __ALWAYS_STATIC_INLINE uint32_t __UXTB16(uint32_t x) #endif #endif /* _CSI_RV32_GCC_H_ */ + diff --git a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_rv_common.h b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_rv_common.h index c2ebf23a79a..1cabea2cac3 100644 --- a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_rv_common.h +++ b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/core/csi_rv_common.h @@ -123,7 +123,67 @@ }) #endif - +#define CSR_MCOR 0x7c2 +#define CSR_MHCR 0x7c1 +#define CSR_MCCR2 0x7c3 +#define CSR_MHINT 0x7c5 +#define CSR_MHINT2 0x7cc +#define CSR_MHINT3 0x7cd +#define CSR_MHINT4 0x7ce +#define CSR_MXSTATUS 0x7c0 +#define CSR_PLIC_BASE 0xfc1 +#define CSR_MRMR 0x7c6 +#define CSR_MRVBR 0x7c7 +#define CSR_MCOUNTERWEN 0x7c9 +#define CSR_MSMPR 0x7f3 + +#define CSR_MARCHID 0xf12 +#define CSR_MIMPID 0xf13 +#define CSR_MHARTID 0xf14 +#define CSR_MCPUID 0xfc0 + +#define CSR_MSTATUS 0x300 +#define CSR_MISA 0x301 +#define CSR_MEDELEG 0x302 +#define CSR_MIDELEG 0x303 +#define CSR_MIE 0x304 +#define CSR_MTVEC 0x305 +#define CSR_MCOUNTEREN 0x306 +#define CSR_MENVCFG 0x30a +#define CSR_MSTATUSH 0x310 +#define CSR_MSCRATCH 0x340 +#define CSR_MEPC 0x341 +#define CSR_MCAUSE 0x342 +#define CSR_MTVAL 0x343 +#define CSR_MIP 0x344 +#define CSR_MTINST 0x34a +#define CSR_MTVAL2 0x34b + + /* Machine Memory Protection */ +#define CSR_PMPCFG0 0x3a0 +#define CSR_PMPCFG1 0x3a1 +#define CSR_PMPCFG2 0x3a2 +#define CSR_PMPCFG3 0x3a3 +#define CSR_PMPCFG4 0x3a4 +#define CSR_PMPCFG5 0x3a5 +#define CSR_PMPCFG6 0x3a6 +#define CSR_PMPCFG7 0x3a7 +#define CSR_PMPCFG8 0x3a8 +#define CSR_PMPCFG9 0x3a9 +#define CSR_PMPCFG10 0x3aa +#define CSR_PMPCFG11 0x3ab +#define CSR_PMPCFG12 0x3ac +#define CSR_PMPCFG13 0x3ad +#define CSR_PMPCFG14 0x3ae +#define CSR_PMPCFG15 0x3af +#define CSR_PMPADDR0 0x3b0 +#define CSR_PMPADDR1 0x3b1 +#define CSR_PMPADDR2 0x3b2 +#define CSR_PMPADDR3 0x3b3 +#define CSR_PMPADDR4 0x3b4 +#define CSR_PMPADDR5 0x3b5 +#define CSR_PMPADDR6 0x3b6 +#define CSR_PMPADDR7 0x3b7 #endif /* __CSI_RV_COMMON_H__ */ diff --git a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/csi_core.h b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/csi_core.h index 85fe3408211..38efec98b36 100644 --- a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/csi_core.h +++ b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/csi_core.h @@ -54,7 +54,9 @@ #if CONFIG_CPU_XUANTIE_E906 || CONFIG_CPU_XUANTIE_E906F || CONFIG_CPU_XUANTIE_E906FD || CONFIG_CPU_XUANTIE_E906P || CONFIG_CPU_XUANTIE_E906FP || CONFIG_CPU_XUANTIE_E906FDP \ || CONFIG_CPU_XUANTIE_E907 || CONFIG_CPU_XUANTIE_E907F || CONFIG_CPU_XUANTIE_E907FD || CONFIG_CPU_XUANTIE_E907P || CONFIG_CPU_XUANTIE_E907FP || CONFIG_CPU_XUANTIE_E907FDP \ - || CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT + || CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT \ + || CONFIG_CPU_XUANTIE_E901PLUS_CP || CONFIG_CPU_XUANTIE_E901PLUS_B_CP || CONFIG_CPU_XUANTIE_E901PLUS_M_CP || CONFIG_CPU_XUANTIE_E901PLUS_BM_CP \ + || CONFIG_CPU_XUANTIE_E901_CP || CONFIG_CPU_XUANTIE_E901_B_CP || CONFIG_CPU_XUANTIE_E901_ZM_CP || CONFIG_CPU_XUANTIE_E901_BZM_CP #include #include #else @@ -112,18 +114,28 @@ __STATIC_INLINE const char* csi_get_cpu_name() return "c908v"; #elif CONFIG_CPU_XUANTIE_C908I return "c908i"; +#elif CONFIG_CPU_XUANTIE_C908X + return "c908x"; +#elif CONFIG_CPU_XUANTIE_C908X_CP + return "c908x-cp"; +#elif CONFIG_CPU_XUANTIE_C908X_CP_XT + return "c908x-cp-xt"; #elif CONFIG_CPU_XUANTIE_C910V2 return "c910v2"; #elif CONFIG_CPU_XUANTIE_C910V3 return "c910v3"; #elif CONFIG_CPU_XUANTIE_C910V3_CP return "c910v3-cp"; +#elif CONFIG_CPU_XUANTIE_C910V3_CP_XT + return "c910v3-cp-xt"; #elif CONFIG_CPU_XUANTIE_C920V2 return "c920v2"; #elif CONFIG_CPU_XUANTIE_C920V3 return "c920v3"; #elif CONFIG_CPU_XUANTIE_C920V3_CP return "c920v3-cp"; +#elif CONFIG_CPU_XUANTIE_C920V3_CP_XT + return "c920v3-cp-xt"; #elif CONFIG_CPU_XUANTIE_R910 return "r910"; #elif CONFIG_CPU_XUANTIE_R920 @@ -140,7 +152,28 @@ __STATIC_INLINE const char* csi_get_cpu_name() return "r908fd-cp"; #elif CONFIG_CPU_XUANTIE_R908FDV_CP return "r908fdv-cp"; - +#elif CONFIG_CPU_XUANTIE_R908_CP_XT + return "r908-cp-xt"; +#elif CONFIG_CPU_XUANTIE_R908FD_CP_XT + return "r908fd-cp-xt"; +#elif CONFIG_CPU_XUANTIE_R908FDV_CP_XT + return "r908fdv-cp-xt"; +#elif CONFIG_CPU_XUANTIE_E901PLUS_CP + return "e901plus-cp"; +#elif CONFIG_CPU_XUANTIE_E901PLUS_B_CP + return "e901plusb-cp"; +#elif CONFIG_CPU_XUANTIE_E901PLUS_M_CP + return "e901plusm-cp"; +#elif CONFIG_CPU_XUANTIE_E901PLUS_BM_CP + return "e901plusbm-cp"; +#elif CONFIG_CPU_XUANTIE_E901_CP + return "e901-cp"; +#elif CONFIG_CPU_XUANTIE_E901_B_CP + return "e901b-cp"; +#elif CONFIG_CPU_XUANTIE_E901_ZM_CP + return "e901zm-cp"; +#elif CONFIG_CPU_XUANTIE_E901_BZM_CP + return "e901bzm-cp"; #elif CONFIG_CPU_XUANTIE_E902 return "e902"; #elif CONFIG_CPU_XUANTIE_E902M @@ -184,3 +217,4 @@ __STATIC_INLINE const char* csi_get_cpu_name() #endif #endif /* _CORE_H_ */ + diff --git a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/syslog.h b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/syslog.h index b24586db4f2..674e0c31b99 100644 --- a/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/syslog.h +++ b/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/syslog.h @@ -119,3 +119,4 @@ extern const char *PFORMAT_E; #endif #endif /* _SYSLOG_H_ */ + diff --git a/bsp/xuantie/smartl/e901/.config b/bsp/xuantie/smartl/e901/.config new file mode 100644 index 00000000000..b9a9d9ca1da --- /dev/null +++ b/bsp/xuantie/smartl/e901/.config @@ -0,0 +1,1418 @@ +CONFIG_XUANTIAN_SMARTL_E901=y + +# +# RT-Thread Kernel +# + +# +# klibc options +# + +# +# rt_vsnprintf options +# +# CONFIG_RT_KLIBC_USING_LIBC_VSNPRINTF is not set +# CONFIG_RT_KLIBC_USING_VSNPRINTF_LONGLONG is not set +# CONFIG_RT_KLIBC_USING_VSNPRINTF_STANDARD is not set +# end of rt_vsnprintf options + +# +# rt_vsscanf options +# +# CONFIG_RT_KLIBC_USING_LIBC_VSSCANF is not set +# end of rt_vsscanf options + +# +# rt_memset options +# +# CONFIG_RT_KLIBC_USING_USER_MEMSET is not set +# CONFIG_RT_KLIBC_USING_LIBC_MEMSET is not set +# CONFIG_RT_KLIBC_USING_TINY_MEMSET is not set +# end of rt_memset options + +# +# rt_memcpy options +# +# CONFIG_RT_KLIBC_USING_USER_MEMCPY is not set +# CONFIG_RT_KLIBC_USING_LIBC_MEMCPY is not set +# CONFIG_RT_KLIBC_USING_TINY_MEMCPY is not set +# end of rt_memcpy options + +# +# rt_memmove options +# +# CONFIG_RT_KLIBC_USING_USER_MEMMOVE is not set +# CONFIG_RT_KLIBC_USING_LIBC_MEMMOVE is not set +# end of rt_memmove options + +# +# rt_memcmp options +# +# CONFIG_RT_KLIBC_USING_USER_MEMCMP is not set +# CONFIG_RT_KLIBC_USING_LIBC_MEMCMP is not set +# end of rt_memcmp options + +# +# rt_strstr options +# +# CONFIG_RT_KLIBC_USING_USER_STRSTR is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRSTR is not set +# end of rt_strstr options + +# +# rt_strcasecmp options +# +# CONFIG_RT_KLIBC_USING_USER_STRCASECMP is not set +# end of rt_strcasecmp options + +# +# rt_strncpy options +# +# CONFIG_RT_KLIBC_USING_USER_STRNCPY is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRNCPY is not set +# end of rt_strncpy options + +# +# rt_strcpy options +# +# CONFIG_RT_KLIBC_USING_USER_STRCPY is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRCPY is not set +# end of rt_strcpy options + +# +# rt_strncmp options +# +# CONFIG_RT_KLIBC_USING_USER_STRNCMP is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRNCMP is not set +# end of rt_strncmp options + +# +# rt_strcmp options +# +# CONFIG_RT_KLIBC_USING_USER_STRCMP is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRCMP is not set +# end of rt_strcmp options + +# +# rt_strlen options +# +# CONFIG_RT_KLIBC_USING_USER_STRLEN is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRLEN is not set +# end of rt_strlen options + +# +# rt_strnlen options +# +# CONFIG_RT_KLIBC_USING_USER_STRNLEN is not set +# end of rt_strnlen options +# end of klibc options + +CONFIG_RT_NAME_MAX=8 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +# CONFIG_RT_USING_NANO is not set +# CONFIG_RT_USING_AMP is not set +# CONFIG_RT_USING_SMP is not set +CONFIG_RT_CPUS_NR=1 +CONFIG_RT_ALIGN_SIZE=8 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=1000 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y +# CONFIG_RT_USING_HOOKLIST is not set +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=256 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=1024 +# CONFIG_RT_USING_TIMER_ALL_SOFT is not set +# CONFIG_RT_USING_CPU_USAGE_TRACER is not set + +# +# kservice options +# +# CONFIG_RT_USING_TINY_FFS is not set +# end of kservice options + +CONFIG_RT_USING_DEBUG=y +CONFIG_RT_DEBUGING_ASSERT=y +CONFIG_RT_DEBUGING_COLOR=y +CONFIG_RT_DEBUGING_CONTEXT=y +# CONFIG_RT_DEBUGING_AUTO_INIT is not set +# CONFIG_RT_USING_CI_ACTION is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_MESSAGEQUEUE_PRIORITY is not set +# CONFIG_RT_USING_SIGNALS is not set +# end of Inter-Thread communication + +# +# Memory Management +# +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +# CONFIG_RT_USING_MEMHEAP is not set +CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +# CONFIG_RT_USING_SLAB_AS_HEAP is not set +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +# CONFIG_RT_USING_HEAP_ISR is not set +CONFIG_RT_USING_HEAP=y +# end of Memory Management + +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +# CONFIG_RT_USING_THREADSAFE_PRINTF is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart0" +CONFIG_RT_VER_NUM=0x50201 +# CONFIG_RT_USING_STDC_ATOMIC is not set +CONFIG_RT_BACKTRACE_LEVEL_MAX_NR=32 +# end of RT-Thread Kernel + +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_RISCV32=y + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 +# CONFIG_RT_USING_LEGACY is not set +CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +# CONFIG_FINSH_USING_WORD_OPERATION is not set +# CONFIG_FINSH_USING_FUNC_EXT is not set +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_CMD_SIZE=80 +CONFIG_MSH_USING_BUILT_IN_COMMANDS=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 +CONFIG_FINSH_USING_OPTION_COMPLETION=y + +# +# DFS: device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_POSIX=y +CONFIG_DFS_USING_WORKDIR=y +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_DFS_FD_MAX=16 +CONFIG_RT_USING_DFS_V1=y +# CONFIG_RT_USING_DFS_V2 is not set +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# CONFIG_RT_USING_DFS_ROMFS is not set +# CONFIG_RT_USING_DFS_CROMFS is not set +# CONFIG_RT_USING_DFS_RAMFS is not set +# CONFIG_RT_USING_DFS_TMPFS is not set +# CONFIG_RT_USING_DFS_MQUEUE is not set +# end of DFS: device virtual file system + +# CONFIG_RT_USING_FAL is not set + +# +# Device Drivers +# +# CONFIG_RT_USING_DM is not set +# CONFIG_RT_USING_DEV_BUS is not set +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_UNAMED_PIPE_NUMBER=64 +# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=64 +# CONFIG_RT_USING_SERIAL_BYPASS is not set +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set +# CONFIG_RT_USING_PHY_V2 is not set +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC is not set +# CONFIG_RT_USING_NULL is not set +# CONFIG_RT_USING_ZERO is not set +# CONFIG_RT_USING_RANDOM is not set +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_LCD is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_BLK is not set +# CONFIG_RT_USING_VIRTIO is not set +CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_KTIME is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CHERRYUSB is not set +# end of Device Drivers + +# +# C/C++ and POSIX layer +# + +# +# ISO-ANSI C layer +# + +# +# Timezone and Daylight Saving Time +# +# CONFIG_RT_LIBC_USING_FULL_TZ_DST is not set +CONFIG_RT_LIBC_USING_LIGHT_TZ_DST=y +CONFIG_RT_LIBC_TZ_DEFAULT_HOUR=8 +CONFIG_RT_LIBC_TZ_DEFAULT_MIN=0 +CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0 +# end of Timezone and Daylight Saving Time +# end of ISO-ANSI C layer + +# +# POSIX (Portable Operating System Interface) layer +# +# CONFIG_RT_USING_POSIX_FS is not set +# CONFIG_RT_USING_POSIX_DELAY is not set +# CONFIG_RT_USING_POSIX_CLOCK is not set +# CONFIG_RT_USING_POSIX_TIMER is not set +# CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Interprocess Communication (IPC) +# +# CONFIG_RT_USING_POSIX_PIPE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set + +# +# Socket is in the 'Network' category +# +# end of Interprocess Communication (IPC) +# end of POSIX (Portable Operating System Interface) layer + +# CONFIG_RT_USING_CPLUSPLUS is not set +# end of C/C++ and POSIX layer + +# +# Network +# +# CONFIG_RT_USING_SAL is not set +# CONFIG_RT_USING_NETDEV is not set +# CONFIG_RT_USING_LWIP is not set +# CONFIG_RT_USING_AT is not set +# end of Network + +# +# Memory protection +# +# CONFIG_RT_USING_MEM_PROTECTION is not set +# CONFIG_RT_USING_HW_STACK_GUARD is not set +# end of Memory protection + +# +# Utilities +# +# CONFIG_RT_USING_RYM is not set +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set +# CONFIG_RT_USING_VAR_EXPORT is not set +# CONFIG_RT_USING_RESOURCE_ID is not set +# CONFIG_RT_USING_ADT is not set +# CONFIG_RT_USING_RT_LINK is not set +# end of Utilities + +# CONFIG_RT_USING_VBUS is not set + +# +# Using USB legacy version +# +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set +# end of Using USB legacy version + +# CONFIG_RT_USING_FDT is not set +# end of RT-Thread Components + +# +# RT-Thread Utestcases +# +# CONFIG_RT_USING_UTESTCASES is not set +# end of RT-Thread Utestcases + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_NANOPB is not set +# CONFIG_PKG_USING_WIFI_HOST_DRIVER is not set +# CONFIG_PKG_USING_ESP_HOSTED is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set +# end of Marvell WiFi + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# end of Wiced WiFi + +# CONFIG_PKG_USING_RW007 is not set + +# +# CYW43012 WiFi +# +# CONFIG_PKG_USING_WLAN_CYW43012 is not set +# end of CYW43012 WiFi + +# +# BL808 WiFi +# +# CONFIG_PKG_USING_WLAN_BL808 is not set +# end of BL808 WiFi + +# +# CYW43439 WiFi +# +# CONFIG_PKG_USING_WLAN_CYW43439 is not set +# end of CYW43439 WiFi +# end of Wi-Fi + +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set +# CONFIG_PKG_USING_ZB_COORDINATOR is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_IOTSHARP_SDK is not set +# end of IoT Cloud + +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_BT_CYW43012 is not set +# CONFIG_PKG_USING_CYW43XX is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set +# CONFIG_PKG_USING_RT_LINK_HW is not set +# CONFIG_PKG_USING_RYANMQTT is not set +# CONFIG_PKG_USING_RYANW5500 is not set +# CONFIG_PKG_USING_LORA_PKT_FWD is not set +# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set +# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set +# CONFIG_PKG_USING_HM is not set +# CONFIG_PKG_USING_SMALL_MODBUS is not set +# CONFIG_PKG_USING_NET_SERVER is not set +# CONFIG_PKG_USING_ZFTP is not set +# CONFIG_PKG_USING_WOL is not set +# CONFIG_PKG_USING_ZEPHYR_POLLING is not set +# CONFIG_PKG_USING_MATTER_ADAPTATION_LAYER is not set +# CONFIG_PKG_USING_LHC_MODBUS is not set +# CONFIG_PKG_USING_QMODBUS is not set +# CONFIG_PKG_USING_PNET is not set +# CONFIG_PKG_USING_OPENER is not set +# CONFIG_PKG_USING_FREEMQTT is not set +# end of IoT - internet of things + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_LIBSODIUM is not set +# CONFIG_PKG_USING_LIBHYDROGEN is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set +# end of security packages + +# +# language packages +# + +# +# JSON: JavaScript Object Notation, a lightweight data-interchange format +# +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PARSON is not set +# CONFIG_PKG_USING_RYAN_JSON is not set +# end of JSON: JavaScript Object Notation, a lightweight data-interchange format + +# +# XML: Extensible Markup Language +# +# CONFIG_PKG_USING_SIMPLE_XML is not set +# CONFIG_PKG_USING_EZXML is not set +# end of XML: Extensible Markup Language + +# CONFIG_PKG_USING_LUATOS_SOC is not set +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set +# CONFIG_PKG_USING_PIKASCRIPT is not set +# CONFIG_PKG_USING_RTT_RUST is not set +# end of language packages + +# +# multimedia packages +# + +# +# LVGL: powerful and easy-to-use embedded GUI library +# +# CONFIG_PKG_USING_LVGL is not set +# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set +# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set +# end of LVGL: powerful and easy-to-use embedded GUI library + +# +# u8g2: a monochrome graphic library +# +# CONFIG_PKG_USING_U8G2_OFFICIAL is not set +# CONFIG_PKG_USING_U8G2 is not set +# end of u8g2: a monochrome graphic library + +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set +# CONFIG_PKG_USING_MP3PLAYER is not set +# CONFIG_PKG_USING_TINYJPEG is not set +# CONFIG_PKG_USING_UGUI is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_TERMBOX is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_3GPP_AMRNB is not set +# end of multimedia packages + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_SEGGER_RTT is not set +# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_LOGMGR is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set +# CONFIG_PKG_USING_GAN_ZHI is not set +# CONFIG_PKG_USING_FDT is not set +# CONFIG_PKG_USING_CBOX is not set +# CONFIG_PKG_USING_SNOWFLAKE is not set +# CONFIG_PKG_USING_HASH_MATCH is not set +# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set +# CONFIG_PKG_USING_VOFA_PLUS is not set +# CONFIG_PKG_USING_ZDEBUG is not set +# CONFIG_PKG_USING_RVBACKTRACE is not set +# CONFIG_PKG_USING_HPATCHLITE is not set +# CONFIG_PKG_USING_THREAD_METRIC is not set +# end of tools packages + +# +# system packages +# + +# +# enhanced kernel services +# +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# end of enhanced kernel services + +# CONFIG_PKG_USING_AUNITY is not set + +# +# acceleration: Assembly language or algorithmic acceleration packages +# +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set +# end of acceleration: Assembly language or algorithmic acceleration packages + +# +# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard +# +# CONFIG_PKG_USING_CMSIS_5 is not set +# CONFIG_PKG_USING_CMSIS_CORE is not set +# CONFIG_PKG_USING_CMSIS_NN is not set +# CONFIG_PKG_USING_CMSIS_RTOS1 is not set +# CONFIG_PKG_USING_CMSIS_RTOS2 is not set +# end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# end of Micrium: Micrium software products porting for RT-Thread + +# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set +# CONFIG_PKG_USING_LITEOS_SDK is not set +# CONFIG_PKG_USING_TZ_DATABASE is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_PERF_COUNTER is not set +# CONFIG_PKG_USING_FILEX is not set +# CONFIG_PKG_USING_LEVELX is not set +# CONFIG_PKG_USING_FLASHDB is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_RPMSG_LITE is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set +# CONFIG_PKG_USING_ARM_2D is not set +# CONFIG_PKG_USING_MCUBOOT is not set +# CONFIG_PKG_USING_TINYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set +# CONFIG_PKG_USING_TFDB is not set +# CONFIG_PKG_USING_QPC is not set +# CONFIG_PKG_USING_AGILE_UPGRADE is not set +# CONFIG_PKG_USING_FLASH_BLOB is not set +# CONFIG_PKG_USING_MLIBC is not set +# CONFIG_PKG_USING_TASK_MSG_BUS is not set +# CONFIG_PKG_USING_UART_FRAMEWORK is not set +# CONFIG_PKG_USING_SFDB is not set +# CONFIG_PKG_USING_RTP is not set +# CONFIG_PKG_USING_REB is not set +# CONFIG_PKG_USING_RMP is not set +# CONFIG_PKG_USING_R_RHEALSTONE is not set +# CONFIG_PKG_USING_HEARTBEAT is not set +# CONFIG_PKG_USING_MICRO_ROS_RTTHREAD_PACKAGE is not set +# end of system packages + +# +# peripheral libraries and drivers +# + +# +# HAL & SDK Drivers +# + +# +# STM32 HAL & SDK Drivers +# +# CONFIG_PKG_USING_STM32F0_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F0_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F1_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F1_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F2_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F2_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F3_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F3_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F4_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F7_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F7_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32G0_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32G0_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32G4_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32G4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32H5_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32H5_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32H7_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32H7_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32H7RS_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32H7RS_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32L0_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32L0_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32L4_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32L4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32L5_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32L5_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32U5_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32U5_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_STM32WL_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32WL_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32WB_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32WB_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32MP1_M4_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32MP1_M4_CMSIS_DRIVER is not set +# end of STM32 HAL & SDK Drivers + +# +# Infineon HAL Packages +# +# CONFIG_PKG_USING_INFINEON_CAT1CM0P is not set +# CONFIG_PKG_USING_INFINEON_CMSIS is not set +# CONFIG_PKG_USING_INFINEON_CORE_LIB is not set +# CONFIG_PKG_USING_INFINEON_MTB_HAL_CAT1 is not set +# CONFIG_PKG_USING_INFINEON_MTB_PDL_CAT1 is not set +# CONFIG_PKG_USING_INFINEON_RETARGET_IO is not set +# CONFIG_PKG_USING_INFINEON_CAPSENSE is not set +# CONFIG_PKG_USING_INFINEON_CSDIDAC is not set +# CONFIG_PKG_USING_INFINEON_SERIAL_FLASH is not set +# CONFIG_PKG_USING_INFINEON_USBDEV is not set +# end of Infineon HAL Packages + +# CONFIG_PKG_USING_BLUETRUM_SDK is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_ESP_IDF is not set + +# +# Kendryte SDK +# +# CONFIG_PKG_USING_K210_SDK is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# end of Kendryte SDK + +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set +# CONFIG_PKG_USING_NUCLEI_SDK is not set +# CONFIG_PKG_USING_RASPBERRYPI_PICO_RP2350_SDK is not set +# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set +# CONFIG_PKG_USING_MM32 is not set + +# +# WCH HAL & SDK Drivers +# +# CONFIG_PKG_USING_CH32V20x_SDK is not set +# CONFIG_PKG_USING_CH32V307_SDK is not set +# end of WCH HAL & SDK Drivers + +# +# AT32 HAL & SDK Drivers +# +# CONFIG_PKG_USING_AT32A403A_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32A403A_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32A423_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32A423_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F45x_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F45x_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F402_405_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F402_405_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F403A_407_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F403A_407_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F413_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F413_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F415_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F415_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F421_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F421_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F423_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F423_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F425_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F425_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F435_437_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F435_437_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32M412_416_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32M412_416_CMSIS_DRIVER is not set +# end of AT32 HAL & SDK Drivers + +# +# HC32 DDL Drivers +# +# CONFIG_PKG_USING_HC32F3_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_HC32F3_SERIES_DRIVER is not set +# CONFIG_PKG_USING_HC32F4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_HC32F4_SERIES_DRIVER is not set +# end of HC32 DDL Drivers + +# +# NXP HAL & SDK Drivers +# +# CONFIG_PKG_USING_NXP_MCX_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_NXP_MCX_SERIES_DRIVER is not set +# CONFIG_PKG_USING_NXP_LPC_DRIVER is not set +# CONFIG_PKG_USING_NXP_LPC55S_DRIVER is not set +# CONFIG_PKG_USING_NXP_IMX6SX_DRIVER is not set +# CONFIG_PKG_USING_NXP_IMX6UL_DRIVER is not set +# CONFIG_PKG_USING_NXP_IMXRT_DRIVER is not set +# end of NXP HAL & SDK Drivers + +# +# NUVOTON Drivers +# +# CONFIG_PKG_USING_NUVOTON_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_NUVOTON_SERIES_DRIVER is not set +# CONFIG_PKG_USING_NUVOTON_ARM926_LIB is not set +# end of NUVOTON Drivers + +# +# GD32 Drivers +# +# CONFIG_PKG_USING_GD32_ARM_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_GD32_ARM_SERIES_DRIVER is not set +# end of GD32 Drivers +# end of HAL & SDK Drivers + +# +# sensors drivers +# +# CONFIG_PKG_USING_LSM6DSM is not set +# CONFIG_PKG_USING_LSM6DSL is not set +# CONFIG_PKG_USING_LPS22HB is not set +# CONFIG_PKG_USING_HTS221 is not set +# CONFIG_PKG_USING_LSM303AGR is not set +# CONFIG_PKG_USING_BME280 is not set +# CONFIG_PKG_USING_BME680 is not set +# CONFIG_PKG_USING_BMA400 is not set +# CONFIG_PKG_USING_BMI160_BMX160 is not set +# CONFIG_PKG_USING_SPL0601 is not set +# CONFIG_PKG_USING_MS5805 is not set +# CONFIG_PKG_USING_DA270 is not set +# CONFIG_PKG_USING_DF220 is not set +# CONFIG_PKG_USING_HSHCAL001 is not set +# CONFIG_PKG_USING_BH1750 is not set +# CONFIG_PKG_USING_MPU6XXX is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_TSL4531 is not set +# CONFIG_PKG_USING_DS18B20 is not set +# CONFIG_PKG_USING_DHT11 is not set +# CONFIG_PKG_USING_DHTXX is not set +# CONFIG_PKG_USING_GY271 is not set +# CONFIG_PKG_USING_GP2Y10 is not set +# CONFIG_PKG_USING_SGP30 is not set +# CONFIG_PKG_USING_HDC1000 is not set +# CONFIG_PKG_USING_BMP180 is not set +# CONFIG_PKG_USING_BMP280 is not set +# CONFIG_PKG_USING_SHTC1 is not set +# CONFIG_PKG_USING_BMI088 is not set +# CONFIG_PKG_USING_HMC5883 is not set +# CONFIG_PKG_USING_MAX6675 is not set +# CONFIG_PKG_USING_MAX31855 is not set +# CONFIG_PKG_USING_TMP1075 is not set +# CONFIG_PKG_USING_SR04 is not set +# CONFIG_PKG_USING_CCS811 is not set +# CONFIG_PKG_USING_PMSXX is not set +# CONFIG_PKG_USING_RT3020 is not set +# CONFIG_PKG_USING_MLX90632 is not set +# CONFIG_PKG_USING_MLX90382 is not set +# CONFIG_PKG_USING_MLX90393 is not set +# CONFIG_PKG_USING_MLX90392 is not set +# CONFIG_PKG_USING_MLX90394 is not set +# CONFIG_PKG_USING_MLX90397 is not set +# CONFIG_PKG_USING_MS5611 is not set +# CONFIG_PKG_USING_MAX31865 is not set +# CONFIG_PKG_USING_VL53L0X is not set +# CONFIG_PKG_USING_INA260 is not set +# CONFIG_PKG_USING_MAX30102 is not set +# CONFIG_PKG_USING_INA226 is not set +# CONFIG_PKG_USING_LIS2DH12 is not set +# CONFIG_PKG_USING_HS300X is not set +# CONFIG_PKG_USING_ZMOD4410 is not set +# CONFIG_PKG_USING_ISL29035 is not set +# CONFIG_PKG_USING_MMC3680KJ is not set +# CONFIG_PKG_USING_QMP6989 is not set +# CONFIG_PKG_USING_BALANCE is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_SHT4X is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_ADT74XX is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_STHS34PF80 is not set +# CONFIG_PKG_USING_P3T1755 is not set +# CONFIG_PKG_USING_QMI8658 is not set +# CONFIG_PKG_USING_ICM20948 is not set +# end of sensors drivers + +# +# touch drivers +# +# CONFIG_PKG_USING_GT9147 is not set +# CONFIG_PKG_USING_GT1151 is not set +# CONFIG_PKG_USING_GT917S is not set +# CONFIG_PKG_USING_GT911 is not set +# CONFIG_PKG_USING_FT6206 is not set +# CONFIG_PKG_USING_FT5426 is not set +# CONFIG_PKG_USING_FT6236 is not set +# CONFIG_PKG_USING_XPT2046_TOUCH is not set +# CONFIG_PKG_USING_CST816X is not set +# CONFIG_PKG_USING_CST812T is not set +# end of touch drivers + +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_ILI9341 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_RS232 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set +# CONFIG_PKG_USING_KOBUKI is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_MICRO_ROS is not set +# CONFIG_PKG_USING_MCP23008 is not set +# CONFIG_PKG_USING_MISAKA_AT24CXX is not set +# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set +# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set +# CONFIG_PKG_USING_SOFT_SERIAL is not set +# CONFIG_PKG_USING_MB85RS16 is not set +# CONFIG_PKG_USING_RFM300 is not set +# CONFIG_PKG_USING_IO_INPUT_FILTER is not set +# CONFIG_PKG_USING_LRF_NV7LIDAR is not set +# CONFIG_PKG_USING_AIP650 is not set +# CONFIG_PKG_USING_FINGERPRINT is not set +# CONFIG_PKG_USING_BT_ECB02C is not set +# CONFIG_PKG_USING_UAT is not set +# CONFIG_PKG_USING_ST7789 is not set +# CONFIG_PKG_USING_VS1003 is not set +# CONFIG_PKG_USING_X9555 is not set +# CONFIG_PKG_USING_SYSTEM_RUN_LED is not set +# CONFIG_PKG_USING_BT_MX01 is not set +# CONFIG_PKG_USING_RGPOWER is not set +# CONFIG_PKG_USING_BT_MX02 is not set +# CONFIG_PKG_USING_GC9A01 is not set +# CONFIG_PKG_USING_IK485 is not set +# CONFIG_PKG_USING_SERVO is not set +# CONFIG_PKG_USING_SEAN_WS2812B is not set +# CONFIG_PKG_USING_IC74HC165 is not set +# CONFIG_PKG_USING_IST8310 is not set +# CONFIG_PKG_USING_ST7789_SPI is not set +# CONFIG_PKG_USING_SPI_TOOLS is not set +# end of peripheral libraries and drivers + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set +# CONFIG_PKG_USING_R_TINYMAIX is not set +# CONFIG_PKG_USING_LLMCHAT is not set +# end of AI packages + +# +# Signal Processing and Control Algorithm Packages +# +# CONFIG_PKG_USING_APID is not set +# CONFIG_PKG_USING_FIRE_PID_CURVE is not set +# CONFIG_PKG_USING_QPID is not set +# CONFIG_PKG_USING_UKAL is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_KISSFFT is not set +# end of Signal Processing and Control Algorithm Packages + +# +# miscellaneous packages +# + +# +# project laboratory +# +# end of project laboratory + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set +# end of samples: kernel and components samples + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_CMATRIX is not set +# CONFIG_PKG_USING_SL is not set +# CONFIG_PKG_USING_CAL is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_COWSAY is not set +# CONFIG_PKG_USING_MORSE is not set +# end of entertainment: terminal games and other interesting software packages + +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set +# CONFIG_PKG_USING_RALARAM is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_CRCLIB is not set +# CONFIG_PKG_USING_LIBCRC is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_DESIGN_PATTERN is not set +# CONFIG_PKG_USING_CONTROLLER is not set +# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set +# CONFIG_PKG_USING_SLCAN2RTT is not set +# CONFIG_PKG_USING_SOEM is not set +# CONFIG_PKG_USING_QPARAM is not set +# CONFIG_PKG_USING_CorevMCU_CLI is not set +# CONFIG_PKG_USING_DRMP is not set +# end of miscellaneous packages + +# +# Arduino libraries +# +# CONFIG_PKG_USING_RTDUINO is not set + +# +# Projects and Demos +# +# CONFIG_PKG_USING_ARDUINO_MSGQ_C_CPP_DEMO is not set +# CONFIG_PKG_USING_ARDUINO_SKETCH_LOADER_DEMO is not set +# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set +# CONFIG_PKG_USING_ARDUINO_RTDUINO_SENSORFUSION_SHIELD is not set +# CONFIG_PKG_USING_ARDUINO_NINEINONE_SENSOR_SHIELD is not set +# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set +# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set +# end of Projects and Demos + +# +# Sensors +# +# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31855 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MSA301 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ITG3200 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MP503 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set +# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_JARZEBSKI_MPU6050 is not set +# end of Sensors + +# +# Display +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_GFX_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_U8G2 is not set +# CONFIG_PKG_USING_ARDUINO_TFT_ESPI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ST7735 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SSD1306 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ILI9341 is not set +# CONFIG_PKG_USING_SEEED_TM1637 is not set +# end of Display + +# +# Timing +# +# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set +# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set +# CONFIG_PKG_USING_ARDUINO_TICKER is not set +# CONFIG_PKG_USING_ARDUINO_TASKSCHEDULER is not set +# end of Timing + +# +# Data Processing +# +# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set +# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set +# CONFIG_PKG_USING_ARDUINO_TENSORFLOW_LITE_MICRO is not set +# CONFIG_PKG_USING_ARDUINO_RUNNINGMEDIAN is not set +# end of Data Processing + +# +# Data Storage +# + +# +# Communication +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set +# end of Communication + +# +# Device Control +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set +# end of Device Control + +# +# Other +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set +# end of Other + +# +# Signal IO +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set +# end of Signal IO + +# +# Uncategorized +# +# end of Arduino libraries +# end of RT-Thread online packages + +# +# Hardware Drivers Config +# +CONFIG_SOC_XUANTIE=y + +# +# On-chip Peripheral Drivers +# +CONFIG_BSP_USING_UART=y +CONFIG_BSP_USING_UART0=y +# CONFIG_ENABLE_FPU is not set +# end of On-chip Peripheral Drivers +# end of Hardware Drivers Config diff --git a/bsp/xuantie/smartl/e901/.cproject b/bsp/xuantie/smartl/e901/.cproject new file mode 100644 index 00000000000..d69a2d0740c --- /dev/null +++ b/bsp/xuantie/smartl/e901/.cproject @@ -0,0 +1,929 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/xuantie/smartl/e901/.project b/bsp/xuantie/smartl/e901/.project new file mode 100644 index 00000000000..c7455faa7a8 --- /dev/null +++ b/bsp/xuantie/smartl/e901/.project @@ -0,0 +1,27 @@ + + + project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + diff --git a/bsp/xuantie/smartl/e901/.settings/org.eclipse.core.runtime.prefs b/bsp/xuantie/smartl/e901/.settings/org.eclipse.core.runtime.prefs new file mode 100644 index 00000000000..9f1acfcfba2 --- /dev/null +++ b/bsp/xuantie/smartl/e901/.settings/org.eclipse.core.runtime.prefs @@ -0,0 +1,3 @@ +content-types/enabled=true +content-types/org.eclipse.cdt.core.asmSource/file-extensions=s +eclipse.preferences.version=1 \ No newline at end of file diff --git a/bsp/xuantie/smartl/e901/.settings/projcfg.ini b/bsp/xuantie/smartl/e901/.settings/projcfg.ini new file mode 100644 index 00000000000..81d9ee44ab2 --- /dev/null +++ b/bsp/xuantie/smartl/e901/.settings/projcfg.ini @@ -0,0 +1,20 @@ +#RT-Thread Studio Project Configuration +# Mon Sep 22 13:30:04 2025 +cfg_version=v3.0 + +board_name= +bsp_version= +bsp_path= +chip_name= +project_base_rtt_bsp=true +is_use_scons_build=true +hardware_adapter= +selected_rtt_version=latest +board_base_nano_proj=false +is_base_example_project=false +example_name= +project_type=rt-thread +os_branch=master +os_version=latest +project_name=project +output_project_path=E:\rt-thread\bsp\xuantie\smartl\e902 \ No newline at end of file diff --git a/bsp/xuantie/smartl/e901/Kconfig b/bsp/xuantie/smartl/e901/Kconfig new file mode 100644 index 00000000000..9ed6a6ffd8c --- /dev/null +++ b/bsp/xuantie/smartl/e901/Kconfig @@ -0,0 +1,18 @@ +mainmenu "RT-Thread Configuration" + +BSP_DIR := . + +RTT_DIR := ../../../../ + +PKGS_DIR := packages + +config XUANTIAN_SMARTL_E901 + bool + select ARCH_RISCV32 + select RT_USING_COMPONENTS_INIT + select RT_USING_USER_MAIN + default y + +source "$(RTT_DIR)/Kconfig" +source "$PKGS_DIR/Kconfig" +source "$BSP_DIR/board/Kconfig" diff --git a/bsp/xuantie/smartl/e901/README.md b/bsp/xuantie/smartl/e901/README.md new file mode 100644 index 00000000000..bc39ba4e101 --- /dev/null +++ b/bsp/xuantie/smartl/e901/README.md @@ -0,0 +1,100 @@ +# XuanTie - E901 Series + +## 一 简介 + +### 1. 内核 + +玄铁 E901+ 是基于 RISC-V 指令架构的低成本、高能效的 32 位嵌入式 CPU 处理器,用户可以以近似 8 位CPU 的成本获得 32 位嵌入式处理器的效率与性能。E901+ 处理器兼容 RV32E[M] [B]_Zc 指令架构,采用 16/32 位混合编码系统,指令系统与流水线硬件结构精简高效。同时支持配置协处理器接口,用于满足用户 DSA(Domain Specific Accelerator)需求,加速特定应用执行,并支持用户进行自定义指令扩展。 + +E901+ 主要针对智能卡、智能电网、低成本微控制器、无线传感网络等嵌入式应用。 + +### 2.特点 + +E902 处理器体系结构的主要特点如下: + +E901+ 处理器体系结构的主要特点如下: + +• 支持 RV32E [M] [B]_Zc 指令集 + +• 16 个 32 位通用寄存器 + +• 两级顺序执行流水线 + +• 支持 RISC-V 机器模式和用户模式 + +• 支持 RISC-V Debug 架构,支持标准五线 JTAG 调试接口,支持 CJTAG 两线调试接口 + +• 支持以下硬件乘/除法器配置: + +**–** 不配置硬件乘/除法器 + +**–** 配置单周期快速硬件乘法器,以及多周期(1-33)慢速硬件除法器 + +**–** 配置多周期(3-33)慢速硬件乘法器,以及多周期(1-33)慢速硬件除法器 + +• 兼容 RISC-V CLIC 中断标准,支持中断优先级可配置,支持中断嵌套和中断咬尾 + +• 外部中断源数量最高可配置为 112 个 + +• 兼容 RISC-V PMP 内存保护标准,0/2/4/8/16 区域可配置 + +• 支持指令总线和系统总线,指令总线支持 AHB-Lite(即 AHB 3.0)协议,系统总线协议支持 AHB 2.0 + +和 AHB-Lite + +• 支持指令高速缓存,缓存行 16 字节,容量 2KiB/4KiB/8KiB 可配 + +• 支持玄铁扩展编程模型 + +• 支持复位启动地址硬件集成时可配置 + +• 支持软复位操作 + +• 支持协处理器接口可配置 + +### 3.BSP支持情况 + +- 当前BSP支持下述内核: + + ```asciiarmor + e901plusbm-cp + ``` + +- 当前BSP默认设置的内核是e901plusbm-cp。 + +- 当使用其他内核架构时需要修改,rtconfig.py文件中的`MCPU`字段。 + +### 4.运行QEMU + +- BSP根目录下存在`qemu.bat`脚本,生成可执行文件后可点击该脚本直接启动QEMU. + +## 二 工具 + +- 编译器: https://www.xrvm.cn/community/download?id=4433353576298909696 +- 模拟器: https://www.xrvm.cn/community/download?id=4397435198627713024 + +注:若上述链接中的编译器与模拟器不能使用,可以使用下述CDK中的编译器与模拟器 + +- SDK:https://www.xrvm.cn/community/download?id=4397799570420076544 + +## 三 调试方法 + +**下述调试方法以E902举例,本BSP操作方式一致**,搭建完成RT-Thread开发环境,在BSP根目录使用env工具在当前目录打开env。 + +![](figures/1.env.png) + +使用前执行一次**menuconfig**命令,更新rtconfig.h配置,然后在当前目录执行**scons -j12**命令编译生成可可执行文件。 + +env + +生成可执行文件,可以直接在命令行启动qemu或者配置vscode脚本借助vscode强大的插件进行图形化调试,qemu的相关命令可以查看玄铁qemu的[用户手册](https://www.xrvm.cn/community/download?id=4397435198627713024),下述是启动qemu的命令,在powershell或命令行可直接执行下述命令,注意qemu需要导出至环境变量或者使用绝对路径。 + +```shell +qemu-system-riscv64 -machine smartl -nographic -kernel rtthread.elf -cpu e906 +``` + +下述是使用vscode调试的展示。 + +env + +一起为RISC-V加油! \ No newline at end of file diff --git a/bsp/xuantie/smartl/e901/SConscript b/bsp/xuantie/smartl/e901/SConscript new file mode 100644 index 00000000000..27c6c5f6358 --- /dev/null +++ b/bsp/xuantie/smartl/e901/SConscript @@ -0,0 +1,19 @@ +# for module compiling +import os +Import('RTT_ROOT') +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for item in list: + path = os.path.join(cwd, item) + if item == 'libraries' or not os.path.isdir(path): + continue + + sconscript_path = os.path.join(path, 'SConscript') + if os.path.isfile(sconscript_path): + objs.extend(SConscript(os.path.join(item, 'SConscript'))) + +Return('objs') diff --git a/bsp/xuantie/smartl/e901/SConstruct b/bsp/xuantie/smartl/e901/SConstruct new file mode 100644 index 00000000000..e26afa61dc9 --- /dev/null +++ b/bsp/xuantie/smartl/e901/SConstruct @@ -0,0 +1,54 @@ +import os +import sys +import rtconfig +from SCons.Script import * + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../../../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] + +try: + from building import * +except: + print('Cannot found RT-Thread root directory, please check RTT_ROOT') + print(RTT_ROOT) + exit(-1) + +TARGET = 'rtthread.' + rtconfig.TARGET_EXT + +DefaultEnvironment(tools=[]) +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +Export('RTT_ROOT') +Export('rtconfig') + +SDK_ROOT = os.path.abspath('./') + +if os.path.exists(SDK_ROOT + '/libraries'): + libraries_path_prefix = SDK_ROOT + '../libraries' +else: + libraries_path_prefix = os.path.dirname(SDK_ROOT) + '/../libraries' + +SDK_LIB = libraries_path_prefix +Export('SDK_LIB') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) + +bsp_vdir = 'build' +library_vdir = 'build/libraries' + +# common include drivers +objs.extend(SConscript(os.path.join(libraries_path_prefix, 'SConscript'), variant_dir=library_vdir, duplicate=0)) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/xuantie/smartl/e901/applications/SConscript b/bsp/xuantie/smartl/e901/applications/SConscript new file mode 100644 index 00000000000..f129b326245 --- /dev/null +++ b/bsp/xuantie/smartl/e901/applications/SConscript @@ -0,0 +1,10 @@ +from building import * +import os + +cwd = GetCurrentDir() +CPPPATH = [cwd] +src = ['main.c'] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/xuantie/smartl/e901/applications/main.c b/bsp/xuantie/smartl/e901/applications/main.c new file mode 100644 index 00000000000..a4b2294b7c3 --- /dev/null +++ b/bsp/xuantie/smartl/e901/applications/main.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2006-2025, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2025-04-21 Wangshun first version + */ + +#include +#include +#include "pre_main.h" + +int main(void) +{ + rt_kprintf("Hello RT-Thread!\r\n"); +} + diff --git a/bsp/xuantie/smartl/e901/board/Kconfig b/bsp/xuantie/smartl/e901/board/Kconfig new file mode 100644 index 00000000000..6abf0d16f47 --- /dev/null +++ b/bsp/xuantie/smartl/e901/board/Kconfig @@ -0,0 +1,30 @@ +menu "Hardware Drivers Config" + +config SOC_XUANTIE + bool + select RT_USING_COMPONENTS_INIT + select RT_USING_USER_MAIN + default y + + +menu "On-chip Peripheral Drivers" + + menuconfig BSP_USING_UART + bool "Enable UART" + select RT_USING_SERIAL + default n + + if BSP_USING_UART + config BSP_USING_UART0 + bool "Enable UART0" + default n + endif + + menuconfig ENABLE_FPU + bool "Enable FPU" + select ARCH_RISCV_FPU + default n + +endmenu + +endmenu diff --git a/bsp/xuantie/smartl/e901/board/SConscript b/bsp/xuantie/smartl/e901/board/SConscript new file mode 100644 index 00000000000..a8088a7c1f5 --- /dev/null +++ b/bsp/xuantie/smartl/e901/board/SConscript @@ -0,0 +1,33 @@ +import os +import rtconfig +from building import * + +Import('SDK_LIB') + +cwd = GetCurrentDir() + +# add general drivers +src = ['board.c'] + +path = [cwd] + +CPPDEFINES = [ + 'CONFIG_KERNEL_RTTHREAD=1', + '__RT_KERNEL_SOURCE__=1', + 'CONFIG_CSI_V2=1', + 'CONFIG_CSI=csi2', + 'CONFIG_INIT_TASK_STACK_SIZE=4096', + 'CONFIG_APP_TASK_STACK_SIZE=8192', + 'CONFIG_ARCH_MAINSTACK=4096', + 'CONFIG_ARCH_INTERRUPTSTACK=4096', + 'CONFIG_XIP=1', + 'CONFIG_LIBC_MINI_PRINTF_SUPPORT=1', + 'CONFIG_SYSTICK_HZ=100', + 'CONFIG_BOARD_SMARTL_EVB=1', + 'CONFIG_DEBUG=1', + 'CLI_CONFIG_STACK_SIZE=4096', + 'CONFIG_CPU_XUANTIE_E901PLUS_BM_CP=1', +] + +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) +Return('group') diff --git a/bsp/xuantie/smartl/e901/board/board.c b/bsp/xuantie/smartl/e901/board/board.c new file mode 100644 index 00000000000..e6dc93acdfa --- /dev/null +++ b/bsp/xuantie/smartl/e901/board/board.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2006-2025, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2025-04-23 Wangshun first version + */ + +#include +#include +#include +#include + +extern unsigned long __heap_start; +extern unsigned long __heap_end; + +/** + * This function will initialize your board. + */ +void rt_hw_board_init() +{ + rt_hw_interrupt_init(); + +#ifdef RT_USING_HEAP + rt_system_heap_init((void *)&__heap_start, (void *)&__heap_end); +#endif + +#ifdef BSP_USING_UART + rt_hw_usart_init(); +#endif + +#ifdef RT_USING_CONSOLE + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif + +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif +} + diff --git a/bsp/xuantie/smartl/e901/board/board.h b/bsp/xuantie/smartl/e901/board/board.h new file mode 100644 index 00000000000..39c3300936e --- /dev/null +++ b/bsp/xuantie/smartl/e901/board/board.h @@ -0,0 +1,443 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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. + */ + +/* + This is an example board.h for Board Compment, New Board should flow the macro defines. +*/ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Common Board Features Define */ + +/* + The Common BOARD_XXX Macro Defines Boards supported features which may reference by Solutions. + Common board macro include: + . BOARD_NAME + · UART + · GPIO + · PWM + · ADC + · BUTTON + · LED + · WIFI + · BT + · AUDIO + BOARD_XXX Macro descripted below should be defined if the board support. +*/ + +/****************************************************************************/ + +/* + This riscv dummy board include: + · UART x1 + · GPIO x2 + · PWM x2 + · ADC x1 + · BUTTON x2 + · LED x2 + · WIFI x0 + · BT x0 + · AUDIO x1 +*/ + +#ifndef CONFIG_BOARD_UART +#define CONFIG_BOARD_UART 1 +#endif + +#ifndef CONFIG_BOARD_GPIO +#define CONFIG_BOARD_GPIO 0 +#endif + +#ifndef CONFIG_BOARD_PWM +#define CONFIG_BOARD_PWM 0 +#endif + +#ifndef CONFIG_BOARD_ADC +#define CONFIG_BOARD_ADC 0 +#endif + +#ifndef CONFIG_BOARD_BUTTON +#define CONFIG_BOARD_BUTTON 0 +#endif + +#ifndef CONFIG_BOARD_LED +#define CONFIG_BOARD_LED 0 +#endif + +#ifndef CONFIG_BOARD_WIFI +#define CONFIG_BOARD_WIFI 0 +#endif + +#ifndef CONFIG_BOARD_BT +#define CONFIG_BOARD_BT 0 +#endif + +#ifndef CONFIG_BOARD_AUDIO +#define CONFIG_BOARD_AUDIO 0 +#endif + +#define BOARD_NAME "RISCV_DUMMY" + +/* the board pins, can be used as uart, gpio, pwd... */ +#define BOARD_PIN0 (0) +#define BOARD_PIN1 (1) +#define BOARD_PIN2 (2) +#define BOARD_PIN3 (3) +#define BOARD_PIN4 (4) +#define BOARD_PIN5 (5) +#define BOARD_PIN6 (6) +#define BOARD_PIN7 (7) +#define BOARD_PIN8 (8) +#define BOARD_PIN9 (9) +#define BOARD_PIN10 (10) +#define BOARD_PIN11 (11) +#define BOARD_PIN12 (12) +/* ... */ + +#if defined(CONFIG_BOARD_UART) && CONFIG_BOARD_UART +/* UART */ + +/* + The total supported uart numbers on this board, 0 meas No uart support. + the BOARD_UART_XXX, x in rang of (0, BOARD_UART_NUM - 1) +*/ +#ifndef BOARD_UART_NUM +#define BOARD_UART_NUM (1) +#endif + +#if defined(BOARD_UART_NUM) && BOARD_UART_NUM > 0 +/* the board uart0 tx pin */ +#define BOARD_UART0_TX_PIN (BOARD_PIN0) +/* the borad uart0 rx pin */ +#define BOARD_UART0_RX_PIN (BOARD_PIN1) +/* The real UART port reference to board logic port 0 */ +#define BOARD_UART0_IDX (0) +/* The default baudrate for uart0 */ +#define BOARD_UART0_BAUD (115200) + +/* #define BOARD_UART1_IDX (1) */ +/* #define BOARD_UART1_BAUD (115200) */ +/* ... */ +#endif /* defined(BOARD_UART_NUM) && BOARD_UART_NUM > 0 */ + +#endif /* defined(CONFIG_BOARD_UART) && CONFIG_BOARD_UART */ + +#if defined(CONFIG_BOARD_GPIO) && CONFIG_BOARD_GPIO +/* GPIO */ +/* + The total supported GPIO Pin numbers on this board, 0 meas No uart support. + the BOARD_GPIO_PIN, x in rang of (0, BOARD_GPIO_PIN_NUM - 1) +*/ +#ifndef BOARD_GPIO_PIN_NUM +#define BOARD_GPIO_PIN_NUM (2) +#endif + +#if defined(BOARD_GPIO_PIN_NUM) && BOARD_GPIO_PIN_NUM > 0 +/* The real gpio reference to board logic gpio pin */ +#define BOARD_GPIO_PIN0 (BOARD_PIN2) +#define BOARD_GPIO_PIN1 (BOARD_PIN3) +/* #define BOARD_GPIO_PIN2 (x) */ +/* #define BOARD_GPIO_PIN3 (x) */ +#endif /* defined(BOARD_GPIO_PIN_NUM) && BOARD_GPIO_PIN_NUM > 0 */ +#endif /* defined(CONFIG_BOARD_GPIO) && CONFIG_BOARD_GPIO */ + +#if defined(CONFIG_BOARD_PWM) && CONFIG_BOARD_PWM +/* PWM */ +/* the board supported pwm channels */ +#ifndef BOARD_PWM_NUM +#define BOARD_PWM_NUM (2) +#endif + +#if defined(BOARD_PWM_NUM) && BOARD_PWM_NUM > 0 +/* the board pwm pin */ +#define BOARD_PWM0_PIN (BOARD_PIN4) +/* The real pwm channel reference to board logic pwm channel */ +#define BOARD_PWM0_CH (0) + +#define BOARD_PWM1_PIN (BOARD_PIN5) +#define BOARD_PWM1_CH (1) +#endif /* defined(BOARD_PWM_NUM) && BOARD_PWM_NUM > 0 */ +#endif /* defined(CONFIG_BOARD_PWM) && CONFIG_BOARD_PWM */ + +#if defined(CONFIG_BOARD_ADC) && CONFIG_BOARD_ADC > 0 +/* ADC */ +/* the board supported adc channels */ +#ifndef BOARD_ADC_NUM +#define BOARD_ADC_NUM (1) +#endif + +#if defined(BOARD_ADC_NUM) && BOARD_ADC_NUM > 0 +/* the board adc pin */ +#define BOARD_ADC0_PIN (BOARD_PIN6) +/* The real adc channel reference to board logic adc channel */ +#define BOARD_ADC0_CH (0) +#endif /* defined(BOARD_ADC_NUM) && BOARD_ADC_NUM > 0 */ +#endif /* defined(CONFIG_BOARD_ADC) && CONFIG_BOARD_ADC > 0 */ + +#if defined(CONFIG_BOARD_BUTTON) && CONFIG_BOARD_BUTTON > 0 +/* BUTTON */ +#ifndef BOARD_BUTTON_NUM +/* + the board supported buttons, include gpio button and adc button, + BOARD_BUTTON_NUM = BOARD_BUTTON_GPIO_NUM + BOARD_BUTTON_ADC_NUM. + +*/ +#define BOARD_BUTTON_NUM (4) +#endif + +#if defined(BOARD_BUTTON_NUM) && BOARD_BUTTON_NUM > 0 + +#define BOARD_BUTTON0_PIN (BOARD_PIN7) +#define BOARD_BUTTON1_PIN (BOARD_PIN8) +#define BOARD_BUTTON2_PIN (BOARD_PIN9) +#define BOARD_BUTTON3_PIN (BOARD_PIN10) + +/* GPIO BUTTON */ +/* the board supported GPIO Buttons */ +#ifndef BOARD_BUTTON_GPIO_NUM +#define BOARD_BUTTON_GPIO_NUM (2) +#endif + +#if defined(BOARD_BUTTON_GPIO_NUM) && BOARD_BUTTON_GPIO_NUM > 0 +/* the board logic button id, in range of (0, BOARD_BUTTON_GPIO_NUM - 1) */ +#define BOARD_BUTTON0 (0) +/* for gpio button, define the pin numner. if the gpio pin used as gpio button, it shoudn't reference as BOARD_GPIO_PINx + */ +#define BOARD_BUTTON0_GPIO_PIN (BOARD_BUTTON0_PIN) + +#define BOARD_BUTTON1 (1) +#define BOARD_BUTTON1_GPIO_PIN (BOARD_BUTTON1_PIN) +#endif /* defined(BOARD_BUTTON_GPIO_NUM) && BOARD_BUTTON_GPIO_NUM > 0 */ + +/* ADC BUTTON */ +/* the board supported adc Buttons */ +#ifndef BOARD_BUTTON_ADC_NUM +#define BOARD_BUTTON_ADC_NUM (2) +#endif + +#if defined(BOARD_BUTTON_ADC_NUM) && BOARD_BUTTON_ADC_NUM > 0 +/* the board logic adc button id, in range of (BOARD_BUTTON_GPIO_NUM, BOARD_BUTTON_NUM - 1), if not suuport GPIO Button, + * BOARD_BUTTON_GPIO_NUM should be 0 */ +#define BOARD_BUTTON2 (BOARD_BUTTON_GPIO_NUM + 0) +#define BOARD_BUTTON2_ADC_PIN (BOARD_BUTTON2_PIN) +/* the adc channel used for button2, if the adc channel used as adc button, it shoudn't reference as BOARD_ADCx_CH*/ +#define BOARD_BUTTON2_ADC_CH (1) +/* the adc device name */ +#define BOARD_BUTTON2_ADC_NAME "adc1" +/* adc voltage reference */ +#define BOARD_BUTTON2_ADC_REF (100) +/* adc voltage range */ +#define BOARD_BUTTON2_ADC_RANG (500) + +#define BOARD_BUTTON3 (BOARD_BUTTON_GPIO_NUM + 1) +#define BOARD_BUTTON3_ADC_PIN (BOARD_BUTTON3_PIN) +#define BOARD_BUTTON3_ADC_CH (1) +#define BOARD_BUTTON3_ADC_NAME "adc1" +#define BOARD_BUTTON3_ADC_REF (600) +#define BOARD_BUTTON3_ADC_RANG (500) + +/* #define BOARD_ADC_BUTTON2 (2) */ +/* #define BOARD_ADC_BUTTON2_CH (1) */ +/* #define BOARD_ADC_BUTTON2_NAME "adc1" */ +/* #define BOARD_ADC_BUTTON2_REF xxx */ +/* #define BOARD_ADC_BUTTON2_RANG xxx */ +#endif /* defined(BOARD_BUTTON_ADC_NUM) && BOARD_BUTTON_ADC_NUM > 0 */ + +#endif /* defined(BOARD_BUTTON_NUM) && BOARD_BUTTON_NUM > 0 */ + +#endif /* defined(BOARD_BUTTON_NUM) && BOARD_BUTTON_NUM > 0 */ + +#if defined(CONFIG_BOARD_LED) && CONFIG_BOARD_LED > 0 +/* LED */ +/* the board supported leds */ +#ifndef BOARD_LED_NUM +#define BOARD_LED_NUM (2) +#endif + +#define BOARD_LED0_PIN BOARD_PIN11 +#define BOARD_LED1_PIN BOARD_PIN12 + +/* PWM LED */ +/* the board supported pwm leds */ +#ifndef BOARD_LED_PWM_NUM +#define BOARD_LED_PWM_NUM (1) +#endif + +#if defined(BOARD_LED_PWM_NUM) && BOARD_LED_PWM_NUM > 0 +#define BOARD_LED0_PWM_PIN (BOARD_LED0_PIN) +/* the pwm channel used for led0, if the pwm channel used as led0, it shoudn't reference as BOARD_PWMx_CH */ +#define BOARD_LED0_PWM_CH (0) +#endif /* defined(BOARD_LED_PWM_NUM) && BOARD_LED_PWM_NUM > 0 */ + +/* GPIO LED */ +#ifndef BOARD_LED_GPIO_NUM +#define BOARD_LED_GPIO_NUM (1) +#endif + +#if defined(BOARD_LED_GPIO_NUM) && BOARD_LED_GPIO_NUM > 0 +/* the gpio pin used for led0, if the gpio pin used as led, it shoudn't reference as BOARD_GPIO_PINx */ +#define BOARD_LED1_GPIO_PIN (BOARD_LED1_PIN) +#endif /* defined(BOARD_LED_GPIO_NUM) && BOARD_LED_GPIO_NUM > 0 */ +#endif /* defined(CONFIG_BOARD_LED) && CONFIG_BOARD_LED > 0 */ + +#if defined(CONFIG_BOARD_BT) && CONFIG_BOARD_BT > 0 +/* BT */ +/* the board support bluetooth */ +#ifndef BOARD_BT_SUPPORT +#define BOARD_BT_SUPPORT 1 +#endif +#endif /* defined(CONFIG_BOARD_BT) && CONFIG_BOARD_BT > 0 */ + +#if defined(CONFIG_BOARD_WIFI) && CONFIG_BOARD_WIFI > 0 +/* WIFI */ +/* the board support wifi */ +#ifndef BOARD_WIFI_SUPPORT +#define BOARD_WIFI_SUPPORT 1 +#endif +#endif /* defined(CONFIG_BOARD_WIFI) && CONFIG_BOARD_WIFI > 0 */ + +#if defined(CONFIG_BOARD_AUDIO) && CONFIG_BOARD_AUDIO > 0 +/* Audio */ +/* the board support audio */ +#ifndef BOARD_AUDIO_SUPPORT +#define BOARD_AUDIO_SUPPORT 1 +#endif +#endif /* defined(CONFIG_BOARD_AUDIO) && CONFIG_BOARD_AUDIO > 0 */ + +/****************************************************************************/ +/* Common solutions defines */ + +/* Console config, Almost all solutions and demos use these. */ +#ifndef CONSOLE_UART_IDX +#define CONSOLE_UART_IDX (BOARD_UART0_IDX) +#endif + +#ifndef CONFIG_CLI_USART_BAUD +#define CONFIG_CLI_USART_BAUD (BOARD_UART0_BAUD) +#endif + +#ifndef CONFIG_CONSOLE_UART_BUFSIZE +#define CONFIG_CONSOLE_UART_BUFSIZE (128) +#endif + +/****************************************************************************/ +/* Commom test demos defines */ + +/* i2c */ +#define EXAMPLE_IIC_IDX 0 /* 1 */ +#define EXAMPLE_PIN_IIC_SDA 0 /* PC1 */ +#define EXAMPLE_PIN_IIC_SCL 0 /* PC0 */ +#define EXAMPLE_PIN_IIC_SDA_FUNC 0 /* PC1_I2C1_SDA */ +#define EXAMPLE_PIN_IIC_SCL_FUNC 0 /* PC0_I2C1_SCL */ + +/* adc */ +#define EXAMPLE_ADC_CH0 0 /* PA8 */ +#define EXAMPLE_ADC_CH0_FUNC 0 /* PA8_ADC_A0 */ +#define EXAMPLE_ADC_CH12 0 /* PA26 */ +#define EXAMPLE_ADC_CH12_FUNC 0 /* PA26_ADC_A12 */ + +/****************************************************************************/ +/* Vendor board defines */ + +/* other board specific defines */ +/* #define CUSTOM_BOARD_xxx */ + +/****************************************************************************/ +/** + * @brief init the board for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_init(void); + +/** + * @brief init the board gpio pin for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_gpio_pin_init(void); + +/** + * @brief init the board uart for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_uart_init(void); + +/** + * @brief init the board pwm for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_pwm_init(void); + +/** + * @brief init the board adc for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_adc_init(void); + +/** + * @brief init the board button for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_button_init(void); + +/** + * @brief init the board led for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_led_init(void); + +/** + * @brief init the board wifi for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_wifi_init(void); + +/** + * @brief init the board bt for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_bt_init(void); + +/** + * @brief init the board audio for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_audio_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __BOARD_H__ */ + diff --git a/bsp/xuantie/smartl/e901/figures/1.env.png b/bsp/xuantie/smartl/e901/figures/1.env.png new file mode 100644 index 0000000000000000000000000000000000000000..64f009ee845922e7c387653570c947a586828e15 GIT binary patch literal 27810 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 literal 0 HcmV?d00001 diff --git a/bsp/xuantie/smartl/e901/figures/3.vscode.png b/bsp/xuantie/smartl/e901/figures/3.vscode.png new file mode 100644 index 0000000000000000000000000000000000000000..21c9b1be8902bb206a88aec49b6b721df66518e6 GIT binary patch literal 168160 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