8c68e7fc9051b49c92eea986a3a24b59fdfc16d9
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 InternalOp
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(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)
167 with m
.Case(InternalOp
.OP_MTMSRD
):
168 L
= self
.fields
.FormX
.L
[0:-1] # X-Form field L
171 comb
+= msr_o
.data
[MSR
.RI
:MSR
.EE
].eq(a_i
[MSR
.RI
:MSR
.EE
])
173 # Architecture says to leave out bits 3 (HV), 51 (ME)
174 # and 63 (LE) (IBM bit numbering)
175 for stt
, end
in [(1,12), (13, 60), (61, 64)]:
176 comb
+= msr_o
.data
[stt
:end
].eq(a_i
[stt
:end
])
177 msr_check_pr(m
, msr_o
.data
)
178 comb
+= msr_o
.ok
.eq(1)
181 with m
.Case(InternalOp
.OP_MFMSR
):
182 # TODO: some of the bits need zeroing? apparently not
183 comb
+= o
.data
.eq(msr_i
)
186 with m
.Case(InternalOp
.OP_RFID
):
187 # XXX f_out.virt_mode <= b_in(MSR.IR) or b_in(MSR.PR);
188 # XXX f_out.priv_mode <= not b_in(MSR.PR);
190 # return addr was in srr0
191 comb
+= nia_o
.data
.eq(br_ext(srr0_i
[2:]))
192 comb
+= nia_o
.ok
.eq(1)
194 comb
+= msr_copy(msr_o
.data
, srr1_i
, zero_me
=False) # don't zero
195 msr_check_pr(m
, msr_o
.data
)
198 comb
+= msr_o
.data
[MSR
.HV
].eq(msr_i
[MSR
.HV
] & srr1_i
[MSR
.HV
])
199 comb
+= msr_o
.data
[MSR
.ME
].eq((msr_i
[MSR
.HV
] & srr1_i
[MSR
.HV
]) |
200 (~msr_i
[MSR
.HV
] & srr1_i
[MSR
.HV
]))
201 # don't understand but it's in the spec
202 with m
.If((msr_i
[63-31:63-29] != Const(0b010, 3)) |
203 (srr1_i
[63-31:63-29] != Const(0b000, 3))):
204 comb
+= msr_o
.data
[63-31:63-29].eq(srr1_i
[63-31:63-29])
206 comb
+= msr_o
.data
[63-31:63-29].eq(msr_i
[63-31:63-29])
207 comb
+= msr_o
.ok
.eq(1)
210 with m
.Case(InternalOp
.OP_SC
):
211 # TODO: scv must generate illegal instruction. this is
212 # the decoder's job, not ours, here.
214 # jump to the trap address, return at cia+4
215 self
.trap(m
, 0xc00, cia_i
+4)
218 #with m.Case(InternalOp.OP_ADDPCIS):
221 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)