Skip to content

Commit

Permalink
xtensa: move arch_kernel_init code into prep_c
Browse files Browse the repository at this point in the history
arch_kernel_init() was misused for all architecture initialization code
that is done in prep_c and prior to cstart on other architectures.
arch_kernel_init() is late in the init process and comes after EARLY
init level, making xtensa have a very special boot path.

Signed-off-by: Anas Nashif <[email protected]>
  • Loading branch information
nashif committed Jul 9, 2024
1 parent ec66949 commit f5c33a3
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 50 deletions.
51 changes: 51 additions & 0 deletions arch/xtensa/core/prep_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,57 @@ extern FUNC_NORETURN void z_cstart(void);
*/
void z_prep_c(void)
{
_cpu_t *cpu0 = &_kernel.cpus[0];

#ifdef CONFIG_KERNEL_COHERENCE
/* Make sure we don't have live data for unexpected cached
* regions due to boot firmware
*/
sys_cache_data_flush_and_invd_all();

/* Our cache top stash location might have junk in it from a
* pre-boot environment. Must be zero or valid!
*/
XTENSA_WSR(ZSR_FLUSH_STR, 0);
#endif

cpu0->nested = 0;

/* The asm2 scheme keeps the kernel pointer in a scratch SR
* (see zsr.h for generation specifics) for easy access. That
* saves 4 bytes of immediate value to store the address when
* compared to the legacy scheme. But in SMP this record is a
* per-CPU thing and having it stored in a SR already is a big
* win.
*/
XTENSA_WSR(ZSR_CPU_STR, cpu0);

#ifdef CONFIG_INIT_STACKS
char *stack_start = K_KERNEL_STACK_BUFFER(z_interrupt_stacks[0]);
size_t stack_sz = K_KERNEL_STACK_SIZEOF(z_interrupt_stacks[0]);
char *stack_end = stack_start + stack_sz;

uint32_t sp;

__asm__ volatile("mov %0, sp" : "=a"(sp));

/* Only clear the interrupt stack if the current stack pointer
* is not within the interrupt stack. Or else we would be
* wiping the in-use stack.
*/
if (((uintptr_t)sp < (uintptr_t)stack_start) ||
((uintptr_t)sp >= (uintptr_t)stack_end)) {
memset(stack_start, 0xAA, stack_sz);
}
#endif

#ifdef CONFIG_XTENSA_MMU
xtensa_mmu_init();
#endif

#ifdef CONFIG_XTENSA_MPU
xtensa_mpu_init();
#endif
z_cstart();
CODE_UNREACHABLE;
}
50 changes: 0 additions & 50 deletions arch/xtensa/include/kernel_arch_func.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,57 +25,7 @@ K_KERNEL_STACK_ARRAY_DECLARE(z_interrupt_stacks, CONFIG_MP_MAX_NUM_CPUS,

static ALWAYS_INLINE void arch_kernel_init(void)
{
_cpu_t *cpu0 = &_kernel.cpus[0];

#ifdef CONFIG_KERNEL_COHERENCE
/* Make sure we don't have live data for unexpected cached
* regions due to boot firmware
*/
sys_cache_data_flush_and_invd_all();

/* Our cache top stash location might have junk in it from a
* pre-boot environment. Must be zero or valid!
*/
XTENSA_WSR(ZSR_FLUSH_STR, 0);
#endif

cpu0->nested = 0;

/* The asm2 scheme keeps the kernel pointer in a scratch SR
* (see zsr.h for generation specifics) for easy access. That
* saves 4 bytes of immediate value to store the address when
* compared to the legacy scheme. But in SMP this record is a
* per-CPU thing and having it stored in a SR already is a big
* win.
*/
XTENSA_WSR(ZSR_CPU_STR, cpu0);

#ifdef CONFIG_INIT_STACKS
char *stack_start = K_KERNEL_STACK_BUFFER(z_interrupt_stacks[0]);
size_t stack_sz = K_KERNEL_STACK_SIZEOF(z_interrupt_stacks[0]);
char *stack_end = stack_start + stack_sz;

uint32_t sp;

__asm__ volatile("mov %0, sp" : "=a"(sp));

/* Only clear the interrupt stack if the current stack pointer
* is not within the interrupt stack. Or else we would be
* wiping the in-use stack.
*/
if (((uintptr_t)sp < (uintptr_t)stack_start) ||
((uintptr_t)sp >= (uintptr_t)stack_end)) {
memset(stack_start, 0xAA, stack_sz);
}
#endif

#ifdef CONFIG_XTENSA_MMU
xtensa_mmu_init();
#endif

#ifdef CONFIG_XTENSA_MPU
xtensa_mpu_init();
#endif
}

void xtensa_switch(void *switch_to, void **switched_from);
Expand Down

0 comments on commit f5c33a3

Please sign in to comment.