1/*
2 * Copyright (c) 2016 Jean-Paul Etienne <fractalclone@gmail.com>
3 * Contributors: 2018 Antmicro <www.antmicro.com>
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#include <zephyr/toolchain.h>
9#include <zephyr/linker/sections.h>
10#include <zephyr/arch/cpu.h>
11#include <zephyr/offsets.h>
12#include "asm_macros.inc"
13
14/* exports */
15GTEXT(__initialize)
16GTEXT(__reset)
17
18/* imports */
19GTEXT(z_prep_c)
20GTEXT(riscv_cpu_wake_flag)
21GTEXT(riscv_cpu_sp)
22GTEXT(arch_secondary_cpu_init)
23
24#if CONFIG_INCLUDE_RESET_VECTOR
25SECTION_FUNC(reset, __reset)
26	/*
27	 * jump to __initialize
28	 * use call opcode in case __initialize is far away.
29	 * This will be dependent on linker.ld configuration.
30	 */
31	call __initialize
32#endif /* CONFIG_INCLUDE_RESET_VECTOR */
33
34/* use ABI name of registers for the sake of simplicity */
35
36/*
37 * Remainder of asm-land initialization code before we can jump into
38 * the C domain
39 */
40SECTION_FUNC(TEXT, __initialize)
41	csrr a0, mhartid
42	li t0, CONFIG_RV_BOOT_HART
43	beq a0, t0, boot_first_core
44	j boot_secondary_core
45
46boot_first_core:
47
48#ifdef CONFIG_FPU
49	/*
50	 * Enable floating-point.
51	 */
52	li t0, MSTATUS_FS_INIT
53	csrs mstatus, t0
54
55	/*
56	 * Floating-point rounding mode set to IEEE-754 default, and clear
57	 * all exception flags.
58	 */
59	fscsr zero
60#endif
61
62#ifdef CONFIG_INIT_STACKS
63	/* Pre-populate all bytes in z_interrupt_stacks with 0xAA */
64	la t0, z_interrupt_stacks
65	/* Total size of all cores' IRQ stack */
66	li t1, __z_interrupt_all_stacks_SIZEOF
67	add t1, t1, t0
68
69	/* Populate z_interrupt_stacks with 0xaaaaaaaa */
70	li t2, 0xaaaaaaaa
71aa_loop:
72	sw t2, 0x00(t0)
73	addi t0, t0, 4
74	blt t0, t1, aa_loop
75#endif /* CONFIG_INIT_STACKS */
76
77	/*
78	 * Initially, setup stack pointer to
79	 * z_interrupt_stacks + __z_interrupt_stack_SIZEOF
80	 */
81	la sp, z_interrupt_stacks
82	li t0, __z_interrupt_stack_SIZEOF
83	add sp, sp, t0
84
85#ifdef CONFIG_WDOG_INIT
86	call _WdogInit
87#endif
88
89	/*
90	 * Jump into C domain. z_prep_c zeroes BSS, copies rw data into RAM,
91	 * and then enters kernel z_cstart
92	 */
93	call z_prep_c
94
95boot_secondary_core:
96#if CONFIG_MP_MAX_NUM_CPUS > 1
97	la t0, riscv_cpu_wake_flag
98	li t1, -1
99	sr t1, 0(t0)
100	la t0, riscv_cpu_boot_flag
101	sr zero, 0(t0)
102
103wait_secondary_wake_flag:
104	la t0, riscv_cpu_wake_flag
105	lr t0, 0(t0)
106	bne a0, t0, wait_secondary_wake_flag
107
108	/* Set up stack */
109	la t0, riscv_cpu_sp
110	lr sp, 0(t0)
111
112	la t0, riscv_cpu_boot_flag
113	li t1, 1
114	sr t1, 0(t0)
115	j arch_secondary_cpu_init
116#else
117	j loop_unconfigured_cores
118#endif
119
120loop_unconfigured_cores:
121	wfi
122	j loop_unconfigured_cores
123