diff --git a/boards/arm/mimxrt595_evk/doc/index.rst b/boards/arm/mimxrt595_evk/doc/index.rst index 61ed427858a101..a82735ba2782ea 100644 --- a/boards/arm/mimxrt595_evk/doc/index.rst +++ b/boards/arm/mimxrt595_evk/doc/index.rst @@ -174,6 +174,20 @@ Serial Port The MIMXRT595 SoC has 13 FLEXCOMM interfaces for serial communication. One is configured as USART for the console and the remaining are not used. +Fusion F1 DSP Core +================== + +You can build a Zephyr application for the RT500 DSP core using nxp_adsp_rt595 +board. Xtensa toolchain supporting RT500 DSP core is included in Zephyr SDK. +To build the hello_world sample for the RT500 DSP core: + +.. code-block:: shell + + $ west build -b nxp_adsp_rt595 samples/hello_world + +For detailed instructions on how to debug DSP firmware, please refer to +this document: `Getting Started with Xplorer for EVK-MIMXRT595`_ + Programming and Debugging ************************* @@ -313,3 +327,6 @@ steps: .. _i.MX RT595 Reference Manual: https://www.nxp.com/webapp/Download?colCode=IMXRT500RM + +.. _Getting Started with Xplorer for EVK-MIMXRT595: + https://www.nxp.com/docs/en/supporting-information/GSXEVKMIMXRT595.pdf diff --git a/boards/xtensa/nxp_adsp_rt595/Kconfig b/boards/xtensa/nxp_adsp_rt595/Kconfig new file mode 100644 index 00000000000000..3c787188a9b017 --- /dev/null +++ b/boards/xtensa/nxp_adsp_rt595/Kconfig @@ -0,0 +1,41 @@ +# Copyright (c) 2023 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +DT_ADSP_RESET_MEM := $(dt_nodelabel_path,adsp_reset) +DT_ADSP_DATA_MEM := $(dt_nodelabel_path,adsp_data) +DT_ADSP_TEXT_MEM := $(dt_nodelabel_path,adsp_text) + +if BOARD_NXP_ADSP_RT595 + +config RT595_ADSP_STACK_SIZE + hex "Boot time stack size" + default 0x1000 + help + Stack space is reserved at the end of the RT595_ADSP_DATA_MEM + region, starting at RT595_ADSP_DATA_MEM_ADDR - RT595_ADSP_STACK_SIZE + +config RT595_ADSP_RESET_MEM_ADDR + hex + default $(dt_node_reg_addr_hex,$(DT_ADSP_RESET_MEM)) + +config RT595_ADSP_RESET_MEM_SIZE + hex + default $(dt_node_reg_size_hex,$(DT_ADSP_RESET_MEM)) + +config RT595_ADSP_DATA_MEM_ADDR + hex + default $(dt_node_reg_addr_hex,$(DT_ADSP_DATA_MEM)) + +config RT595_ADSP_DATA_MEM_SIZE + hex + default $(dt_node_reg_size_hex,$(DT_ADSP_DATA_MEM)) + +config RT595_ADSP_TEXT_MEM_ADDR + hex + default $(dt_node_reg_addr_hex,$(DT_ADSP_TEXT_MEM)) + +config RT595_ADSP_TEXT_MEM_SIZE + hex + default $(dt_node_reg_size_hex,$(DT_ADSP_TEXT_MEM)) + +endif # BOARD_NXP_ADSP_RT595 diff --git a/boards/xtensa/nxp_adsp_rt595/Kconfig.board b/boards/xtensa/nxp_adsp_rt595/Kconfig.board new file mode 100644 index 00000000000000..a88eb58638fe61 --- /dev/null +++ b/boards/xtensa/nxp_adsp_rt595/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NXP_ADSP_RT595 + bool "NXP ADSP RT595" + depends on SOC_SERIES_NXP_RT5XX diff --git a/boards/xtensa/nxp_adsp_rt595/Kconfig.defconfig b/boards/xtensa/nxp_adsp_rt595/Kconfig.defconfig new file mode 100644 index 00000000000000..7ffe782d28b288 --- /dev/null +++ b/boards/xtensa/nxp_adsp_rt595/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NXP_ADSP_RT595 + +config BOARD + default "nxp_adsp_rt595" + +endif # BOARD_NXP_ADSP_RT595 diff --git a/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.dts b/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.dts new file mode 100644 index 00000000000000..dc546c8db2451f --- /dev/null +++ b/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.dts @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 Google LLC. + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +/ { + model = "nxp_adsp_rt595"; + compatible = "nxp"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "cdns,tensilica-xtensa-lx6"; + reg = <0>; + }; + }; + + sram0: memory@0 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "memory"; + compatible = "mmio-sram"; + /* Reserve first 512kB of shared memory for ADSP. */ + reg = <0x0 DT_SIZE_K(512)>; + /* Reset section must always be at 0 and at least 1kB. */ + adsp_reset: memory@0 { + reg = <0x0 DT_SIZE_K(1)>; + }; + /* Code and data sections can be moved around and resized if needed. */ + adsp_text: memory@400 { + reg = <0x400 DT_SIZE_K(255)>; + }; + /* On RT595 ADSP shared RAM is mapped at offset 0 on the code bus and at + * offset 0x800000 on the data bus. + */ + adsp_data: memory@840000 { + reg = <0x840000 DT_SIZE_K(256)>; + }; + }; + + chosen { + zephyr,sram = &adsp_data; + }; +}; diff --git a/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.yaml b/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.yaml new file mode 100644 index 00000000000000..ca3e0c21252430 --- /dev/null +++ b/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595.yaml @@ -0,0 +1,9 @@ +identifier: nxp_adsp_rt595 +name: i.MXRT595 DSP +type: mcu +arch: xtensa +toolchain: + - zephyr +testing: + only_tags: + - kernel diff --git a/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595_defconfig b/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595_defconfig new file mode 100644 index 00000000000000..0e80f8a41a66ec --- /dev/null +++ b/boards/xtensa/nxp_adsp_rt595/nxp_adsp_rt595_defconfig @@ -0,0 +1,7 @@ +CONFIG_SOC_SERIES_NXP_RT5XX=y +CONFIG_SOC_NXP_RT595=y +CONFIG_BOARD_NXP_ADSP_RT595=y + +CONFIG_GEN_ISR_TABLES=y +CONFIG_GEN_IRQ_VECTOR_TABLE=n +CONFIG_XTENSA_SMALL_VECTOR_TABLE_ENTRY=y diff --git a/soc/xtensa/nxp_adsp/CMakeLists.txt b/soc/xtensa/nxp_adsp/CMakeLists.txt index f317b0b7054d85..f306839ac2a90b 100644 --- a/soc/xtensa/nxp_adsp/CMakeLists.txt +++ b/soc/xtensa/nxp_adsp/CMakeLists.txt @@ -1,8 +1,12 @@ -# NXP i.MX8 SoC family CMake file +# NXP i.MX8/RT SoC family CMake file # # Copyright (c) 2021 NXP # SPDX-License-Identifier: Apache-2.0 +if(CONFIG_SOC_NXP_RT595) + zephyr_compile_definitions(CPU_MIMXRT595SFFOC_dsp) +endif() + add_subdirectory(common) # west sign diff --git a/soc/xtensa/nxp_adsp/Kconfig.defconfig b/soc/xtensa/nxp_adsp/Kconfig.defconfig index 4c8e3f9c83c438..0dc331f883480a 100644 --- a/soc/xtensa/nxp_adsp/Kconfig.defconfig +++ b/soc/xtensa/nxp_adsp/Kconfig.defconfig @@ -1,4 +1,4 @@ -# NXP i.MX8 SoC family default configuration options +# NXP i.MX8/RT SoC family default configuration options # # Copyright (c) 2021 NXP # SPDX-License-Identifier: Apache-2.0 @@ -6,4 +6,24 @@ source "soc/xtensa/nxp_adsp/*/Kconfig.defconfig.series" config CACHE_MANAGEMENT - def_bool y + default y + +config SMP + default n + +config XTENSA_TIMER + default y + +config KERNEL_ENTRY + default "__start" + +config MULTI_LEVEL_INTERRUPTS + default n + +config 2ND_LEVEL_INTERRUPTS + default n + +# To prevent test uses TEST_LOGGING_MINIMAL +config TEST_LOGGING_DEFAULTS + default n + depends on TEST diff --git a/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.series b/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.series index 7431522e867ebd..1976bc119126b2 100644 --- a/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.series +++ b/soc/xtensa/nxp_adsp/imx8/Kconfig.defconfig.series @@ -15,36 +15,16 @@ config SOC string default "nxp_imx8" -config SMP - default n - -config XTENSA_TIMER - default y - config SYS_CLOCK_HW_CYCLES_PER_SEC default 666000000 if XTENSA_TIMER config SYS_CLOCK_TICKS_PER_SEC default 50000 -config KERNEL_ENTRY - default "__start" - -config MULTI_LEVEL_INTERRUPTS - default n - -config 2ND_LEVEL_INTERRUPTS - default n - config DYNAMIC_INTERRUPTS default y config LOG default y -# To prevent test uses TEST_LOGGING_MINIMAL -config TEST_LOGGING_DEFAULTS - default n - depends on TEST - endif # SOC_SERIES_NXP_IMX8 diff --git a/soc/xtensa/nxp_adsp/imx8m/Kconfig.defconfig.series b/soc/xtensa/nxp_adsp/imx8m/Kconfig.defconfig.series index 03967cb74e4336..d0fc446b4b0f04 100644 --- a/soc/xtensa/nxp_adsp/imx8m/Kconfig.defconfig.series +++ b/soc/xtensa/nxp_adsp/imx8m/Kconfig.defconfig.series @@ -17,38 +17,18 @@ config SOC string default "mimx8ml8" -config SMP - default n - -config XTENSA_TIMER - default y - config SYS_CLOCK_HW_CYCLES_PER_SEC default 800000000 if XTENSA_TIMER config SYS_CLOCK_TICKS_PER_SEC default 50000 -config KERNEL_ENTRY - default "__start" - -config MULTI_LEVEL_INTERRUPTS - default n - -config 2ND_LEVEL_INTERRUPTS - default n - config DYNAMIC_INTERRUPTS default y config LOG default y -# To prevent test uses TEST_LOGGING_MINIMAL -config TEST_LOGGING_DEFAULTS - default n - depends on TEST - # endif # SOC_MIMX8M_ADSP endif # SOC_SERIES_NXP_IMX8M diff --git a/soc/xtensa/nxp_adsp/rt5xx/Kconfig.defconfig.series b/soc/xtensa/nxp_adsp/rt5xx/Kconfig.defconfig.series new file mode 100644 index 00000000000000..b5a56658c7da20 --- /dev/null +++ b/soc/xtensa/nxp_adsp/rt5xx/Kconfig.defconfig.series @@ -0,0 +1,46 @@ +# Copyright (c) 2023 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_NXP_RT5XX + +config SOC_SERIES + string + default "rt5xx" + +config SOC_TOOLCHAIN_NAME + string + default "nxp_rt500_adsp" + +config SOC + string + default "nxp_rt5xx" + +config SOC_PART_NUMBER + string + default "MIMXRT595SFFOC_dsp" if SOC_NXP_RT595 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 198000000 + +config XTENSA_CCOUNT_HZ + default SYS_CLOCK_HW_CYCLES_PER_SEC + +config SYS_CLOCK_TICKS_PER_SEC + default 1000 + +config DYNAMIC_INTERRUPTS + default n + +config CACHE + default n + +config DCACHE + default n + +config CACHE_MANAGEMENT + default n + +config LOG + default n + +endif # SOC_SERIES_NXP_RT5XX diff --git a/soc/xtensa/nxp_adsp/rt5xx/Kconfig.series b/soc/xtensa/nxp_adsp/rt5xx/Kconfig.series new file mode 100644 index 00000000000000..5135b881638a36 --- /dev/null +++ b/soc/xtensa/nxp_adsp/rt5xx/Kconfig.series @@ -0,0 +1,12 @@ +# Copyright (c) 2023 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_NXP_RT5XX + bool "NXP RT5xx Series" + select SOC_FAMILY_NXP_ADSP + select XTENSA + select XTENSA_HAL if ("$(ZEPHYR_TOOLCHAIN_VARIANT)" != "xcc" && "$(ZEPHYR_TOOLCHAIN_VARIANT)" != "xt-clang") + select XTENSA_RESET_VECTOR + select XTENSA_USE_CORE_CRT1 + help + NXP RT5xx ADSP Series diff --git a/soc/xtensa/nxp_adsp/rt5xx/Kconfig.soc b/soc/xtensa/nxp_adsp/rt5xx/Kconfig.soc new file mode 100644 index 00000000000000..e5b598c4f57089 --- /dev/null +++ b/soc/xtensa/nxp_adsp/rt5xx/Kconfig.soc @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +choice + prompt "NXP RT5xx ADSP SoC Selection" + + config SOC_NXP_RT595 + bool "NXP RT595" + depends on SOC_SERIES_NXP_RT5XX +endchoice diff --git a/soc/xtensa/nxp_adsp/rt5xx/include/_soc_inthandlers.h b/soc/xtensa/nxp_adsp/rt5xx/include/_soc_inthandlers.h new file mode 100644 index 00000000000000..0919a03d9ce16c --- /dev/null +++ b/soc/xtensa/nxp_adsp/rt5xx/include/_soc_inthandlers.h @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2023 Google LLC. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#if !defined(XCHAL_INT0_LEVEL) || XCHAL_INT0_LEVEL != 5 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT1_LEVEL) || XCHAL_INT1_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT2_LEVEL) || XCHAL_INT2_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT3_LEVEL) || XCHAL_INT3_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT4_LEVEL) || XCHAL_INT4_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT5_LEVEL) || XCHAL_INT5_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT6_LEVEL) || XCHAL_INT6_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT7_LEVEL) || XCHAL_INT7_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT8_LEVEL) || XCHAL_INT8_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT9_LEVEL) || XCHAL_INT9_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT10_LEVEL) || XCHAL_INT10_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT11_LEVEL) || XCHAL_INT11_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT12_LEVEL) || XCHAL_INT12_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT13_LEVEL) || XCHAL_INT13_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT14_LEVEL) || XCHAL_INT14_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT15_LEVEL) || XCHAL_INT15_LEVEL != 1 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT16_LEVEL) || XCHAL_INT16_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT17_LEVEL) || XCHAL_INT17_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT18_LEVEL) || XCHAL_INT18_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT19_LEVEL) || XCHAL_INT19_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT20_LEVEL) || XCHAL_INT20_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT21_LEVEL) || XCHAL_INT21_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT22_LEVEL) || XCHAL_INT22_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT23_LEVEL) || XCHAL_INT23_LEVEL != 2 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT24_LEVEL) || XCHAL_INT24_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT25_LEVEL) || XCHAL_INT25_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT26_LEVEL) || XCHAL_INT26_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT27_LEVEL) || XCHAL_INT27_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT28_LEVEL) || XCHAL_INT28_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT29_LEVEL) || XCHAL_INT29_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT30_LEVEL) || XCHAL_INT30_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif +#if !defined(XCHAL_INT31_LEVEL) || XCHAL_INT31_LEVEL != 3 +#error core-isa.h interrupt level does not match dispatcher! +#endif + +/* + * Interrupt masks for every level (RT595 ADSP): + * XCHAL_INTLEVEL1_MASK: 0x0000FFE0 + * XCHAL_INTLEVEL2_MASK: 0x00FF0006 + * XCHAL_INTLEVEL3_MASK: 0xFF000018 + * XCHAL_INTLEVEL4_MASK: 0x00000000 + * XCHAL_INTLEVEL5_MASK: 0x00000001 + */ + +static inline int _xtensa_handle_one_int1(unsigned int mask) +{ + int irq; + + mask &= XCHAL_INTLEVEL1_MASK; + for (int i = 5; i <= 31; i++) { + if (mask & BIT(i)) { + mask = BIT(i); + irq = i; + goto handle_irq; + } + } + return 0; +handle_irq: + _sw_isr_table[irq].isr(_sw_isr_table[irq].arg); + return mask; +} + +static inline int _xtensa_handle_one_int2(unsigned int mask) +{ + int irq; + + mask &= XCHAL_INTLEVEL2_MASK; + for (int i = 1; i <= 31; i++) { + if (mask & BIT(i)) { + mask = BIT(i); + irq = i; + goto handle_irq; + } + } + return 0; +handle_irq: + _sw_isr_table[irq].isr(_sw_isr_table[irq].arg); + return mask; +} + +static inline int _xtensa_handle_one_int3(unsigned int mask) +{ + int irq; + + mask &= XCHAL_INTLEVEL3_MASK; + for (int i = 3; i <= 31; i++) { + if (mask & BIT(i)) { + mask = BIT(i); + irq = i; + goto handle_irq; + } + } + return 0; +handle_irq: + _sw_isr_table[irq].isr(_sw_isr_table[irq].arg); + return mask; +} + +static inline int _xtensa_handle_one_int4(unsigned int mask) +{ + return 0; +} + +static inline int _xtensa_handle_one_int5(unsigned int mask) +{ + int irq; + + if (mask & BIT(0)) { + mask = BIT(0); + irq = 0; + goto handle_irq; + } + return 0; +handle_irq: + _sw_isr_table[irq].isr(_sw_isr_table[irq].arg); + return mask; +} diff --git a/soc/xtensa/nxp_adsp/rt5xx/include/soc/memory.h b/soc/xtensa/nxp_adsp/rt5xx/include/soc/memory.h new file mode 100644 index 00000000000000..af9e1888e1ca5d --- /dev/null +++ b/soc/xtensa/nxp_adsp/rt5xx/include/soc/memory.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 Google LLC. + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +#define IRAM_BASE (CONFIG_RT595_ADSP_TEXT_MEM_ADDR) +#define IRAM_SIZE (CONFIG_RT595_ADSP_TEXT_MEM_SIZE) + +#define SDRAM0_BASE (CONFIG_RT595_ADSP_DATA_MEM_ADDR) +#define SDRAM0_SIZE (CONFIG_RT595_ADSP_DATA_MEM_SIZE - CONFIG_RT595_ADSP_STACK_SIZE) + +/* The reset vector address in SRAM and its size. */ +#define XCHAL_RESET_VECTOR0_PADDR_IRAM (CONFIG_RT595_ADSP_RESET_MEM_ADDR) +#define MEM_RESET_TEXT_SIZE (0x2e0) +#define MEM_RESET_LIT_SIZE (0x120) + +/* Base address of all interrupt vectors in IRAM. */ +#define XCHAL_VECBASE_RESET_PADDR_IRAM (IRAM_BASE) +#define MEM_VECBASE_LIT_SIZE (0x178) + +/* Vector and literal sizes. */ +#define MEM_VECT_LIT_SIZE (0x4) +#define MEM_VECT_TEXT_SIZE (0x1C) + +/* Addresses of the interrupt vectors. */ +#define XCHAL_INT_VECTOR_ADDR(x) (XCHAL_VECBASE_RESET_PADDR_IRAM + (x)) +#define XCHAL_INTLEVEL2_VECTOR_PADDR_IRAM (XCHAL_INT_VECTOR_ADDR(0x17C)) +#define XCHAL_INTLEVEL3_VECTOR_PADDR_IRAM (XCHAL_INT_VECTOR_ADDR(0x19C)) +#define XCHAL_INTLEVEL4_VECTOR_PADDR_IRAM (XCHAL_INT_VECTOR_ADDR(0x1BC)) +#define XCHAL_INTLEVEL5_VECTOR_PADDR_IRAM (XCHAL_INT_VECTOR_ADDR(0x1DC)) +#define XCHAL_KERNEL_VECTOR_PADDR_IRAM (XCHAL_INT_VECTOR_ADDR(0x1FC)) +#define XCHAL_USER_VECTOR_PADDR_IRAM (XCHAL_INT_VECTOR_ADDR(0x21C)) +#define XCHAL_DOUBLEEXC_VECTOR_PADDR_IRAM (XCHAL_INT_VECTOR_ADDR(0x23C)) + +/* Location for the intList section which is later used to construct the + * Interrupt Descriptor Table (IDT). This is a bogus address as this + * section will be stripped off in the final image. + */ +#define IDT_BASE (IRAM_BASE + IRAM_SIZE) + +/* Size of the Interrupt Descriptor Table (IDT). */ +#define IDT_SIZE (0x2000) diff --git a/soc/xtensa/nxp_adsp/rt5xx/linker.ld b/soc/xtensa/nxp_adsp/rt5xx/linker.ld new file mode 100644 index 00000000000000..27be72151948c9 --- /dev/null +++ b/soc/xtensa/nxp_adsp/rt5xx/linker.ld @@ -0,0 +1,464 @@ +/* + * Copyright (c) 2021 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +OUTPUT_ARCH(xtensa) + +#include +#include + +#include +#include +#include + +#define RAMABLE_REGION sdram0 :sdram0_phdr +#define ROMABLE_REGION sdram0 :sdram0_phdr + +MEMORY +{ + vector_reset_text : + org = XCHAL_RESET_VECTOR0_PADDR_IRAM, + len = MEM_RESET_TEXT_SIZE + vector_reset_lit : + org = XCHAL_RESET_VECTOR0_PADDR_IRAM + MEM_RESET_TEXT_SIZE, + len = MEM_RESET_LIT_SIZE + vector_base_text : + org = XCHAL_VECBASE_RESET_PADDR_IRAM, + len = MEM_VECBASE_LIT_SIZE + vector_int2_lit : + org = XCHAL_INTLEVEL2_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, + len = MEM_VECT_LIT_SIZE + vector_int2_text : + org = XCHAL_INTLEVEL2_VECTOR_PADDR_IRAM, + len = MEM_VECT_TEXT_SIZE + vector_int3_lit : + org = XCHAL_INTLEVEL3_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, + len = MEM_VECT_LIT_SIZE + vector_int3_text : + org = XCHAL_INTLEVEL3_VECTOR_PADDR_IRAM, + len = MEM_VECT_TEXT_SIZE + vector_int4_lit : + org = XCHAL_INTLEVEL4_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, + len = MEM_VECT_LIT_SIZE + vector_int4_text : + org = XCHAL_INTLEVEL4_VECTOR_PADDR_IRAM, + len = MEM_VECT_TEXT_SIZE + vector_int5_lit : + org = XCHAL_INTLEVEL5_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, + len = MEM_VECT_LIT_SIZE + vector_int5_text : + org = XCHAL_INTLEVEL5_VECTOR_PADDR_IRAM, + len = MEM_VECT_TEXT_SIZE + vector_kernel_lit : + org = XCHAL_KERNEL_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, + len = MEM_VECT_LIT_SIZE + vector_kernel_text : + org = XCHAL_KERNEL_VECTOR_PADDR_IRAM, + len = MEM_VECT_TEXT_SIZE + vector_user_lit : + org = XCHAL_USER_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, + len = MEM_VECT_LIT_SIZE + vector_user_text : + org = XCHAL_USER_VECTOR_PADDR_IRAM, + len = MEM_VECT_TEXT_SIZE + vector_double_lit : + org = XCHAL_DOUBLEEXC_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, + len = MEM_VECT_LIT_SIZE + vector_double_text : + org = XCHAL_DOUBLEEXC_VECTOR_PADDR_IRAM, + len = MEM_VECT_TEXT_SIZE + iram_text_start : + org = XCHAL_DOUBLEEXC_VECTOR_PADDR_IRAM + MEM_VECT_TEXT_SIZE, + len = (IRAM_BASE + IRAM_SIZE) - (XCHAL_DOUBLEEXC_VECTOR_PADDR + MEM_VECT_TEXT_SIZE) + sdram0 : + org = SDRAM0_BASE, + len = SDRAM0_SIZE +#ifdef CONFIG_GEN_ISR_TABLES + IDT_LIST : + org = IDT_BASE, + len = IDT_SIZE +#endif +} + +PHDRS +{ + vector_reset_text_phdr PT_LOAD; + vector_reset_lit_phdr PT_LOAD; + vector_base_text_phdr PT_LOAD; + vector_base_lit_phdr PT_LOAD; + vector_int2_text_phdr PT_LOAD; + vector_int2_lit_phdr PT_LOAD; + vector_int3_text_phdr PT_LOAD; + vector_int3_lit_phdr PT_LOAD; + vector_int4_text_phdr PT_LOAD; + vector_int4_lit_phdr PT_LOAD; + vector_int5_text_phdr PT_LOAD; + vector_int5_lit_phdr PT_LOAD; + vector_kernel_text_phdr PT_LOAD; + vector_kernel_lit_phdr PT_LOAD; + vector_user_text_phdr PT_LOAD; + vector_user_lit_phdr PT_LOAD; + vector_double_text_phdr PT_LOAD; + vector_double_lit_phdr PT_LOAD; + iram_text_start_phdr PT_LOAD; + sdram0_phdr PT_LOAD; +} + +PROVIDE(_memmap_reset_vector = XCHAL_RESET_VECTOR0_PADDR_IRAM); +PROVIDE(_memmap_vecbase_reset = XCHAL_VECBASE_RESET_PADDR_IRAM); + +ENTRY(CONFIG_KERNEL_ENTRY) + +/* Various memory-map dependent cache attribute settings: */ +_memmap_cacheattr_wb_base = 0x00000012; +_memmap_cacheattr_wt_base = 0x00000012; +_memmap_cacheattr_bp_base = 0x00000022; +_memmap_cacheattr_unused_mask = 0xFFFFFF00; +_memmap_cacheattr_wb_trapnull = 0x22222212; +_memmap_cacheattr_wba_trapnull = 0x22222212; +_memmap_cacheattr_wbna_trapnull = 0x22222212; +_memmap_cacheattr_wt_trapnull = 0x22222212; +_memmap_cacheattr_bp_trapnull = 0x22222222; +_memmap_cacheattr_wb_strict = 0xFFFFFF12; +_memmap_cacheattr_wt_strict = 0xFFFFFF12; +_memmap_cacheattr_bp_strict = 0xFFFFFF22; +_memmap_cacheattr_wb_allvalid = 0x22222212; +_memmap_cacheattr_wt_allvalid = 0x22222212; +_memmap_cacheattr_bp_allvalid = 0x22222222; +_memmap_region_map = 0x00000003; +PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull); + +SECTIONS +{ + +#include + .ResetVector.text : ALIGN(4) + { + _ResetVector_text_start = ABSOLUTE(.); + KEEP (*(.ResetVector.text)) + _ResetVector_text_end = ABSOLUTE(.); + } >vector_reset_text :vector_reset_text_phdr + + .ResetVector.literal : ALIGN(4) + { + _ResetVector_literal_start = ABSOLUTE(.); + *(.ResetVector.literal) + _ResetVector_literal_end = ABSOLUTE(.); + } >vector_reset_lit :vector_reset_lit_phdr + + .WindowVectors.text : ALIGN(4) + { + _WindowVectors_text_start = ABSOLUTE(.); + KEEP (*(.WindowVectors.text)) + _WindowVectors_text_end = ABSOLUTE(.); + } >vector_base_text :vector_base_text_phdr + + .Level2InterruptVector.literal : ALIGN(4) + { + _Level2InterruptVector_literal_start = ABSOLUTE(.); + *(.Level2InterruptVector.literal) + _Level2InterruptVector_literal_end = ABSOLUTE(.); + } >vector_int2_lit :vector_int2_lit_phdr + + .Level2InterruptVector.text : ALIGN(4) + { + _Level2InterruptVector_text_start = ABSOLUTE(.); + KEEP (*(.Level2InterruptVector.text)) + _Level2InterruptVector_text_end = ABSOLUTE(.); + } >vector_int2_text :vector_int2_text_phdr + + .Level3InterruptVector.literal : ALIGN(4) + { + _Level3InterruptVector_literal_start = ABSOLUTE(.); + *(.Level3InterruptVector.literal) + _Level3InterruptVector_literal_end = ABSOLUTE(.); + } >vector_int3_lit :vector_int3_lit_phdr + + .Level3InterruptVector.text : ALIGN(4) + { + _Level3InterruptVector_text_start = ABSOLUTE(.); + KEEP (*(.Level3InterruptVector.text)) + _Level3InterruptVector_text_end = ABSOLUTE(.); + } >vector_int3_text :vector_int3_text_phdr + + .DebugExceptionVector.literal : ALIGN(4) + { + _DebugExceptionVector_literal_start = ABSOLUTE(.); + *(.DebugExceptionVector.literal) + _DebugExceptionVector_literal_end = ABSOLUTE(.); + } >vector_int4_lit :vector_int4_lit_phdr + + .DebugExceptionVector.text : ALIGN(4) + { + _DebugExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.DebugExceptionVector.text)) + _DebugExceptionVector_text_end = ABSOLUTE(.); + } >vector_int4_text :vector_int4_text_phdr + + .NMIExceptionVector.literal : ALIGN(4) + { + _NMIExceptionVector_literal_start = ABSOLUTE(.); + *(.NMIExceptionVector.literal) + _NMIExceptionVector_literal_end = ABSOLUTE(.); + } >vector_int5_lit :vector_int5_lit_phdr + + .NMIExceptionVector.text : ALIGN(4) + { + _NMIExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.NMIExceptionVector.text)) + _NMIExceptionVector_text_end = ABSOLUTE(.); + } >vector_int5_text :vector_int5_text_phdr + + .KernelExceptionVector.literal : ALIGN(4) + { + _KernelExceptionVector_literal_start = ABSOLUTE(.); + *(.KernelExceptionVector.literal) + _KernelExceptionVector_literal_end = ABSOLUTE(.); + } >vector_kernel_lit :vector_kernel_lit_phdr + + .KernelExceptionVector.text : ALIGN(4) + { + _KernelExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.KernelExceptionVector.text)) + _KernelExceptionVector_text_end = ABSOLUTE(.); + } >vector_kernel_text :vector_kernel_text_phdr + + .UserExceptionVector.literal : ALIGN(4) + { + _UserExceptionVector_literal_start = ABSOLUTE(.); + *(.UserExceptionVector.literal) + _UserExceptionVector_literal_end = ABSOLUTE(.); + } >vector_user_lit :vector_user_lit_phdr + + .UserExceptionVector.text : ALIGN(4) + { + _UserExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.UserExceptionVector.text)) + _UserExceptionVector_text_end = ABSOLUTE(.); + } >vector_user_text :vector_user_text_phdr + + .DoubleExceptionVector.literal : ALIGN(4) + { + _DoubleExceptionVector_literal_start = ABSOLUTE(.); + *(.DoubleExceptionVector.literal) + _DoubleExceptionVector_literal_end = ABSOLUTE(.); + } >vector_double_lit :vector_double_lit_phdr + + .DoubleExceptionVector.text : ALIGN(4) + { + _DoubleExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.DoubleExceptionVector.text)) + _DoubleExceptionVector_text_end = ABSOLUTE(.); + } >vector_double_text :vector_double_text_phdr + + .iram.text : ALIGN(4) + { + _stext = .; + _iram_text_start = ABSOLUTE(.); + *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) + _iram_text_end = ABSOLUTE(.); + } >iram_text_start :iram_text_start_phdr + + .rodata : ALIGN(4) + { + __rodata_region_start = ABSOLUTE(.); + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE__ = ABSOLUTE(.); + KEEP (*(.xt_except_table)) + KEEP (*(.gcc_except_table .gcc_except_table.*)) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + KEEP (*(.eh_frame)) + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __XT_EXCEPTION_DESCS__ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + . = ALIGN(4); + _bss_table_start = ABSOLUTE(.); + LONG(_bss_start) + LONG(_bss_end) + _bss_table_end = ABSOLUTE(.); + __rodata_region_end = ABSOLUTE(.); + } >sdram0 :sdram0_phdr + + .module_init : ALIGN(4) + { + _module_init_start = ABSOLUTE(.); + *(*.initcall) + _module_init_end = ABSOLUTE(.); + } >sdram0 :sdram0_phdr + + .text : ALIGN(4) + { + _stext = .; + _text_start = ABSOLUTE(.); + KEEP (*(.ResetVector.text)) + *(.ResetVector.literal) + *(.entry.text) + *(.init.literal) + KEEP(*(.init)) + *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.fini.literal) + KEEP(*(.fini)) + *(.gnu.version) + _text_end = ABSOLUTE(.); + _etext = .; + } >iram_text_start :iram_text_start_phdr + +#include + + .fw_ready : ALIGN(4) + { + KEEP(*(".fw_ready")); + KEEP (*(.fw_ready_metadata)) + } >sdram0 :sdram0_phdr + + .noinit : ALIGN(4) + { + *(.noinit) + *(.noinit.*) + } >sdram0 :sdram0_phdr + + .data : ALIGN(4) + { + __data_start = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + KEEP(*(.gnu.linkonce.d.*personality*)) + *(.data1) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + KEEP(*(.jcr)) + _trace_ctx_start = ABSOLUTE(.); + *(.trace_ctx) + _trace_ctx_end = ABSOLUTE(.); + . = ALIGN(4); + *(.gna_model) + __data_end = ABSOLUTE(.); + . = ALIGN(4096); + } >sdram0 :sdram0_phdr + + .lit4 : ALIGN(4) + { + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + } >sdram0 :sdram0_phdr + +#include + + .bss (NOLOAD) : ALIGN(8) + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + _bss_end = ABSOLUTE(.); + } >sdram0 :sdram0_phdr + + .heap_mem (NOLOAD) : ALIGN(8) + { + . = ALIGN (8); + _heap_mem_start = ABSOLUTE(.); + *(*.heap_mem) + _heap_mem_end = ABSOLUTE(.); + + } >sdram0 :sdram0_phdr + + /* stack */ + _end = ALIGN (8); + + /DISCARD/ : { *(.note.GNU-stack) } + _heap_sentry = SDRAM0_BASE + SDRAM0_SIZE; + __stack = SDRAM0_BASE + SDRAM0_SIZE + CONFIG_RT595_ADSP_STACK_SIZE; + .comment 0 : { *(.comment) } + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + .debug_ranges 0 : { *(.debug_ranges) } + .xtensa.info 0 : { *(.xtensa.info) } + .xt.insn 0 : + { + KEEP (*(.xt.insn)) + KEEP (*(.gnu.linkonce.x.*)) + } + .xt.prop 0 : + { + KEEP (*(.xt.prop)) + KEEP (*(.xt.prop.*)) + KEEP (*(.gnu.linkonce.prop.*)) + } + .xt.lit 0 : + { + KEEP (*(.xt.lit)) + KEEP (*(.xt.lit.*)) + KEEP (*(.gnu.linkonce.p.*)) + } + .xt.profile_range 0 : + { + KEEP (*(.xt.profile_range)) + KEEP (*(.gnu.linkonce.profile_range.*)) + } + .xt.profile_ranges 0 : + { + KEEP (*(.xt.profile_ranges)) + KEEP (*(.gnu.linkonce.xt.profile_ranges.*)) + } + .xt.profile_files 0 : + { + KEEP (*(.xt.profile_files)) + KEEP (*(.gnu.linkonce.xt.profile_files.*)) + } +#ifdef CONFIG_GEN_ISR_TABLES +#include +#endif +}