| /* |
| * Copyright (c) 2016 Jean-Paul Etienne <fractalclone@gmail.com> |
| * Contributors: 2018 Antmicro <www.antmicro.com> |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <zephyr/toolchain.h> |
| #include <zephyr/linker/sections.h> |
| #include <zephyr/arch/cpu.h> |
| #include <offsets.h> |
| #include "asm_macros.inc" |
| |
| /* exports */ |
| GTEXT(__initialize) |
| GTEXT(__reset) |
| |
| /* imports */ |
| GTEXT(z_prep_c) |
| GTEXT(riscv_cpu_wake_flag) |
| GTEXT(riscv_cpu_sp) |
| GTEXT(arch_secondary_cpu_init) |
| |
| #if CONFIG_INCLUDE_RESET_VECTOR |
| SECTION_FUNC(reset, __reset) |
| /* |
| * jump to __initialize |
| * use call opcode in case __initialize is far away. |
| * This will be dependent on linker.ld configuration. |
| */ |
| call __initialize |
| #endif /* CONFIG_INCLUDE_RESET_VECTOR */ |
| |
| /* use ABI name of registers for the sake of simplicity */ |
| |
| /* |
| * Remainder of asm-land initialization code before we can jump into |
| * the C domain |
| */ |
| SECTION_FUNC(TEXT, __initialize) |
| csrr a0, mhartid |
| li t0, CONFIG_RV_BOOT_HART |
| beq a0, t0, boot_first_core |
| j boot_secondary_core |
| |
| boot_first_core: |
| |
| #ifdef CONFIG_FPU |
| /* |
| * Enable floating-point. |
| */ |
| li t0, MSTATUS_FS_INIT |
| csrs mstatus, t0 |
| |
| /* |
| * Floating-point rounding mode set to IEEE-754 default, and clear |
| * all exception flags. |
| */ |
| fscsr zero |
| #endif |
| |
| #ifdef CONFIG_INIT_STACKS |
| /* Pre-populate all bytes in z_interrupt_stacks with 0xAA */ |
| la t0, z_interrupt_stacks |
| li t1, __z_interrupt_stack_SIZEOF |
| add t1, t1, t0 |
| |
| /* Populate z_interrupt_stacks with 0xaaaaaaaa */ |
| li t2, 0xaaaaaaaa |
| aa_loop: |
| sw t2, 0x00(t0) |
| addi t0, t0, 4 |
| blt t0, t1, aa_loop |
| #endif |
| |
| /* |
| * Initially, setup stack pointer to |
| * z_interrupt_stacks + __z_interrupt_stack_SIZEOF |
| */ |
| la sp, z_interrupt_stacks |
| li t0, __z_interrupt_stack_SIZEOF |
| add sp, sp, t0 |
| |
| #ifdef CONFIG_WDOG_INIT |
| call _WdogInit |
| #endif |
| |
| /* |
| * Jump into C domain. z_prep_c zeroes BSS, copies rw data into RAM, |
| * and then enters kernel z_cstart |
| */ |
| call z_prep_c |
| |
| boot_secondary_core: |
| #if CONFIG_MP_MAX_NUM_CPUS > 1 |
| la t0, riscv_cpu_wake_flag |
| li t1, -1 |
| sr t1, 0(t0) |
| la t0, riscv_cpu_boot_flag |
| sr zero, 0(t0) |
| |
| wait_secondary_wake_flag: |
| la t0, riscv_cpu_wake_flag |
| lr t0, 0(t0) |
| bne a0, t0, wait_secondary_wake_flag |
| |
| /* Set up stack */ |
| la t0, riscv_cpu_sp |
| lr sp, 0(t0) |
| |
| la t0, riscv_cpu_boot_flag |
| li t1, 1 |
| sr t1, 0(t0) |
| j arch_secondary_cpu_init |
| #else |
| j loop_unconfigured_cores |
| #endif |
| |
| loop_unconfigured_cores: |
| wfi |
| j loop_unconfigured_cores |