SPARC: Add support for single-vector trapping (SVT)

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 <martin.aberg@gaisler.com>
This commit is contained in:
Martin Åberg 2023-09-29 10:45:20 +02:00 committed by Henrik Brix Andersen
commit fbd9dd4526
4 changed files with 158 additions and 1 deletions

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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 <zephyr/toolchain.h>
#include <zephyr/linker/sections.h>
#include <zephyr/arch/sparc/sparc.h>
#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