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