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