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