move cia and msr to trap input record
[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):
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.ok.eq(1)
100
101 def ispec(self):
102 return TrapInputData(self.pspec)
103
104 def ospec(self):
105 return TrapOutputData(self.pspec)
106
107 def elaborate(self, platform):
108 m = Module()
109 comb = m.d.comb
110 op = self.i.ctx.op
111
112 # convenience variables
113 a_i, b_i, cia_i, msr_i = self.i.a, self.i.b, op.cia, op.msr
114 srr0_i, srr1_i = self.i.srr0, self.i.srr1
115 o, msr_o, nia_o = self.o.o, self.o.msr, self.o.nia
116 srr0_o, srr1_o = self.o.srr0, self.o.srr1
117 traptype, trapaddr = op.traptype, op.trapaddr
118
119 # take copy of D-Form TO field
120 i_fields = self.fields.FormD
121 to = Signal(i_fields.TO[0:-1].shape())
122 comb += to.eq(i_fields.TO[0:-1])
123
124 # signed/unsigned temporaries for RA and RB
125 a_s = Signal(signed(64), reset_less=True)
126 b_s = Signal(signed(64), reset_less=True)
127
128 a = Signal(64, reset_less=True)
129 b = Signal(64, reset_less=True)
130
131 # set up A and B comparison (truncate/sign-extend if 32 bit)
132 with m.If(op.is_32bit):
133 comb += a_s.eq(exts(a_i, 32, 64))
134 comb += b_s.eq(exts(b_i, 32, 64))
135 comb += a.eq(a_i[0:32])
136 comb += b.eq(b_i[0:32])
137 with m.Else():
138 comb += a_s.eq(a_i)
139 comb += b_s.eq(b_i)
140 comb += a.eq(a_i)
141 comb += b.eq(b_i)
142
143 # establish comparison bits
144 lt_s = Signal(reset_less=True)
145 gt_s = Signal(reset_less=True)
146 lt_u = Signal(reset_less=True)
147 gt_u = Signal(reset_less=True)
148 equal = Signal(reset_less=True)
149
150 comb += lt_s.eq(a_s < b_s)
151 comb += gt_s.eq(a_s > b_s)
152 comb += lt_u.eq(a < b)
153 comb += gt_u.eq(a > b)
154 comb += equal.eq(a == b)
155
156 # They're in reverse bit order because POWER.
157 # Check V3.0B Book 1, Appendix C.6 for chart
158 trap_bits = Signal(5, reset_less=True)
159 comb += trap_bits.eq(Cat(gt_u, lt_u, equal, gt_s, lt_s))
160
161 # establish if the trap should go ahead (any tests requested in TO)
162 # or if traptype is set already
163 should_trap = Signal(reset_less=True)
164 comb += should_trap.eq((trap_bits & to).any() | traptype.any())
165
166 # TODO: some #defines for the bits n stuff.
167 with m.Switch(op.insn_type):
168 #### trap ####
169 with m.Case(MicrOp.OP_TRAP):
170 # trap instructions (tw, twi, td, tdi)
171 with m.If(should_trap):
172 # generate trap-type program interrupt
173 self.trap(m, trapaddr<<4, cia_i)
174 with m.If(traptype == 0):
175 # say trap occurred (see 3.0B Book III 6.5.9 p1074-6)
176 comb += srr1_o.data[PI.TRAP].eq(1)
177 with m.If(traptype & TT.PRIV):
178 comb += srr1_o.data[PI.PRIV].eq(1)
179 with m.If(traptype & TT.FP):
180 comb += srr1_o.data[PI.FP].eq(1)
181 with m.If(traptype & TT.ADDR):
182 comb += srr1_o.data[PI.ADR].eq(1)
183 with m.If(traptype & TT.ILLEG):
184 comb += srr1_o.data[PI.ILLEG].eq(1)
185 comb += srr1_o.ok.eq(1)
186
187 # when SRR1 is written to, update MSR bits
188 self.msr_exception(m, trapaddr)
189
190 # move to MSR
191 with m.Case(MicrOp.OP_MTMSRD, MicrOp.OP_MTMSR):
192 L = self.fields.FormX.L[0:-1] # X-Form field L
193 # start with copy of msr
194 comb += msr_o.eq(msr_i)
195 with m.If(L):
196 # just update RI..EE
197 comb += msr_o.data[MSR.RI].eq(a_i[MSR.RI])
198 comb += msr_o.data[MSR.EE].eq(a_i[MSR.EE])
199 with m.Else():
200 # Architecture says to leave out bits 3 (HV), 51 (ME)
201 # and 63 (LE) (IBM bit numbering)
202 with m.If(op.insn_type == MicrOp.OP_MTMSRD):
203 for stt, end in [(1,12), (13, 60), (61, 64)]:
204 comb += msr_o.data[stt:end].eq(a_i[stt:end])
205 with m.Else():
206 # mtmsr - 32-bit, only room for bottom 32 LSB flags
207 for stt, end in [(1,12), (13, 32)]:
208 comb += msr_o.data[stt:end].eq(a_i[stt:end])
209 msr_check_pr(m, msr_o.data)
210 comb += msr_o.ok.eq(1)
211
212 # move from MSR
213 with m.Case(MicrOp.OP_MFMSR):
214 # TODO: some of the bits need zeroing? apparently not
215 comb += o.data.eq(msr_i)
216 comb += o.ok.eq(1)
217
218 with m.Case(MicrOp.OP_RFID):
219 # XXX f_out.virt_mode <= b_in(MSR.IR) or b_in(MSR.PR);
220 # XXX f_out.priv_mode <= not b_in(MSR.PR);
221
222 # return addr was in srr0
223 comb += nia_o.data.eq(br_ext(srr0_i[2:]))
224 comb += nia_o.ok.eq(1)
225
226 # MSR was in srr1: copy it over, however *caveats below*
227 comb += msr_copy(msr_o.data, srr1_i, zero_me=False) # don't zero
228
229 # check problem state
230 msr_check_pr(m, msr_o.data)
231
232 # hypervisor stuff. here: bits 3 (HV) and 51 (ME) were
233 # copied over by msr_copy but if HV was not set we need
234 # the *original* (msr_i) bits
235 with m.If(~msr_i[MSR.HV]):
236 comb += msr_o.data[MSR.HV].eq(msr_i[MSR.HV])
237 comb += msr_o.data[MSR.ME].eq(msr_i[MSR.ME])
238
239 # don't understand but it's in the spec. again: bits 32-34
240 # are copied from srr1_i and need *restoring* to msr_i
241 bits = slice(63-31,63-29+1) # bits 29, 30, 31 (Power notation)
242 with m.If((msr_i[bits] == Const(0b010, 3)) &
243 (srr1_i[bits] == Const(0b000, 3))):
244 comb += msr_o.data[bits].eq(msr_i[bits])
245
246 comb += msr_o.ok.eq(1)
247
248 # OP_SC
249 with m.Case(MicrOp.OP_SC):
250 # scv is not covered here. currently an illegal instruction.
251 # raising "illegal" is the decoder's job, not ours, here.
252
253 # jump to the trap address, return at cia+4
254 self.trap(m, 0xc00, cia_i+4)
255
256 # and update several MSR bits
257 self.msr_exception(m, 0xc00)
258
259 # TODO (later)
260 #with m.Case(MicrOp.OP_ADDPCIS):
261 # pass
262
263 comb += self.o.ctx.eq(self.i.ctx)
264
265 return m