from soc.decoder.power_fields import DecodeFields
from soc.decoder.power_fieldsn import SignalBitRange
-# TODO at some point move these to their own module (for use elsewhere)
-# TODO: turn these into python constants (just "MSR_SF = 63-0 # comment" etc.)
-"""
- Listed in V3.0B Book III Chap 4.2.1
- -- MSR bit numbers
- constant MSR_SF : integer := (63 - 0); -- Sixty-Four bit mode
- constant MSR_HV : integer := (63 - 3); -- Hypervisor state
- constant MSR_S : integer := (63 - 41); -- Secure state
- constant MSR_EE : integer := (63 - 48); -- External interrupt Enable
- constant MSR_PR : integer := (63 - 49); -- PRoblem state
- constant MSR_FP : integer := (63 - 50); -- FP available
- constant MSR_ME : integer := (63 - 51); -- Machine Check int enable
- constant MSR_IR : integer := (63 - 58); -- Instruction Relocation
- constant MSR_DR : integer := (63 - 59); -- Data Relocation
- constant MSR_PMM : integer := (63 - 60); -- Performance Monitor Mark
- constant MSR_RI : integer := (63 - 62); -- Recoverable Interrupt
- constant MSR_LE : integer := (63 - 63); -- Little Endian
-"""
+
+# Listed in V3.0B Book III Chap 4.2.1
+# MSR bit numbers
+MSR_SF = (63 - 0) # Sixty-Four bit mode
+MSR_HV = (63 - 3) # Hypervisor state
+MSR_S = (63 - 41) # Secure state
+MSR_EE = (63 - 48) # External interrupt Enable
+MSR_PR = (63 - 49) # PRoblem state
+MSR_FP = (63 - 50) # FP available
+MSR_ME = (63 - 51) # Machine Check int enable
+MSR_IR = (63 - 58) # Instruction Relocation
+MSR_DR = (63 - 59) # Data Relocation
+MSR_PMM = (63 - 60) # Performance Monitor Mark
+MSR_RI = (63 - 62) # Recoverable Interrupt
+MSR_LE = (63 - 63) # Little Endian
+
class TrapMainStage(PipeModBase):
def __init__(self, pspec):
m = Module()
comb = m.d.comb
op = self.i.ctx.op
- a_i, b_i = self.i.a, self.i.b
+
+ # convenience variables
+ a_i, b_i, cia_i, msr_i = self.i.a, self.i.b, self.i.cia, self.i.msr
+ o, msr_o, nia_o = self.o.o, self.o.msr, self.o.nia
+ srr0_o, srr1_o = self.o.srr0, self.o.srr1
# take copy of D-Form TO field
i_fields = self.fields.FormD
ctrl_tmp.srr1(63 - 46) <= '1';
"""
with m.If(should_trap):
- comb += self.o.nia.data.eq(0x700) # trap address
- comb += self.o.nia.ok.eq(1)
- comb += self.o.srr1.data.eq(self.i.msr) # old MSR
- comb += self.o.srr1.data[63-46].eq(1) # XXX which bit?
- comb += self.o.srr1.ok.eq(1)
- comb += self.o.srr0.data.eq(self.i.cia) # old PC
- comb += self.o.srr0.ok.eq(1)
+ comb += nia_o.data.eq(0x700) # trap address
+ comb += nia_o.ok.eq(1)
+ comb += srr1_o.data.eq(msr_i) # old MSR
+ comb += srr1_o.data[63-46].eq(1) # XXX which bit?
+ comb += srr1_o.ok.eq(1)
+ comb += srr0_o.data.eq(cia_i) # old PC
+ comb += srr0_o.ok.eq(1)
# move to SPR
with m.Case(InternalOp.OP_MTMSR):
ctrl_tmp.msr(MSR_IR) <= '1';
ctrl_tmp.msr(MSR_DR) <= '1';
"""
+ """
+ L = self.fields.FormXL.L[0:-1]
+ if e_in.insn(16) = '1' then <-- this is X-form field "L".
+ -- just update EE and RI
+ ctrl_tmp.msr(MSR_EE) <= c_in(MSR_EE);
+ ctrl_tmp.msr(MSR_RI) <= c_in(MSR_RI);
+ """
L = self.fields.FormX.L[0:-1]
with m.If(L):
- comb += self.o.msr[MSR_EE].eq(self.i.msr[MSR_EE])
- comb += self.o.msr[MSR_RI].eq(self.i.msr[MSR_RI])
+ comb += msr_o[MSR_EE].eq(msr_i[MSR_EE])
+ comb += msr_o[MSR_RI].eq(msr_i[MSR_RI])
with m.Else():
for stt, end in [(1,12), (13, 60), (61, 64)]:
- comb += self.o.msr.data[stt:end].eq(a[stt:end])
+ comb += msr_o.data[stt:end].eq(a_i[stt:end])
with m.If(a[MSR_PR]):
- self.o.msr[MSR_EE].eq(1)
- self.o.msr[MSR_IR].eq(1)
- self.o.msr[MSR_DR].eq(1)
- comb += self.o.msr.ok.eq(1)
+ msr_o[MSR_EE].eq(1)
+ msr_o[MSR_IR].eq(1)
+ msr_o[MSR_DR].eq(1)
+ comb += msr_o.ok.eq(1)
# move from SPR
with m.Case(InternalOp.OP_MFMSR):
result := ctrl.msr;
result_en := '1';
"""
- comb += self.o.o.data.eq(self.i.msr)
- comb += self.o.o.ok.eq(1)
+ comb += o.data.eq(msr_i)
+ comb += o.ok.eq(1)
with m.Case(InternalOp.OP_RFID):
"""
ctrl_tmp.msr(MSR_DR) <= '1';
end if;
"""
- comb += self.o.nia.data.eq(br_ext(a[63:1] & 0))
- comb += self.o.nia.ok.eq(1)
+ comb += nia_o.data.eq(br_ext(a_i[2:]))
+ comb += nia_o.ok.eq(1)
for stt, end in [(0,16), (22, 27), (31, 64)]:
- comb += self.o.msr.data[stt:end].eq(a[stt:end])
+ comb += msr_o.data[stt:end].eq(b_i[stt:end])
with m.If(a[MSR_PR]):
- self.o.msr[MSR_EE].eq(1)
- self.o.msr[MSR_IR].eq(1)
- self.o.msr[MSR_DR].eq(1)
- comb += self.o.msr.ok.eq(1)
+ msr_o[MSR_EE].eq(1)
+ msr_o[MSR_IR].eq(1)
+ msr_o[MSR_DR].eq(1)
+ comb += msr_o.ok.eq(1)
with m.Case(InternalOp.OP_SC):
"""
ctrl_tmp.irq_nia <= std_logic_vector(to_unsigned(16#C00#, 64));
ctrl_tmp.srr1 <= msr_copy(ctrl.msr);
"""
- comb += self.o.nia.eq(0xC00) # trap address
- comb += self.o.nia.ok.eq(1)
- comb += self.o.srr1.data.eq(self.i.msr)
- comb += self.o.srr1.ok.eq(1)
+ comb += nia_o.eq(0xC00) # trap address
+ comb += nia_o.ok.eq(1)
+ comb += srr1_o.data.eq(msr_i)
+ comb += srr1_o.ok.eq(1)
# TODO (later)
#with m.Case(InternalOp.OP_ADDPCIS):