diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index a3746f147f9..1a17bf1eddd 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -26,6 +26,12 @@ config NUM_IRQS int default 32 +config SPARC_SVT + bool "Single-vector trapping" + help + Use Single-vector trapping (SVT). Defined by SPARC-V8 Embedded (V8E) + Architecture Specification and available in some LEON processors. + config SPARC_CASA bool "CASA instructions" help diff --git a/arch/sparc/core/CMakeLists.txt b/arch/sparc/core/CMakeLists.txt index 82ff7906638..cc458404ed8 100644 --- a/arch/sparc/core/CMakeLists.txt +++ b/arch/sparc/core/CMakeLists.txt @@ -13,8 +13,9 @@ zephyr_library_sources( thread.c window_trap.S sw_trap_set_pil.S - trap_table_mvt.S ) +zephyr_library_sources_ifdef(CONFIG_SPARC_SVT trap_table_svt.S) +zephyr_library_sources_ifndef(CONFIG_SPARC_SVT trap_table_mvt.S) zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c) diff --git a/arch/sparc/core/reset_trap.S b/arch/sparc/core/reset_trap.S index dd4046c47bc..6f1f6c037e3 100644 --- a/arch/sparc/core/reset_trap.S +++ b/arch/sparc/core/reset_trap.S @@ -12,6 +12,18 @@ GTEXT(__sparc_trap_reset) SECTION_FUNC(TEXT, __sparc_trap_reset) +#ifdef CONFIG_SPARC_SVT +#ifdef CONFIG_SOC_SPARC_LEON + /* On LEON, enable single vector trapping by setting ASR17.SV. */ + rd %asr17, %g1 + set (1<<13), %g2 + or %g1, %g2, %g1 + wr %g1, %asr17 +#else +#error "Don't know how to enable SVT on this SOC" +#endif +#endif + set __sparc_trap_table, %g1 wr %g1, %tbr wr 2, %wim diff --git a/arch/sparc/core/trap_table_svt.S b/arch/sparc/core/trap_table_svt.S new file mode 100644 index 00000000000..461cc5a51df --- /dev/null +++ b/arch/sparc/core/trap_table_svt.S @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2023 Frontgrade Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * This file contains the trap entry for SPARC operating with + * single-vector trap model, defined in SPARC V8E. The processor + * redirects execution to a single entry on any trap event. From + * there, two levels of look-up tables are used to find the trap + * handler. + * + * - Execution time is constant. + * - Condition flags are not modified. + * - Provides handler with PSR in l0, TBR in l6 + * - This SVT implementation is less than 400 bytes long. (An MVT + * table is always 4096 bytes long.) + * + * See trap_table_mvt.S for information about SPARC trap types. + */ + +#include +#include +#include + +#ifdef CONFIG_IRQ_OFFLOAD + #define IRQ_OFFLOAD_HANDLER __sparc_trap_irq_offload +#else + #define IRQ_OFFLOAD_HANDLER __sparc_trap_fault +#endif + +GTEXT(__sparc_trap_table) +GTEXT(__start) + +SECTION_SUBSEC_FUNC(TEXT, traptable, __sparc_trap_table) +__start: + rd %psr, %l0 + mov %tbr, %l6 + + and %l6, 0xf00, %l7 + srl %l7, 6, %l7 + set __sparc_trap_table_svt_level0, %l4 + ld [%l4 + %l7], %l4 + + and %l6, 0x0f0, %l7 + srl %l7, 2, %l7 + ld [%l4 + %l7], %l4 + + srl %l6, 4, %l3 + jmp %l4 + and %l3, 0xf, %l3 /* Interrupt level */ + +__sparc_trap_svt_in_trap: + ta 0x00 + nop + +SECTION_VAR(RODATA, __sparc_trap_table_svt_tables) + .align 4 +__sparc_trap_table_svt_level0: + .word __sparc_trap_table_svt_00 + .word __sparc_trap_table_svt_10 + .word __sparc_trap_table_svt_allbad + .word __sparc_trap_table_svt_allbad + .word __sparc_trap_table_svt_allbad + .word __sparc_trap_table_svt_allbad + .word __sparc_trap_table_svt_allbad + .word __sparc_trap_table_svt_allbad + .word __sparc_trap_table_svt_80 + .word __sparc_trap_table_svt_allbad + .word __sparc_trap_table_svt_allbad + .word __sparc_trap_table_svt_allbad + .word __sparc_trap_table_svt_allbad + .word __sparc_trap_table_svt_allbad + .word __sparc_trap_table_svt_allbad + .word __sparc_trap_table_svt_allbad + +__sparc_trap_table_svt_00: + .word __sparc_trap_reset + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_window_overflow + .word __sparc_trap_window_underflow +__sparc_trap_table_svt_allbad: + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + +__sparc_trap_table_svt_10: + .word __sparc_trap_fault + .word __sparc_trap_interrupt + .word __sparc_trap_interrupt + .word __sparc_trap_interrupt + .word __sparc_trap_interrupt + .word __sparc_trap_interrupt + .word __sparc_trap_interrupt + .word __sparc_trap_interrupt + .word __sparc_trap_interrupt + .word __sparc_trap_interrupt + .word __sparc_trap_interrupt + .word __sparc_trap_interrupt + .word __sparc_trap_interrupt + .word __sparc_trap_interrupt + .word __sparc_trap_interrupt + .word __sparc_trap_interrupt + +__sparc_trap_table_svt_80: + .word __sparc_trap_svt_in_trap + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_flush_windows + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_sw_set_pil + .word __sparc_trap_fault + .word __sparc_trap_fault + .word __sparc_trap_fault + .word IRQ_OFFLOAD_HANDLER + .word __sparc_trap_fault + .word __sparc_trap_except_reason