RISC-V architecture bugfix potpourri
[akaros.git] / kern / arch / riscv / entry.S
1 #include <arch/pcr.h>
2 #include <arch/trap.h>
3 #include <ros/memlayout.h>
4
5 #ifdef __riscv64
6 # define STORE    sd
7 # define LOAD     ld
8 # define REGBYTES 8
9 #else
10 # define STORE    sw
11 # define LOAD     lw
12 # define REGBYTES 4
13 #endif
14
15   .text
16   .ent    save_kernel_tf_asm
17   .global save_kernel_tf_asm
18 save_kernel_tf_asm:
19   STORE  s0,20*REGBYTES(a0)
20   STORE  s1,21*REGBYTES(a0)
21   STORE  s2,22*REGBYTES(a0)
22   STORE  s3,23*REGBYTES(a0)
23   STORE  s4,24*REGBYTES(a0)
24   STORE  s5,25*REGBYTES(a0)
25   STORE  s6,26*REGBYTES(a0)
26   STORE  s7,27*REGBYTES(a0)
27   STORE  s8,28*REGBYTES(a0)
28   STORE  s9,29*REGBYTES(a0)
29   STORE  sp,30*REGBYTES(a0)
30
31   mfpcr  t0,ASM_CR(PCR_SR)
32   STORE  t0,32*REGBYTES(a0)
33
34   # set EPC to this function's return address
35   STORE  ra,33*REGBYTES(x2)
36
37   .end  save_kernel_tf_asm
38
39   .text
40   .ent    pop_kernel_tf
41   .global pop_kernel_tf
42 pop_kernel_tf:
43   LOAD  t0,32*REGBYTES(a0)
44   LOAD  ra,33*REGBYTES(x2)
45
46   LOAD  s0,20*REGBYTES(a0)
47   LOAD  s1,21*REGBYTES(a0)
48   LOAD  s2,22*REGBYTES(a0)
49   LOAD  s3,23*REGBYTES(a0)
50   LOAD  s4,24*REGBYTES(a0)
51   LOAD  s5,25*REGBYTES(a0)
52   LOAD  s6,26*REGBYTES(a0)
53   LOAD  s7,27*REGBYTES(a0)
54   LOAD  s8,28*REGBYTES(a0)
55   LOAD  s9,29*REGBYTES(a0)
56   LOAD  sp,30*REGBYTES(a0)
57
58   mtpcr  t0,ASM_CR(PCR_SR)
59   ret
60
61   .end  pop_kernel_tf
62
63   .ent  save_tf
64 save_tf:  # write the trap frame onto the stack
65
66   ret
67   .end  save_tf
68
69   .globl  env_pop_tf
70   .ent  env_pop_tf
71 env_pop_tf:  # write the trap frame onto the stack
72   # restore gprs
73   LOAD  t0,32*REGBYTES(a0)  # restore sr (should disable interrupts)
74   mtpcr  t0,ASM_CR(PCR_SR)
75
76   LOAD  x1,1*REGBYTES(a0)
77   mtpcr  x1,ASM_CR(PCR_K0)
78   LOAD  x1,2*REGBYTES(a0)
79   mtpcr x1,ASM_CR(PCR_K1)
80   move  x1,a0
81   LOAD  x3,3*REGBYTES(x1)
82   LOAD  x4,4*REGBYTES(x1)
83   LOAD  x5,5*REGBYTES(x1)
84   LOAD  x6,6*REGBYTES(x1)
85   LOAD  x7,7*REGBYTES(x1)
86   LOAD  x8,8*REGBYTES(x1)
87   LOAD  x9,9*REGBYTES(x1)
88   LOAD  x10,10*REGBYTES(x1)
89   LOAD  x11,11*REGBYTES(x1)
90   LOAD  x12,12*REGBYTES(x1)
91   LOAD  x13,13*REGBYTES(x1)
92   LOAD  x14,14*REGBYTES(x1)
93   LOAD  x15,15*REGBYTES(x1)
94   LOAD  x16,16*REGBYTES(x1)
95   LOAD  x17,17*REGBYTES(x1)
96   LOAD  x18,18*REGBYTES(x1)
97   LOAD  x19,19*REGBYTES(x1)
98   LOAD  x20,20*REGBYTES(x1)
99   LOAD  x21,21*REGBYTES(x1)
100   LOAD  x22,22*REGBYTES(x1)
101   LOAD  x23,23*REGBYTES(x1)
102   LOAD  x24,24*REGBYTES(x1)
103   LOAD  x25,25*REGBYTES(x1)
104   LOAD  x26,26*REGBYTES(x1)
105   LOAD  x27,27*REGBYTES(x1)
106   LOAD  x28,28*REGBYTES(x1)
107   LOAD  x29,29*REGBYTES(x1)
108   LOAD  x30,30*REGBYTES(x1)
109   LOAD  x31,31*REGBYTES(x1)
110
111   # gtfo!
112   LOAD  x2,33*REGBYTES(x1)
113   mtpcr x2,ASM_CR(PCR_EPC)
114   mfpcr x1,ASM_CR(PCR_K0)
115   mfpcr x2,ASM_CR(PCR_K1)
116   eret
117   .end  env_pop_tf
118
119   .global  trap_entry
120   .ent  trap_entry
121 trap_entry:
122   # save x1 and x2 so we can use them as temporaries
123   mtpcr x1, ASM_CR(PCR_K0)
124   mtpcr x2, ASM_CR(PCR_K1)
125
126   # when coming from kernel, continue below its stack
127   mfpcr x1, ASM_CR(PCR_SR)
128   and   x1, x1, SR_PS
129   add   x2, sp, -SIZEOF_TRAPFRAME_T
130   bnez  x1, 1f
131
132   # otherwise, start at the top of the per-core stack
133   la    x2, percore_stacks - SIZEOF_TRAPFRAME_T
134   mfpcr x1, ASM_CR(PCR_COREID)
135   add   x1, x1, 1
136   sll   x1, x1, KSTKSHIFT
137   add   x2, x2, x1
138
139 1:# save gprs
140   STORE  x3,3*REGBYTES(x2)
141   STORE  x4,4*REGBYTES(x2)
142   STORE  x5,5*REGBYTES(x2)
143   STORE  x6,6*REGBYTES(x2)
144   STORE  x7,7*REGBYTES(x2)
145   STORE  x8,8*REGBYTES(x2)
146   STORE  x9,9*REGBYTES(x2)
147   STORE  x10,10*REGBYTES(x2)
148   STORE  x11,11*REGBYTES(x2)
149   STORE  x12,12*REGBYTES(x2)
150   STORE  x13,13*REGBYTES(x2)
151   STORE  x14,14*REGBYTES(x2)
152   STORE  x15,15*REGBYTES(x2)
153   STORE  x16,16*REGBYTES(x2)
154   STORE  x17,17*REGBYTES(x2)
155   STORE  x18,18*REGBYTES(x2)
156   STORE  x19,19*REGBYTES(x2)
157   STORE  x20,20*REGBYTES(x2)
158   STORE  x21,21*REGBYTES(x2)
159   STORE  x22,22*REGBYTES(x2)
160   STORE  x23,23*REGBYTES(x2)
161   STORE  x24,24*REGBYTES(x2)
162   STORE  x25,25*REGBYTES(x2)
163   STORE  x26,26*REGBYTES(x2)
164   STORE  x27,27*REGBYTES(x2)
165   STORE  x28,28*REGBYTES(x2)
166   STORE  x29,29*REGBYTES(x2)
167   STORE  x30,30*REGBYTES(x2)
168   STORE  x31,31*REGBYTES(x2)
169
170   mfpcr  x3,ASM_CR(PCR_K0)
171   STORE  x3,1*REGBYTES(x2)          # x1 is in PCR_K0
172   mfpcr  x3,ASM_CR(PCR_K1)
173   STORE  x3,2*REGBYTES(x2)          # x2 is in PCR_K1
174
175   # get sr, epc, badvaddr, cause
176   mfpcr  x3,ASM_CR(PCR_SR)          # sr
177   STORE  x3,32*REGBYTES(x2)
178   mfpcr  x4,ASM_CR(PCR_EPC)          # epc
179   STORE  x4,33*REGBYTES(x2)
180   mfpcr  x3,ASM_CR(PCR_BADVADDR)      # badvaddr
181   STORE  x3,34*REGBYTES(x2)
182   mfpcr  x3,ASM_CR(PCR_CAUSE)        # cause
183   STORE  x3,35*REGBYTES(x2)
184
185   # get faulting insn, if it wasn't a fetch-related trap
186   and   x3, x3, CAUSE_EXCCODE
187   li    x5, CAUSE_MISALIGNED_FETCH
188   li    x6, CAUSE_FAULT_FETCH
189   beq   x3, x5, 1f
190   beq   x3, x6, 1f
191   lh    x3,0(x4)
192   lh    x4,2(x4)
193   sh    x3,  36*REGBYTES(x2)
194   sh    x4,2+36*REGBYTES(x2)
195 1:
196   li    s9, 0
197   move  sp, x2
198   move  a0, x2
199   j     handle_trap
200   .end  trap_entry
201
202   .global  cpu_halt
203   .ent  cpu_halt
204 cpu_halt:
205 1:b     1b   # handle_ipi can advance the PC to break out of this loop.
206   ret
207   .end  cpu_halt