Allow the formal engine to perform a same-cycle result in the ALU
[soc.git] / src / soc / fu / trap / main_stage.py
1 """Trap Pipeline
2
3 Deals with td/tw/tdi/twi as well as mfmsr/mtmsr, sc and rfid. addpcis TODO.
4 Also used generally for interrupts (as a micro-coding mechanism) by
5 actually modifying the decoded instruction in PowerDecode2.
6
7 * https://bugs.libre-soc.org/show_bug.cgi?id=325
8 * https://bugs.libre-soc.org/show_bug.cgi?id=344
9 * https://libre-soc.org/openpower/isa/fixedtrap/
10 """
11
12 from nmigen import (Module, Signal, Cat, Mux, Const, signed)
13 from nmutil.pipemodbase import PipeModBase
14 from nmutil.extend import exts
15 from soc.fu.trap.pipe_data import TrapInputData, TrapOutputData
16 from soc.fu.branch.main_stage import br_ext
17 from openpower.decoder.power_enums import MicrOp
18 from soc.experiment.mem_types import LDSTException
19
20 from openpower.decoder.power_fields import DecodeFields
21 from openpower.decoder.power_fieldsn import SignalBitRange
22
23 from openpower.consts import MSR, PI, TT, field, field_slice
24
25
26 def msr_copy(msr_o, msr_i, zero_me=True):
27 """msr_copy (also used to copy relevant bits into SRR1)
28
29 ISA says this:
30 Defined MSR bits are classified as either full func tion or partial
31 function. Full function MSR bits are saved in SRR1 or HSRR1 when
32 an interrupt other than a System Call Vectored interrupt occurs and
33 restored by rfscv, rfid, or hrfid, while partial function MSR bits
34 are not saved or restored. Full function MSR bits lie in the range
35 0:32, 37:41, and 48:63, and partial function MSR bits lie in the
36 range 33:36 and 42:47. (Note this is IBM bit numbering).
37 """
38 l = []
39 if zero_me:
40 l.append(msr_o.eq(0))
41 for stt, end in [(0,16), (22, 27), (31, 64)]:
42 l.append(msr_o[stt:end].eq(msr_i[stt:end]))
43 return l
44
45
46 def msr_check_pr(m, d_in, msr):
47 """msr_check_pr: checks "problem state"
48 """
49 comb = m.d.comb
50 with m.If(d_in[MSR.PR]):
51 comb += msr[MSR.EE].eq(1) # set external interrupt bit
52 comb += msr[MSR.IR].eq(1) # set instruction relocation bit
53 comb += msr[MSR.DR].eq(1) # set data relocation bit
54
55
56 class TrapMainStage(PipeModBase):
57 def __init__(self, pspec):
58 super().__init__(pspec, "main")
59 self.fields = DecodeFields(SignalBitRange, [self.i.ctx.op.insn])
60 self.fields.create_specs()
61
62 def trap(self, m, trap_addr, return_addr):
63 """trap. sets new PC, stores MSR and old PC in SRR1 and SRR0
64 """
65 comb = m.d.comb
66 op = self.i.ctx.op
67 msr_i = op.msr
68 svstate_i = op.svstate
69
70 exc = LDSTException("trapexc")
71 comb += exc.eq(op.ldst_exc)
72 srr1_i = exc.srr1 # new SRR1 bits come from exception
73 nia_o = self.o.nia
74 svsrr0_o, srr0_o, srr1_o = self.o.svsrr0, self.o.srr0, self.o.srr1
75
76 # trap address
77 comb += nia_o.data.eq(trap_addr)
78 comb += nia_o.ok.eq(1)
79
80 # addr to begin from on return
81 comb += srr0_o.data.eq(return_addr)
82 comb += srr0_o.ok.eq(1)
83
84 # take a copy of the current MSR into SRR1, but first copy old SRR1
85 # this preserves the bits of SRR1 that are not supposed to change:
86 # MSR.IR,DR,PMM,RI,LE (0-5) and MR,FP,ME,FE0 (11-14)
87 # i would suggest reading v3.0C p1063 Book III section 7.2.1 for
88 # advice but it's so obscure and indirect, that it's just easier
89 # to copy microwatt behaviour. see writeback.vhdl
90 # IMPORTANT: PowerDecoder2 needed to actually read SRR1 for
91 # it to have the contents *of* SRR1 to copy over!
92 comb += msr_copy(srr1_o.data, msr_i, False) # old MSR
93 comb += srr1_o.data[16:22].eq(srr1_i[0:6]) # IR,DR,PMM,RI,LE
94 comb += srr1_o.data[27:31].eq(srr1_i[11:15]) # MR,FP,ME,FE0
95 comb += srr1_o.ok.eq(1)
96
97 # take a copy of the current SVSTATE into SVSRR0
98 comb += svsrr0_o.data.eq(svstate_i) # old SVSTATE
99 comb += svsrr0_o.ok.eq(1)
100
101 def msr_exception(self, m, trap_addr, msr_hv=None):
102 """msr_exception - sets bits in MSR specific to an exception.
103 the full list of what needs to be done is given in V3.0B
104 Book III Section 6.5 p1063 however it turns out that for the
105 majority of cases (microwatt showing the way, here), all these
106 bits are all set by all (implemented) interrupt types. this
107 may change in the future, hence the (unused) trap_addr argument
108 """
109 comb = m.d.comb
110 op = self.i.ctx.op
111 msr_i, msr_o = op.msr, self.o.msr
112 comb += msr_o.data.eq(msr_i) # copy msr, first, then modify
113 comb += msr_o.data[MSR.SF].eq(1)
114 comb += msr_o.data[MSR.EE].eq(0)
115 comb += msr_o.data[MSR.PR].eq(0)
116 comb += msr_o.data[MSR.IR].eq(0)
117 comb += msr_o.data[MSR.DR].eq(0)
118 comb += msr_o.data[MSR.RI].eq(0)
119 comb += msr_o.data[MSR.LE].eq(1)
120 comb += msr_o.data[MSR.FE0].eq(0)
121 comb += msr_o.data[MSR.FE1].eq(0)
122 comb += msr_o.data[MSR.VSX].eq(0)
123 comb += msr_o.data[MSR.TM].eq(0)
124 comb += msr_o.data[MSR.VEC].eq(0)
125 comb += msr_o.data[MSR.FP].eq(0)
126 comb += msr_o.data[MSR.PMM].eq(0)
127 comb += msr_o.data[MSR.TEs].eq(0) # this is only 2 bits
128 comb += msr_o.data[MSR.TEe].eq(0) # so just zero them both
129 comb += msr_o.data[MSR.UND].eq(0)
130 if msr_hv is not None:
131 comb += msr_o.data[MSR.HV].eq(msr_hv)
132 comb += msr_o.ok.eq(1)
133
134 def ispec(self):
135 return TrapInputData(self.pspec)
136
137 def ospec(self):
138 return TrapOutputData(self.pspec)
139
140 def elaborate(self, platform):
141 m = Module()
142 comb = m.d.comb
143 op = self.i.ctx.op
144
145 # convenience variables
146 a_i, b_i = self.i.a, self.i.b
147 cia_i, msr_i, svstate_i = op.cia, op.msr, op.svstate
148 srr0_i, srr1_i, svsrr0_i = self.i.srr0, self.i.srr1, self.i.svsrr0
149 o = self.o.o
150 msr_o, nia_o, svstate_o = self.o.msr, self.o.nia, self.o.svstate
151 srr0_o, srr1_o, svsrr0_o = self.o.srr0, self.o.srr1, self.o.svsrr0
152 traptype, trapaddr = op.traptype, op.trapaddr
153
154 # take copy of D-Form TO field
155 i_fields = self.fields.FormD
156 to = Signal(i_fields.TO[0:-1].shape())
157 comb += to.eq(i_fields.TO[0:-1])
158
159 # signed/unsigned temporaries for RA and RB
160 a_s = Signal(signed(64), reset_less=True)
161 b_s = Signal(signed(64), reset_less=True)
162
163 a = Signal(64, reset_less=True)
164 b = Signal(64, reset_less=True)
165
166 # set up A and B comparison (truncate/sign-extend if 32 bit)
167 with m.If(op.is_32bit):
168 comb += a_s.eq(exts(a_i, 32, 64))
169 comb += b_s.eq(exts(b_i, 32, 64))
170 comb += a.eq(a_i[0:32])
171 comb += b.eq(b_i[0:32])
172 with m.Else():
173 comb += a_s.eq(a_i)
174 comb += b_s.eq(b_i)
175 comb += a.eq(a_i)
176 comb += b.eq(b_i)
177
178 # establish comparison bits
179 lt_s = Signal(reset_less=True)
180 gt_s = Signal(reset_less=True)
181 lt_u = Signal(reset_less=True)
182 gt_u = Signal(reset_less=True)
183 equal = Signal(reset_less=True)
184
185 comb += lt_s.eq(a_s < b_s)
186 comb += gt_s.eq(a_s > b_s)
187 comb += lt_u.eq(a < b)
188 comb += gt_u.eq(a > b)
189 comb += equal.eq(a == b)
190
191 # They're in reverse bit order because POWER.
192 # Check V3.0B Book 1, Appendix C.6 for chart
193 trap_bits = Signal(5, reset_less=True)
194 comb += trap_bits.eq(Cat(gt_u, lt_u, equal, gt_s, lt_s))
195
196 # establish if the trap should go ahead (any tests requested in TO)
197 # or if traptype is set already
198 should_trap = Signal(reset_less=True)
199 comb += should_trap.eq((trap_bits & to).any() | traptype.any())
200
201 # TODO: some #defines for the bits n stuff.
202 with m.Switch(op.insn_type):
203
204 ###############
205 # TDI/TWI/TD/TW. v3.0B p90-91
206
207 with m.Case(MicrOp.OP_TRAP):
208 # trap instructions (tw, twi, td, tdi)
209 with m.If(should_trap):
210 # generate trap-type program interrupt
211 self.trap(m, trapaddr<<4, cia_i)
212 with m.If(traptype == 0):
213 # say trap occurred (see 3.0B Book III 6.5.9 p1074-6)
214 comb += srr1_o.data[PI.TRAP].eq(1)
215 with m.If(traptype & TT.PRIV):
216 comb += srr1_o.data[PI.PRIV].eq(1)
217 with m.If(traptype & TT.FP):
218 comb += srr1_o.data[PI.FP].eq(1)
219 with m.If(traptype & TT.ADDR):
220 comb += srr1_o.data[PI.ADR].eq(1)
221 with m.If((traptype & TT.MEMEXC).bool() &
222 (trapaddr == 0x400)):
223 # Instruction Storage Interrupt (ISI - 0x400)
224 # v3.0C Book III Chap 7.5.5 p1085
225 # decode exception bits, store in SRR1
226 exc = LDSTException("trapexc")
227 comb += exc.eq(op.ldst_exc)
228 comb += srr1_o.data[PI.INVALID].eq(exc.invalid)
229 comb += srr1_o.data[PI.PERMERR].eq(exc.perm_error)
230 comb += srr1_o.data[PI.ILLEG].eq(exc.badtree)
231 comb += srr1_o.data[PI.PRIV].eq(exc.rc_error)
232 with m.If(traptype & TT.EINT):
233 # do nothing unusual? see 3.0B Book III 6.5.7 p1073
234 pass
235 with m.If(traptype & TT.DEC):
236 # do nothing unusual?
237 pass
238 with m.If(traptype & TT.ILLEG):
239 comb += srr1_o.data[PI.ILLEG].eq(1)
240 comb += srr1_o.ok.eq(1)
241
242 # when SRR1 is written to, update MSR bits
243 self.msr_exception(m, trapaddr)
244
245 # and store SVSTATE in SVSRR0
246 comb += svsrr0_o.data.eq(svstate_i)
247 comb += svsrr0_o.ok.eq(1)
248
249 ###################
250 # MTMSR/D. v3.0B p TODO - move to MSR
251
252 with m.Case(MicrOp.OP_MTMSRD, MicrOp.OP_MTMSR):
253 # L => bit 16 in LSB0, bit 15 in MSB0 order
254 L = self.fields.FormX.L1[0:1] # X-Form field L1
255 # start with copy of msr
256 comb += msr_o.eq(msr_i)
257 with m.If(L):
258 # just update RI..EE
259 comb += msr_o.data[MSR.RI].eq(a_i[MSR.RI])
260 comb += msr_o.data[MSR.EE].eq(a_i[MSR.EE])
261 with m.Else():
262 # Architecture says to leave out bits 3 (HV), 51 (ME)
263 # and 63 (LE) (IBM bit numbering)
264 with m.If(op.insn_type == MicrOp.OP_MTMSRD):
265 # not MSB0 notation here!
266 for stt, end in [(1,12), (13, 60), (61, 64)]:
267 comb += msr_o.data[stt:end].eq(a_i[stt:end])
268 # put *back* bits 29-31 (MSB0 notation)
269 bits = field_slice(29, 31)
270 with m.If((msr_i[bits] == Const(0b010, 3)) &
271 (a_i[bits] == Const(0b000, 3))):
272 comb += msr_o.data[bits].eq(msr_i[bits])
273
274 with m.Else():
275 # mtmsr - 32-bit, only room for bottom 32 LSB flags
276 for stt, end in [(1,12), (13, 32)]:
277 comb += msr_o.data[stt:end].eq(a_i[stt:end])
278 # check problem state: if set, not permitted to set EE,IR,DR
279 msr_check_pr(m, a_i, msr_o.data)
280
281 # Per https://bugs.libre-soc.org/show_bug.cgi?id=325#c123,
282 # this actually *is* in the microwatt code now.
283 #
284 # hypervisor stuff. here: bits 3 (HV) and 51 (ME) were
285 # copied over by msr_copy but if HV was not set we need
286 # the *original* (msr_i) bits
287 # XXX taking this out to see what happens when running
288 # linux-5.7 microwatt buildroot. microwatt does not
289 # implement HV, so this is unlikely to work. 0x900
290 # linux kernel exception handling tends to support this
291 # with m.If(~msr_i[MSR.HV]):
292 # comb += msr_o.data[MSR.HV].eq(msr_i[MSR.HV])
293 # comb += msr_o.data[MSR.ME].eq(msr_i[MSR.ME])
294
295 comb += msr_o.ok.eq(1)
296
297 ###################
298 # MFMSR. v3.0B p TODO - move from MSR
299
300 with m.Case(MicrOp.OP_MFMSR):
301 # some of the bits need zeroing? apparently not
302 comb += o.data.eq(msr_i)
303 comb += o.ok.eq(1)
304
305 ###################
306 # RFID. v3.0B p955
307
308 with m.Case(MicrOp.OP_RFID):
309
310 # return addr was in srr0
311 comb += nia_o.data.eq(br_ext(srr0_i[2:]))
312 comb += nia_o.ok.eq(1)
313
314 # svstate was in svsrr0
315 comb += svstate_o.data.eq(svstate_i)
316 comb += svstate_o.ok.eq(1)
317
318 # MSR was in srr1: copy it over, however *caveats below*
319 comb += msr_copy(msr_o.data, srr1_i, zero_me=False) # don't zero
320
321 if False: # XXX no - not doing hypervisor yet
322 with m.If(~self.i.ctx.op.insn[9]): # XXX BAD HACK! (hrfid)
323 with m.If(field(msr_i, 3)): # HV
324 comb += field(msr_o, 51).eq(field(srr1_i, 51)) # ME
325 with m.Else():
326 comb += field(msr_o, 51).eq(field(msr_i, 51)) # ME
327 else:
328 # same as microwatt: treat MSR.ME rfid same as hrfid
329 comb += field(msr_o, 51).eq(field(srr1_i, 51)) # ME
330
331 # check problem state: if set, not permitted to set EE,IR,DR
332 msr_check_pr(m, srr1_i, msr_o.data)
333
334 # don't understand but it's in the spec. again: bits 32-34
335 # are copied from srr1_i and need *restoring* to msr_i
336
337 bits = field_slice(29, 31) # bits 29, 30, 31 (Power notation)
338 with m.If((msr_i[bits] == Const(0b010, 3)) &
339 (srr1_i[bits] == Const(0b000, 3))):
340 comb += msr_o.data[bits].eq(msr_i[bits])
341
342 comb += msr_o.ok.eq(1)
343
344 #################
345 # SC. v3.0B p952
346
347 with m.Case(MicrOp.OP_SC):
348 # scv is not covered here. currently an illegal instruction.
349 # raising "illegal" is the decoder's job, not ours, here.
350
351 # According to V3.0B, Book II, section 3.3.1, the System Call
352 # instruction allows you to trap directly into the hypervisor
353 # if the opcode's LEV sub-field is equal to 1.
354 # however we are following *microwatt* - which has
355 # not implemented hypervisor.
356
357 # jump to the trap address, return at cia+4
358 self.trap(m, 0xc00, cia_i+4)
359 self.msr_exception(m, 0xc00)
360
361 # TODO (later)
362 #with m.Case(MicrOp.OP_ADDPCIS):
363 # pass
364
365 comb += self.o.ctx.eq(self.i.ctx)
366
367 return m