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.
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/
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
19 from soc
.decoder
.power_fields
import DecodeFields
20 from soc
.decoder
.power_fieldsn
import SignalBitRange
22 from soc
.decoder
.power_decoder2
import (TT_FP
, TT_PRIV
, TT_TRAP
, TT_ADDR
,
24 from soc
.consts
import MSR
, PI
27 def msr_copy(msr_o
, msr_i
, zero_me
=True):
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).
41 for stt
, end
in [(0,16), (22, 27), (31, 64)]:
42 l
.append(msr_o
[stt
:end
].eq(msr_i
[stt
:end
]))
46 def msr_check_pr(m
, msr
):
47 """msr_check_pr: checks "problem state"
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
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()
62 def trap(self
, m
, trap_addr
, return_addr
):
63 """trap. sets new PC, stores MSR and old PC in SRR1 and SRR0
67 nia_o
, srr0_o
, srr1_o
= self
.o
.nia
, self
.o
.srr0
, self
.o
.srr1
70 comb
+= nia_o
.data
.eq(trap_addr
)
71 comb
+= nia_o
.ok
.eq(1)
73 # addr to begin from on return
74 comb
+= srr0_o
.data
.eq(return_addr
)
75 comb
+= srr0_o
.ok
.eq(1)
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)
82 return TrapInputData(self
.pspec
)
85 return TrapOutputData(self
.pspec
)
87 def elaborate(self
, platform
):
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
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])
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)
108 a
= Signal(64, reset_less
=True)
109 b
= Signal(64, reset_less
=True)
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])
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)
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
)
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
))
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())
146 # TODO: some #defines for the bits n stuff.
147 with m
.Switch(op
.insn_type
):
149 with m
.Case(MicrOp
.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)
167 with m
.Case(MicrOp
.OP_MTMSRD
, MicrOp
.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
)
173 comb
+= msr_o
.data
[MSR
.RI
].eq(a_i
[MSR
.RI
])
174 comb
+= msr_o
.data
[MSR
.EE
].eq(a_i
[MSR
.EE
])
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)
184 with m
.Case(MicrOp
.OP_MFMSR
):
185 # TODO: some of the bits need zeroing? apparently not
186 comb
+= o
.data
.eq(msr_i
)
189 with m
.Case(MicrOp
.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);
193 # return addr was in srr0
194 comb
+= nia_o
.data
.eq(br_ext(srr0_i
[2:]))
195 comb
+= nia_o
.ok
.eq(1)
197 comb
+= msr_copy(msr_o
.data
, srr1_i
, zero_me
=False) # don't zero
198 msr_check_pr(m
, msr_o
.data
)
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])
209 comb
+= msr_o
.data
[63-31:63-29].eq(msr_i
[63-31:63-29])
210 comb
+= msr_o
.ok
.eq(1)
213 with m
.Case(MicrOp
.OP_SC
):
214 # TODO: scv must generate illegal instruction. this is
215 # the decoder's job, not ours, here.
217 # jump to the trap address, return at cia+4
218 self
.trap(m
, 0xc00, cia_i
+4)
221 #with m.Case(MicrOp.OP_ADDPCIS):
224 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)