167 lines
4.9 KiB
Plaintext
167 lines
4.9 KiB
Plaintext
import GetPut::*;
|
|
|
|
import IsaCfg::*;
|
|
import RV_ISA::*;
|
|
|
|
typedef Bit#(2) XLENEncoding;
|
|
XLENEncoding xlen_32 = 2'b01;
|
|
XLENEncoding xlen_64 = 2'b10;
|
|
XLENEncoding xlen_128 = 2'b11;
|
|
|
|
typedef Bit#(2) FSVSState;
|
|
FSVSState fsvs_OFF = 2'b00;
|
|
FSVSState fsvs_INITIAL = 2'b01;
|
|
FSVSState fsvs_CLEAN = 2'b10;
|
|
FSVSState fsvs_DIRTY = 2'b11;
|
|
|
|
typedef Bit#(2) XSState;
|
|
XSState xs_ALL_OFF = 2'b00;
|
|
XSState xs_NONE_DIRTY_OR_CLEAN = 2'b01;
|
|
XSState xs_NONE_DIRTY_SOME_CLEAN = 2'b10;
|
|
XSState xs_SOME_DIRTY = 2'b11;
|
|
|
|
typedef struct {
|
|
Bool sie; // Supervisor Interrupt Enable
|
|
Bool mie; // Machine Interrupt Enable
|
|
Bool spie; // Supervisor Mode Interupts Enabled During Trap
|
|
Bool ube; // User Mode Data Accesses are Big Endian
|
|
Bool mpie; // Machine Mode Interrupts Enabled During Trap
|
|
Bool spp; // Supervisor Previous Privilege Mode
|
|
FSVSState vs; // Vector Extension State
|
|
RVPrivilegeLevel mpp; // Machine Previous Privilege Level
|
|
FSVSState fs; // Floating Point Status
|
|
XSState xs; // User Mode Extension Status
|
|
Bool mprv; // Modify Privilege Mode For Loads/Stores
|
|
Bool sum; // Permit Supervisor User Memory Access
|
|
Bool mxr; // Make Executable Pages Readable
|
|
Bool tvm; // Trap Virtual Memory Management Accesses
|
|
Bool tw; // Timeout-Wait
|
|
Bool tsr; // Trap SRET Instruction
|
|
|
|
XLENEncoding uxl; // User Mode XLEN value (RV64 only)
|
|
XLENEncoding sxl; // Supervisor Mode XLEN value (RV64 only)
|
|
|
|
Bool sbe; // Supervisor Mode Data Accesses are Big Endian
|
|
Bool mbe; // Machine Mode Data Accesses are Big Endian
|
|
} MachineStatus deriving(Bits, Eq, FShow);
|
|
|
|
instance DefaultValue#(MachineStatus);
|
|
defaultValue = MachineStatus {
|
|
sie: False,
|
|
mie: False,
|
|
spie: False,
|
|
ube: False,
|
|
mpie: False,
|
|
spp: False,
|
|
vs: fsvs_OFF,
|
|
mpp: priv_MACHINE,
|
|
fs: fsvs_OFF,
|
|
xs: xs_ALL_OFF,
|
|
mprv: False,
|
|
sum: False,
|
|
mxr: False,
|
|
tvm: False,
|
|
tw: False,
|
|
tsr: False,
|
|
|
|
uxl: xlen_64,
|
|
sxl: xlen_64,
|
|
|
|
sbe: False,
|
|
mbe: False
|
|
};
|
|
endinstance
|
|
|
|
interface MachineStatus_Ifc#(numeric type xlen);
|
|
method Bit#(xlen) pack;
|
|
method Action unpack(Bit#(xlen) bits);
|
|
interface Get#(MachineStatus) getMachineStatus;
|
|
interface Put#(MachineStatus) putMachineStatus;
|
|
endinterface
|
|
|
|
module mkMachineStatus#(IsaCfg#(xlen) cfg)(MachineStatus_Ifc#(xlen))
|
|
provisos(
|
|
Add#(a__, 32, xlen)
|
|
);
|
|
Reg#(MachineStatus) mstatus <- mkReg(defaultValue);
|
|
|
|
function Bit#(32) packLower;
|
|
return {
|
|
9'b0,
|
|
pack(mstatus.tsr),
|
|
pack(mstatus.tw),
|
|
pack(mstatus.tvm),
|
|
pack(mstatus.mxr),
|
|
pack(mstatus.sum),
|
|
pack(mstatus.mprv),
|
|
pack(mstatus.xs),
|
|
pack(mstatus.fs),
|
|
pack(mstatus.mpp),
|
|
pack(mstatus.vs),
|
|
pack(mstatus.spp),
|
|
pack(mstatus.mpie),
|
|
pack(mstatus.ube),
|
|
pack(mstatus.spie),
|
|
1'b0,
|
|
pack(mstatus.mie),
|
|
1'b0,
|
|
pack(mstatus.sie),
|
|
1'b0
|
|
};
|
|
endfunction
|
|
|
|
function Bit#(32) packUpper;
|
|
return {
|
|
26'b0,
|
|
pack(mstatus.mbe),
|
|
pack(mstatus.sbe),
|
|
pack(mstatus.sxl),
|
|
pack(mstatus.uxl)
|
|
};
|
|
endfunction
|
|
|
|
method Bit#(xlen) pack;
|
|
Bit#(32) lower = packLower;
|
|
Bit#(xlen) mstatus_ = 0;
|
|
|
|
Bit#(1) sd = ((mstatus.vs | mstatus.fs | mstatus.xs) == 0 ? 0 : 1);
|
|
mstatus_[valueof(xlen)-1] = sd;
|
|
mstatus_[31:0] = lower;
|
|
|
|
if (valueof(xlen) == 64) begin
|
|
mstatus_[valueof(xlen)-2:32] = packUpper;
|
|
end
|
|
|
|
return mstatus_;
|
|
endmethod
|
|
|
|
method Action unpack(Bit#(xlen) bits);
|
|
endmethod
|
|
|
|
interface Get getMachineStatus = toGet(mstatus);
|
|
interface Put putMachineStatus;
|
|
method Action put(MachineStatus value);
|
|
//
|
|
// Only MPP, MIE, and MIE are writable.
|
|
//
|
|
MachineStatus mstatus_ = mstatus;
|
|
|
|
if (cfg.extS) begin
|
|
mstatus_.mpp = value.mpp;
|
|
end else begin
|
|
// Supervisor mode not supported, ensure only USER and MACHINE
|
|
// mode are set in MPP.
|
|
RVPrivilegeLevel requestedMPP = value.mpp;
|
|
if (requestedMPP == priv_USER || requestedMPP == priv_MACHINE) begin
|
|
mstatus_.mpp = requestedMPP;
|
|
end
|
|
end
|
|
|
|
mstatus_.mpie = value.mpie;
|
|
mstatus_.mie = value.mie;
|
|
|
|
mstatus <= mstatus_;
|
|
endmethod
|
|
endinterface
|
|
endmodule
|