SPARC: Keep interrupts disabled during kernel init

This commit avoids enabling interrupts during Zephyr init.

Details:
Interrupts will be enabled only when the first thread starts or if
arch_irq_unlock() is called before that.

The logic is now:
1. Enable traps, disable interrupts globally
2. Initialize bss
3. Call _PrepC

Use in-place memset() to avoid register window overflow and underflow
traps. That is perhaps not the common scenario, but could happen with
memset() implementation which contains SAVE instructions on a system
with few register windows.

The second, and more important, item this commit addresses is that it
increases the processor interrupt level (priority) to highest. That
is, it enters _PrepC with all maskable interrupts levels disabled.

This fixes some cases where interrupts could be taken after
z_clock_driver_init() while the system was still initializing. That
seem to have occurred when clearing large thread stacks.

The third thing is that we now start out with current window pointer
0 (PSR.CWP=0) instead of 1. It has no practical implication except
for preparing for possible future support for systems with only
two windows.

Signed-off-by: Martin Åberg <martin.aberg@gaisler.com>
This commit is contained in:
Martin Åberg 2020-11-26 12:16:22 +01:00 committed by Christopher Friedt
commit a1d1a5f547

View file

@ -14,44 +14,40 @@ GTEXT(__sparc_trap_reset)
SECTION_FUNC(TEXT, __sparc_trap_reset)
set __sparc_trap_table, %g1
wr %g1, %tbr
wr %g0, 4, %wim
/* %psr := pil=0, et=0, cwp=1 */
set (PSR_S | PSR_PS | 1), %g7
wr %g7, %psr
nop
nop
nop
wr 2, %wim
wr PSR_PIL | PSR_S | PSR_PS | PSR_ET, %psr
/* NOTE: wrpsr above may have changed the current register window. */
/* We are in the 3 instruction wrpsr delay so use global registers. */
set z_interrupt_stacks, %g2
set CONFIG_ISR_STACK_SIZE, %g4
add %g2, %g4, %g1
and %g1, 0xfffffff0, %l3
/*
* According to SPARC ABI, Chapter 3: The system marks the deepest
* stack frame by setting the frame pointer to zero. No other frame's
* %fp has a zero value.
*/
set z_interrupt_stacks, %o0
set CONFIG_ISR_STACK_SIZE, %o2
add %o0, %o2, %l2
and %l2, 0xfffffff0, %l3
sub %l3, 96, %sp
clr %fp
clr %i7
#ifdef CONFIG_INIT_STACKS
/* already have z_interrupt_stacks and CONFIG_ISR_STACK_SIZE in place */
call memset
mov 0xaa, %o1
/* In-place memset() to avoid register window related traps. */
set 0xaaaaaaaa, %l0
mov %l0, %l1
1:
std %l0, [%g2]
add %g2, 8, %g2
cmp %g2, %l3
bne 1b
nop
#endif
call z_bss_zero
nop
/* Enable traps for the first time */
/* %psr := pil=0, et=1, cwp=1 */
wr %g7, PSR_ET, %psr
nop
nop
nop
call _PrepC
nop