1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Early initialization code for riscv
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)
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)
78 # get sr, epc, badvaddr, cause
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
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)
94 # get faulting insn, if it wasn't a fetch-related trap
96 STORE x5, 36 * REGBYTES(sp)
101 .align 2 # four byte alignment, as required by mtvec
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
116 csrrw sp, mscratch, sp
118 addi sp, sp, -MENTRY_FRAME_SIZE
121 mv a0,sp # put trapframe as first argument
127 addi sp, sp, MENTRY_FRAME_SIZE
129 # restore original stack pointer (either sp or mscratch)
130 csrrw sp, mscratch, sp
132 csrrw sp, mscratch, sp