0ddb2823f13243ba8a54aa501b2c641514092980
[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 InternalOp
18
19 from soc.decoder.power_fields import DecodeFields
20 from soc.decoder.power_fieldsn import SignalBitRange
21
22 from soc.decoder.power_decoder2 import (TT_FP, TT_PRIV, TT_TRAP, TT_ADDR,
23 TT_ILLEG)
24 from soc.consts import MSR, PI
25
26
27 def msr_copy(msr_o, msr_i, zero_me=True):
28 """msr_copy
29 ISA says this:
30 Defined MSR bits are classified as either full func tion or partial
31 function. Full function MSR bits are saved in SRR1 or HSRR1 when
32 an interrupt other than a System Call Vectored interrupt occurs and
33 restored by rfscv, rfid, or hrfid, while partial function MSR bits
34 are not saved or restored. Full function MSR bits lie in the range
35 0:32, 37:41, and 48:63, and partial function MSR bits lie in the
36 range 33:36 and 42:47. (Note this is IBM bit numbering).
37 """
38 l = []
39 if zero_me:
40 l.append(msr_o.eq(0))
41 for stt, end in [(0,16), (22, 27), (31, 64)]:
42 l.append(msr_o[stt:end].eq(msr_i[stt:end]))
43 return l
44
45
46 def msr_check_pr(m, msr):
47 """msr_check_pr: checks "problem state"
48 """
49 comb = m.d.comb
50 with m.If(msr[MSR.PR]):
51 comb += msr[MSR.EE].eq(1) # set external interrupt bit
52 comb += msr[MSR.IR].eq(1) # set instruction relocation bit
53 comb += msr[MSR.DR].eq(1) # set data relocation bit
54
55
56 class TrapMainStage(PipeModBase):
57 def __init__(self, pspec):
58 super().__init__(pspec, "main")
59 self.fields = DecodeFields(SignalBitRange, [self.i.ctx.op.insn])
60 self.fields.create_specs()
61
62 def trap(self, m, trap_addr, return_addr):
63 """trap. sets new PC, stores MSR and old PC in SRR1 and SRR0
64 """
65 comb = m.d.comb
66 msr_i = self.i.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 ispec(self):
82 return TrapInputData(self.pspec)
83
84 def ospec(self):
85 return TrapOutputData(self.pspec)
86
87 def elaborate(self, platform):
88 m = Module()
89 comb = m.d.comb
90 op = self.i.ctx.op
91
92 # convenience variables
93 a_i, b_i, cia_i, msr_i = self.i.a, self.i.b, self.i.cia, self.i.msr
94 srr0_i, srr1_i = self.i.srr0, self.i.srr1
95 o, msr_o, nia_o = self.o.o, self.o.msr, self.o.nia
96 srr0_o, srr1_o = self.o.srr0, self.o.srr1
97 traptype, trapaddr = op.traptype, op.trapaddr
98
99 # take copy of D-Form TO field
100 i_fields = self.fields.FormD
101 to = Signal(i_fields.TO[0:-1].shape())
102 comb += to.eq(i_fields.TO[0:-1])
103
104 # signed/unsigned temporaries for RA and RB
105 a_s = Signal(signed(64), reset_less=True)
106 b_s = Signal(signed(64), reset_less=True)
107
108 a = Signal(64, reset_less=True)
109 b = Signal(64, reset_less=True)
110
111 # set up A and B comparison (truncate/sign-extend if 32 bit)
112 with m.If(op.is_32bit):
113 comb += a_s.eq(exts(a_i, 32, 64))
114 comb += b_s.eq(exts(b_i, 32, 64))
115 comb += a.eq(a_i[0:32])
116 comb += b.eq(b_i[0:32])
117 with m.Else():
118 comb += a_s.eq(a_i)
119 comb += b_s.eq(b_i)
120 comb += a.eq(a_i)
121 comb += b.eq(b_i)
122
123 # establish comparison bits
124 lt_s = Signal(reset_less=True)
125 gt_s = Signal(reset_less=True)
126 lt_u = Signal(reset_less=True)
127 gt_u = Signal(reset_less=True)
128 equal = Signal(reset_less=True)
129
130 comb += lt_s.eq(a_s < b_s)
131 comb += gt_s.eq(a_s > b_s)
132 comb += lt_u.eq(a < b)
133 comb += gt_u.eq(a > b)
134 comb += equal.eq(a == b)
135
136 # They're in reverse bit order because POWER.
137 # Check V3.0B Book 1, Appendix C.6 for chart
138 trap_bits = Signal(5, reset_less=True)
139 comb += trap_bits.eq(Cat(gt_u, lt_u, equal, gt_s, lt_s))
140
141 # establish if the trap should go ahead (any tests requested in TO)
142 # or if traptype is set already
143 should_trap = Signal(reset_less=True)
144 comb += should_trap.eq((trap_bits & to).any() | traptype.any())
145
146 # TODO: some #defines for the bits n stuff.
147 with m.Switch(op.insn_type):
148 #### trap ####
149 with m.Case(InternalOp.OP_TRAP):
150 # trap instructions (tw, twi, td, tdi)
151 with m.If(should_trap):
152 # generate trap-type program interrupt
153 self.trap(m, trapaddr<<4, cia_i)
154 with m.If(traptype == 0):
155 # say trap occurred (see 3.0B Book III 7.5.9)
156 comb += srr1_o.data[PI.TRAP].eq(1)
157 with m.If(traptype & TT_PRIV):
158 comb += srr1_o.data[PI.PRIV].eq(1)
159 with m.If(traptype & TT_FP):
160 comb += srr1_o.data[PI.FP].eq(1)
161 with m.If(traptype & TT_ADDR):
162 comb += srr1_o.data[PI.ADR].eq(1)
163 with m.If(traptype & TT_ILLEG):
164 comb += srr1_o.data[PI.ILLEG].eq(1)
165
166 # move to MSR
167 with m.Case(InternalOp.OP_MTMSRD, InternalOp.OP_MTMSR):
168 L = self.fields.FormX.L[0:-1] # X-Form field L
169 # start with copy of msr
170 comb += msr_o.eq(msr_i)
171 with m.If(L):
172 # just update RI..EE
173 comb += msr_o.data[MSR.RI].eq(a_i[MSR.RI])
174 comb += msr_o.data[MSR.EE].eq(a_i[MSR.EE])
175 with m.Else():
176 # Architecture says to leave out bits 3 (HV), 51 (ME)
177 # and 63 (LE) (IBM bit numbering)
178 for stt, end in [(1,12), (13, 60), (61, 64)]:
179 comb += msr_o.data[stt:end].eq(a_i[stt:end])
180 msr_check_pr(m, msr_o.data)
181 comb += msr_o.ok.eq(1)
182
183 # move from MSR
184 with m.Case(InternalOp.OP_MFMSR):
185 # TODO: some of the bits need zeroing? apparently not
186 comb += o.data.eq(msr_i)
187 comb += o.ok.eq(1)
188
189 with m.Case(InternalOp.OP_RFID):
190 # XXX f_out.virt_mode <= b_in(MSR.IR) or b_in(MSR.PR);
191 # XXX f_out.priv_mode <= not b_in(MSR.PR);
192
193 # return addr was in srr0
194 comb += nia_o.data.eq(br_ext(srr0_i[2:]))
195 comb += nia_o.ok.eq(1)
196 # MSR was in srr1
197 comb += msr_copy(msr_o.data, srr1_i, zero_me=False) # don't zero
198 msr_check_pr(m, msr_o.data)
199
200 # hypervisor stuff
201 comb += msr_o.data[MSR.HV].eq(msr_i[MSR.HV] & srr1_i[MSR.HV])
202 comb += msr_o.data[MSR.ME].eq((msr_i[MSR.HV] & srr1_i[MSR.HV]) |
203 (~msr_i[MSR.HV] & srr1_i[MSR.HV]))
204 # don't understand but it's in the spec
205 with m.If((msr_i[63-31:63-29] != Const(0b010, 3)) |
206 (srr1_i[63-31:63-29] != Const(0b000, 3))):
207 comb += msr_o.data[63-31:63-29].eq(srr1_i[63-31:63-29])
208 with m.Else():
209 comb += msr_o.data[63-31:63-29].eq(msr_i[63-31:63-29])
210 comb += msr_o.ok.eq(1)
211
212 # OP_SC
213 with m.Case(InternalOp.OP_SC):
214 # TODO: scv must generate illegal instruction. this is
215 # the decoder's job, not ours, here.
216
217 # jump to the trap address, return at cia+4
218 self.trap(m, 0xc00, cia_i+4)
219
220 # TODO (later)
221 #with m.Case(InternalOp.OP_ADDPCIS):
222 # pass
223
224 comb += self.o.ctx.eq(self.i.ctx)
225
226 return m