util/crossgcc: Update DESTDIR variable use
[coreboot2.git] / src / arch / riscv / trap_util.S
blobd81f884b009e9704dd1241bf96acc3b2a4f631bd
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Early initialization code for riscv
4  */
6 #include <bits.h>
7 #include <mcall.h>
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
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)
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
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)
94         # get faulting insn, if it wasn't a fetch-related trap
95         li      x5, -1
96         STORE   x5, 36 * REGBYTES(sp)
97 .endm
99         .text
100         .global  trap_entry
101         .align 2 # four byte alignment, as required by mtvec
102 trap_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
118         addi    sp, sp, -MENTRY_FRAME_SIZE
119         save_tf
121         mv a0,sp # put trapframe as first argument
123         jal trap_handler
125 trap_return:
126         restore_regs
127         addi    sp, sp, MENTRY_FRAME_SIZE
129         # restore original stack pointer (either sp or mscratch)
130         csrrw   sp, mscratch, sp
131         bnez    sp, 1f
132         csrrw   sp, mscratch, sp
134         mret