xref: /aosp_15_r20/external/coreboot/src/arch/riscv/trap_util.S (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Early initialization code for riscv
4 */
5
6#include <bits.h>
7#include <mcall.h>
8
9.macro restore_regs
10	# restore x registers
11	LOAD	 x1, 1 * REGBYTES(sp)
12	LOAD	 x3, 3 * REGBYTES(sp)
13	LOAD	 x4, 4 * REGBYTES(sp)
14	LOAD	 x5, 5 * REGBYTES(sp)
15	LOAD	 x6, 6 * REGBYTES(sp)
16	LOAD	 x7, 7 * REGBYTES(sp)
17	LOAD	 x8, 8 * REGBYTES(sp)
18	LOAD	 x9, 9 * REGBYTES(sp)
19	LOAD	x10, 10 * REGBYTES(sp)
20	LOAD	x11, 11 * REGBYTES(sp)
21	LOAD	x12, 12 * REGBYTES(sp)
22	LOAD	x13, 13 * REGBYTES(sp)
23	LOAD	x14, 14 * REGBYTES(sp)
24	LOAD	x15, 15 * REGBYTES(sp)
25	LOAD	x16, 16 * REGBYTES(sp)
26	LOAD	x17, 17 * REGBYTES(sp)
27	LOAD	x18, 18 * REGBYTES(sp)
28	LOAD	x19, 19 * REGBYTES(sp)
29	LOAD	x20, 20 * REGBYTES(sp)
30	LOAD	x21, 21 * REGBYTES(sp)
31	LOAD	x22, 22 * REGBYTES(sp)
32	LOAD	x23, 23 * REGBYTES(sp)
33	LOAD	x24, 24 * REGBYTES(sp)
34	LOAD	x25, 25 * REGBYTES(sp)
35	LOAD	x26, 26 * REGBYTES(sp)
36	LOAD	x27, 27 * REGBYTES(sp)
37	LOAD	x28, 28 * REGBYTES(sp)
38	LOAD	x29, 29 * REGBYTES(sp)
39	LOAD	x30, 30 * REGBYTES(sp)
40	LOAD	x31, 31 * REGBYTES(sp)
41.endm
42
43.macro save_tf
44	# save general purpose registers
45	# no point in saving x0 since it is always 0
46	STORE	 x1, 1 * REGBYTES(sp)
47	# x2 is our stack pointer and is saved further below
48	STORE	 x3, 3 * REGBYTES(sp)
49	STORE	 x4, 4 * REGBYTES(sp)
50	STORE	 x5, 5 * REGBYTES(sp)
51	STORE	 x6, 6 * REGBYTES(sp)
52	STORE	 x7, 7 * REGBYTES(sp)
53	STORE	 x8, 8 * REGBYTES(sp)
54	STORE	 x9, 9 * REGBYTES(sp)
55	STORE	x10, 10 * REGBYTES(sp)
56	STORE	x11, 11 * REGBYTES(sp)
57	STORE	x12, 12 * REGBYTES(sp)
58	STORE	x13, 13 * REGBYTES(sp)
59	STORE	x14, 14 * REGBYTES(sp)
60	STORE	x15, 15 * REGBYTES(sp)
61	STORE	x16, 16 * REGBYTES(sp)
62	STORE	x17, 17 * REGBYTES(sp)
63	STORE	x18, 18 * REGBYTES(sp)
64	STORE	x19, 19 * REGBYTES(sp)
65	STORE	x20, 20 * REGBYTES(sp)
66	STORE	x21, 21 * REGBYTES(sp)
67	STORE	x22, 22 * REGBYTES(sp)
68	STORE	x23, 23 * REGBYTES(sp)
69	STORE	x24, 24 * REGBYTES(sp)
70	STORE	x25, 25 * REGBYTES(sp)
71	STORE	x26, 26 * REGBYTES(sp)
72	STORE	x27, 27 * REGBYTES(sp)
73	STORE	x28, 28 * REGBYTES(sp)
74	STORE	x29, 29 * REGBYTES(sp)
75	STORE	x30, 30 * REGBYTES(sp)
76	STORE	x31, 31 * REGBYTES(sp)
77
78	# get sr, epc, badvaddr, cause
79	csrr	t0, mscratch
80	bnez	t0, 1f	# t0 == 0, trap come from coreboot
81			# t0 != 0, t0 is saved old sp
82	add	t0, sp, MENTRY_FRAME_SIZE
831:
84	csrr	s0, mstatus
85	csrr	t1, mepc
86	csrr	t2, mtval
87	csrr	t3, mcause
88	STORE	t0, 2 * REGBYTES(sp)
89	STORE	s0, 32 * REGBYTES(sp)
90	STORE	t1, 33 * REGBYTES(sp)
91	STORE	t2, 34 * REGBYTES(sp)
92	STORE	t3, 35 * REGBYTES(sp)
93
94	# get faulting insn, if it wasn't a fetch-related trap
95	li	x5, -1
96	STORE	x5, 36 * REGBYTES(sp)
97.endm
98
99	.text
100	.global  trap_entry
101	.align 2 # four byte alignment, as required by mtvec
102trap_entry:
103	# mscratch is initialized to 0
104	# when exiting coreboot, write sp to mscratch
105	# before jumping to m-mode firmware we always set trap vector to the entry point of the
106	# payload and we don't care about mscratch anymore. mscratch is only ever used as
107	# exception stack if whatever coreboot jumps to is in s-mode.
108	#TODO we could check MPP field in mstatus to see if come from unpriviledged code. That
109	#     way we could still use mscratch for other purposes inside the code base.
110	#TODO In case we got called from s-mode firmware we need to protect our stack and trap
111	#     handler with a PMP region.
112	csrrw	sp, mscratch, sp
113	# sp == 0 => trap came from coreboot
114	# sp != 0 => trap came from s-mode payload
115	bnez	sp, 1f
116	csrrw	sp, mscratch, sp
1171:
118	addi	sp, sp, -MENTRY_FRAME_SIZE
119	save_tf
120
121	mv a0,sp # put trapframe as first argument
122
123	LOAD	t0, trap_handler
124	jalr	t0
125
126trap_return:
127	restore_regs
128	addi	sp, sp, MENTRY_FRAME_SIZE
129
130	# restore original stack pointer (either sp or mscratch)
131	csrrw	sp, mscratch, sp
132	bnez	sp, 1f
133	csrrw	sp, mscratch, sp
1341:
135	mret
136