From fbd9dd4526bea21f44e4ca5367e899d85f6cdb9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C3=85berg?= Date: Fri, 29 Sep 2023 10:45:20 +0200 Subject: [PATCH] SPARC: Add support for single-vector trapping (SVT) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds support for the single-vector trapping (SVT) model, defined by SPARC-V8 Embedded (V8E) Architecture Specification. SVT is available in most LEON processors. With single-vector trapping enabled, all traps are vectored through a single trap vector (TBR.A) rather than one 16-byte entry for each trap type. This improves memory utilization because the full 4 KiB trap table is not needed. This implementation uses a two-level of lookup table to find the handler for the trap type (0..255). - Execution time is constant. - Condition flags are preserved. - The implementation footprint is 60 bytes .text and 284 bytes .rodata. For comparison, a non-SVT table is always 4096 .text. Signed-off-by: Martin Ã…berg --- arch/sparc/Kconfig | 6 ++ arch/sparc/core/CMakeLists.txt | 3 +- arch/sparc/core/reset_trap.S | 12 +++ arch/sparc/core/trap_table_svt.S | 138 +++++++++++++++++++++++++++++++ 4 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 arch/sparc/core/trap_table_svt.S 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