0737ced8f2621813de59b934cb2b4bbda323c2e8
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
)
23 from soc
.consts
import MSR
, PI
26 def msr_copy(msr_o
, msr_i
, zero_me
=True):
29 Defined MSR bits are classified as either full func tion or partial
30 function. Full function MSR bits are saved in SRR1 or HSRR1 when
31 an interrupt other than a System Call Vectored interrupt occurs and
32 restored by rfscv, rfid, or hrfid, while partial function MSR bits
33 are not saved or restored. Full function MSR bits lie in the range
34 0:32, 37:41, and 48:63, and partial function MSR bits lie in the
35 range 33:36 and 42:47. (Note this is IBM bit numbering).
40 for stt
, end
in [(0,16), (22, 27), (31, 64)]:
41 l
.append(msr_o
[stt
:end
].eq(msr_i
[stt
:end
]))
45 def msr_check_pr(m
, msr
):
46 """msr_check_pr: checks "problem state"
49 with m
.If(msr
[MSR
.PR
]):
50 comb
+= msr
[MSR
.EE
].eq(1) # set external interrupt bit
51 comb
+= msr
[MSR
.IR
].eq(1) # set instruction relocation bit
52 comb
+= msr
[MSR
.DR
].eq(1) # set data relocation bit
55 class TrapMainStage(PipeModBase
):
56 def __init__(self
, pspec
):
57 super().__init
__(pspec
, "main")
58 self
.fields
= DecodeFields(SignalBitRange
, [self
.i
.ctx
.op
.insn
])
59 self
.fields
.create_specs()
61 def trap(self
, m
, trap_addr
, return_addr
):
62 """trap. sets new PC, stores MSR and old PC in SRR1 and SRR0
66 nia_o
, srr0_o
, srr1_o
= self
.o
.nia
, self
.o
.srr0
, self
.o
.srr1
69 comb
+= nia_o
.data
.eq(trap_addr
)
70 comb
+= nia_o
.ok
.eq(1)
72 # addr to begin from on return
73 comb
+= srr0_o
.data
.eq(return_addr
)
74 comb
+= srr0_o
.ok
.eq(1)
76 # take a copy of the current MSR in SRR1
77 comb
+= msr_copy(srr1_o
.data
, msr_i
) # old MSR
78 comb
+= srr1_o
.ok
.eq(1)
81 return TrapInputData(self
.pspec
)
84 return TrapOutputData(self
.pspec
)
86 def elaborate(self
, platform
):
91 # convenience variables
92 a_i
, b_i
, cia_i
, msr_i
= self
.i
.a
, self
.i
.b
, self
.i
.cia
, self
.i
.msr
93 srr0_i
, srr1_i
= self
.i
.srr0
, self
.i
.srr1
94 o
, msr_o
, nia_o
= self
.o
.o
, self
.o
.msr
, self
.o
.nia
95 srr0_o
, srr1_o
= self
.o
.srr0
, self
.o
.srr1
96 traptype
, trapaddr
= op
.traptype
, op
.trapaddr
98 # take copy of D-Form TO field
99 i_fields
= self
.fields
.FormD
100 to
= Signal(i_fields
.TO
[0:-1].shape())
101 comb
+= to
.eq(i_fields
.TO
[0:-1])
103 # signed/unsigned temporaries for RA and RB
104 a_s
= Signal(signed(64), reset_less
=True)
105 b_s
= Signal(signed(64), reset_less
=True)
107 a
= Signal(64, reset_less
=True)
108 b
= Signal(64, reset_less
=True)
110 # set up A and B comparison (truncate/sign-extend if 32 bit)
111 with m
.If(op
.is_32bit
):
112 comb
+= a_s
.eq(exts(a_i
, 32, 64))
113 comb
+= b_s
.eq(exts(b_i
, 32, 64))
114 comb
+= a
.eq(a_i
[0:32])
115 comb
+= b
.eq(b_i
[0:32])
122 # establish comparison bits
123 lt_s
= Signal(reset_less
=True)
124 gt_s
= Signal(reset_less
=True)
125 lt_u
= Signal(reset_less
=True)
126 gt_u
= Signal(reset_less
=True)
127 equal
= Signal(reset_less
=True)
129 comb
+= lt_s
.eq(a_s
< b_s
)
130 comb
+= gt_s
.eq(a_s
> b_s
)
131 comb
+= lt_u
.eq(a
< b
)
132 comb
+= gt_u
.eq(a
> b
)
133 comb
+= equal
.eq(a
== b
)
135 # They're in reverse bit order because POWER.
136 # Check V3.0B Book 1, Appendix C.6 for chart
137 trap_bits
= Signal(5, reset_less
=True)
138 comb
+= trap_bits
.eq(Cat(gt_u
, lt_u
, equal
, gt_s
, lt_s
))
140 # establish if the trap should go ahead (any tests requested in TO)
141 # or if traptype is set already
142 should_trap
= Signal(reset_less
=True)
143 comb
+= should_trap
.eq((trap_bits
& to
).any() | traptype
.any())
145 # TODO: some #defines for the bits n stuff.
146 with m
.Switch(op
.insn_type
):
148 with m
.Case(InternalOp
.OP_TRAP
):
149 # trap instructions (tw, twi, td, tdi)
150 with m
.If(should_trap
):
151 # generate trap-type program interrupt
152 self
.trap(m
, trapaddr
<<4, cia_i
)
153 with m
.If(traptype
== 0):
154 # say trap occurred (see 3.0B Book III 7.5.9)
155 comb
+= srr1_o
.data
[PI
.TRAP
].eq(1)
156 with m
.If(traptype
& TT_PRIV
):
157 comb
+= srr1_o
.data
[PI
.PRIV
].eq(1)
158 with m
.If(traptype
& TT_FP
):
159 comb
+= srr1_o
.data
[PI
.FP
].eq(1)
160 with m
.If(traptype
& TT_ADDR
):
161 comb
+= srr1_o
.data
[PI
.ADR
].eq(1)
164 with m
.Case(InternalOp
.OP_MTMSRD
):
165 L
= self
.fields
.FormX
.L
[0:-1] # X-Form field L
167 # just update EE and RI
168 comb
+= msr_o
.data
[MSR
.EE
].eq(a_i
[MSR
.EE
])
169 comb
+= msr_o
.data
[MSR
.RI
].eq(a_i
[MSR
.RI
])
171 # Architecture says to leave out bits 3 (HV), 51 (ME)
172 # and 63 (LE) (IBM bit numbering)
173 for stt
, end
in [(1,12), (13, 60), (61, 64)]:
174 comb
+= msr_o
.data
[stt
:end
].eq(a_i
[stt
:end
])
175 msr_check_pr(m
, msr_o
.data
)
176 comb
+= msr_o
.ok
.eq(1)
179 with m
.Case(InternalOp
.OP_MFMSR
):
180 # TODO: some of the bits need zeroing? apparently not
181 comb
+= o
.data
.eq(msr_i
)
184 with m
.Case(InternalOp
.OP_RFID
):
185 # XXX f_out.virt_mode <= b_in(MSR.IR) or b_in(MSR.PR);
186 # XXX f_out.priv_mode <= not b_in(MSR.PR);
188 # return addr was in srr0
189 comb
+= nia_o
.data
.eq(br_ext(srr0_i
[2:]))
190 comb
+= nia_o
.ok
.eq(1)
192 comb
+= msr_copy(msr_o
.data
, srr1_i
, zero_me
=False) # don't zero
193 msr_check_pr(m
, msr_o
.data
)
194 comb
+= msr_o
.ok
.eq(1)
197 with m
.Case(InternalOp
.OP_SC
):
198 # TODO: scv must generate illegal instruction. this is
199 # the decoder's job, not ours, here.
201 # jump to the trap address, return at cia+4
202 self
.trap(m
, 0xc00, cia_i
+4)
205 #with m.Case(InternalOp.OP_ADDPCIS):
208 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)