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