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:
parent
50edb6f22c
commit
a1d1a5f547
1 changed files with 17 additions and 21 deletions
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue