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:
parent
dd5874b924
commit
fbd9dd4526
4 changed files with 158 additions and 1 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
138
arch/sparc/core/trap_table_svt.S
Normal file
138
arch/sparc/core/trap_table_svt.S
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue