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