mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Improved permissions for CSR access
This commit is contained in:
parent
60f12a6f60
commit
679ff3455b
@ -36,7 +36,20 @@ random_stimulus = True
|
||||
random_order = False
|
||||
|
||||
|
||||
def main():
|
||||
def flow_control_test():
|
||||
with OpenOCD() as cvw:
|
||||
cvw.reset_dm()
|
||||
cvw.reset_hart()
|
||||
|
||||
cvw.halt()
|
||||
cvw.read_data("DCSR")
|
||||
for _ in range(50):
|
||||
cvw.step()
|
||||
cvw.read_data("PCM")
|
||||
cvw.resume()
|
||||
|
||||
|
||||
def register_rw_test():
|
||||
with OpenOCD() as cvw:
|
||||
registers = dict.fromkeys(cvw.register_translations.keys(),[])
|
||||
reg_addrs = list(registers.keys())
|
||||
@ -49,7 +62,7 @@ def main():
|
||||
cvw.reset_dm()
|
||||
cvw.reset_hart()
|
||||
|
||||
time.sleep(70) # wait for OpenSBI
|
||||
#time.sleep(70) # wait for OpenSBI
|
||||
|
||||
cvw.halt()
|
||||
|
||||
@ -140,4 +153,5 @@ def random_hex(reg_name):
|
||||
return "0x" + f"{(data & (2**size-1)):x}".rjust(pad, "0")
|
||||
|
||||
|
||||
main()
|
||||
#register_rw_test()
|
||||
flow_control_test()
|
||||
|
@ -141,8 +141,9 @@ module dm import cvw::*; #(parameter cvw_t P) (
|
||||
logic AckUnavail;
|
||||
logic DmActive; // This bit is used to (de)activate the DM. Toggling off-on acts as reset
|
||||
// DMStatus
|
||||
logic StickyUnavail;
|
||||
logic ImpEBreak;
|
||||
const logic NdmResetPending = 0;
|
||||
const logic StickyUnavail = 0;
|
||||
const logic ImpEBreak = 0; // TODO: change this to const 1 if implementing 1x32bit progbuf
|
||||
logic AllHaveReset;
|
||||
logic AnyHaveReset;
|
||||
logic AllResumeAck;
|
||||
@ -156,9 +157,9 @@ module dm import cvw::*; #(parameter cvw_t P) (
|
||||
logic AllHalted;
|
||||
logic AnyHalted;
|
||||
const logic Authenticated = 1;
|
||||
logic AuthBusy;
|
||||
const logic AuthBusy = 0;
|
||||
const logic HasResetHaltReq = 1;
|
||||
logic ConfStrPtrValid;
|
||||
const logic ConfStrPtrValid = 0; // Used with SysBusAccess
|
||||
const logic [3:0] Version = 3; // DM Version
|
||||
// AbstractCS
|
||||
const logic [4:0] ProgBufSize = 0;
|
||||
@ -179,11 +180,9 @@ module dm import cvw::*; #(parameter cvw_t P) (
|
||||
assign AllResumeAck = ResumeAck;
|
||||
assign AnyResumeAck = ResumeAck;
|
||||
|
||||
// See spec 3.14.2
|
||||
assign DMControl = {2'b0, 1'b0, 2'b0, 1'b0, 10'b0, 10'b0, 4'b0, NdmReset, DmActive};
|
||||
|
||||
// See spec 3.14.1
|
||||
assign DMStatus = {7'b0, 1'b0, StickyUnavail, ImpEBreak, 2'b0,
|
||||
assign DMStatus = {7'b0, NdmResetPending, StickyUnavail, ImpEBreak, 2'b0,
|
||||
AllHaveReset, AnyHaveReset, AllResumeAck, AnyResumeAck, AllNonExistent,
|
||||
AnyNonExistent, AllUnavail, AnyUnavail, AllRunning, AnyRunning, AllHalted,
|
||||
AnyHalted, Authenticated, AuthBusy, HasResetHaltReq, ConfStrPtrValid, Version};
|
||||
@ -203,17 +202,8 @@ module dm import cvw::*; #(parameter cvw_t P) (
|
||||
case (State)
|
||||
INACTIVE : begin
|
||||
// Reset Values
|
||||
// TODO: one-line these
|
||||
{HaltReq, ResumeReq, AckHaveReset, HaltOnReset, NdmReset} <= 0;
|
||||
RspData <= 0;
|
||||
HaltReq <= 0;
|
||||
ResumeReq <= 0;
|
||||
AckHaveReset <= 0;
|
||||
HaltOnReset <= 0;
|
||||
NdmReset <= 0;
|
||||
StickyUnavail <= 0;
|
||||
ImpEBreak <= 0;
|
||||
AuthBusy <= 0;
|
||||
ConfStrPtrValid <= 0;
|
||||
CmdErr <= 0;
|
||||
if (ReqValid) begin
|
||||
if (ReqAddress == `DMCONTROL & ReqOP == `OP_WRITE & ReqData[`DMACTIVE]) begin
|
||||
|
@ -76,6 +76,11 @@ module rad import cvw::*; #(parameter cvw_t P) (
|
||||
GPRegNo = 0;
|
||||
FPRegNo = 0;
|
||||
case (Regno) inside
|
||||
[`DCSR_REGNO:`DPC_REGNO] : begin
|
||||
ShiftCount = P.LLEN - 1;
|
||||
CSRegNo = 1;
|
||||
end
|
||||
|
||||
[`FFLAGS_REGNO:`FCSR_REGNO],
|
||||
[`MSTATUS_REGNO:`MCOUNTEREN_REGNO], // InvalidRegNo = ~P.ZICSR_SUPPORTED;
|
||||
`MENVCFG_REGNO,
|
||||
@ -85,7 +90,6 @@ module rad import cvw::*; #(parameter cvw_t P) (
|
||||
[`MSCRATCH_REGNO:`MIP_REGNO],
|
||||
[`PMPCFG0_REGNO:`PMPADDR3F_REGNO], // TODO This is variable len (P.PA_BITS)?
|
||||
[`TSELECT_REGNO:`TDATA3_REGNO],
|
||||
[`DCSR_REGNO:`DPC_REGNO],
|
||||
`SIP_REGNO,
|
||||
`MIP_REGNO,
|
||||
`MHPMEVENTBASE_REGNO,
|
||||
@ -106,7 +110,7 @@ module rad import cvw::*; #(parameter cvw_t P) (
|
||||
`MIP_REGNO : begin
|
||||
ShiftCount = P.LLEN - 1;
|
||||
CSRegNo = 1;
|
||||
//RegReadOnly = 1;
|
||||
RegReadOnly = 1;
|
||||
end
|
||||
|
||||
[`HPMCOUNTERBASE_REGNO:`TIME_REGNO],
|
||||
|
@ -94,6 +94,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
||||
output logic IllegalCSRAccessM, // Illegal CSR access: CSR doesn't exist or is inaccessible at this privilege level
|
||||
output logic BigEndianM, // memory access is big-endian based on privilege mode and STATUS register endian fields
|
||||
// Debug Mode output
|
||||
input logic DebugMode,
|
||||
input logic [2:0] DebugCause,
|
||||
output logic Step,
|
||||
output logic [P.XLEN-1:0] DPC,
|
||||
@ -123,7 +124,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
||||
logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW;
|
||||
logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM;
|
||||
logic CSRWriteDM;
|
||||
logic CSRMWriteM, CSRSWriteM, CSRUWriteM, CSRDWriteM;
|
||||
logic CSRMWriteM, CSRSWriteM, CSRUWriteM;
|
||||
logic UngatedCSRMWriteM;
|
||||
logic WriteFRMM, WriteFFLAGSM;
|
||||
logic [P.XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextMtvalM;
|
||||
@ -222,7 +223,6 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
||||
assign CSRMWriteM = UngatedCSRMWriteM & InstrValidNotFlushedM;
|
||||
assign CSRSWriteM = CSRWriteDM & (|PrivilegeModeW) & InstrValidNotFlushedM;
|
||||
assign CSRUWriteM = CSRWriteDM & InstrValidNotFlushedM;
|
||||
assign CSRDWriteM = CSRWriteDM;
|
||||
assign MTrapM = TrapM & (NextPrivilegeModeM == P.M_MODE);
|
||||
assign STrapM = TrapM & (NextPrivilegeModeM == P.S_MODE) & P.S_SUPPORTED;
|
||||
|
||||
@ -303,7 +303,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
||||
end
|
||||
|
||||
if (P.DEBUG_SUPPORTED) begin:csrd
|
||||
csrd #(P) csrd(.clk, .reset,
|
||||
csrd #(P) csrd(.clk, .reset, .DebugMode, .PrivilegeModeW,
|
||||
.CSRWriteDM, .CSRAdrM(CSRAdrDM), .CSRWriteValM(CSRWriteValDM), .CSRDReadValM, .IllegalCSRDAccessM,
|
||||
.DebugCause, .Step, .DPC, .PCNextF, .EnterDebugMode);
|
||||
end else begin
|
||||
|
@ -28,6 +28,8 @@
|
||||
|
||||
module csrd import cvw::*; #(parameter cvw_t P) (
|
||||
input logic clk, reset,
|
||||
input logic DebugMode,
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
input logic CSRWriteDM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [P.XLEN-1:0] CSRWriteValM,
|
||||
@ -45,7 +47,7 @@ module csrd import cvw::*; #(parameter cvw_t P) (
|
||||
localparam DCSR_ADDR = 12'h7B0; // Debug Control and Status Register
|
||||
localparam DPC_ADDR = 12'h7B1; // Debug PC
|
||||
|
||||
// TODO: these registers are only accessible from Debug Mode.
|
||||
logic CSRDWriteM;
|
||||
logic [31:0] DCSR;
|
||||
logic [P.XLEN-1:0] DPCWriteVal;
|
||||
logic WriteDCSRM;
|
||||
@ -68,40 +70,44 @@ module csrd import cvw::*; #(parameter cvw_t P) (
|
||||
logic [1:0] Prv;
|
||||
|
||||
|
||||
assign CSRDWriteM = CSRWriteDM & (PrivilegeModeW == P.M_MODE) & DebugMode;
|
||||
|
||||
assign WriteDCSRM = CSRDWriteM & (CSRAdrM == DCSR_ADDR);
|
||||
assign WriteDPCM = CSRDWriteM & (CSRAdrM == DPC_ADDR);
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
Prv <= 3;
|
||||
Cause <= 0;
|
||||
Prv <= 2'h3;
|
||||
Cause <= 3'h0;
|
||||
end else if (EnterDebugMode) begin
|
||||
// Prv <= // hart priv mode
|
||||
Prv <= PrivilegeModeW;
|
||||
Cause <= DebugCause;
|
||||
end else if (WriteDCSRM) begin
|
||||
Prv <= CSRWriteValM[`PRV]; // TODO: overwrite hart privilege mode
|
||||
end
|
||||
end
|
||||
|
||||
assign WriteDCSRM = CSRWriteDM & (CSRAdrM == DCSR_ADDR);
|
||||
assign WriteDPCM = CSRWriteDM & (CSRAdrM == DPC_ADDR);
|
||||
|
||||
flopenr #(4) DCSRreg (clk, reset, WriteDCSRM,
|
||||
{CSRWriteValM[`EBREAKM], CSRWriteValM[`EBREAKS], CSRWriteValM[`EBREAKU], CSRWriteValM[`STEP]},
|
||||
{ebreakM, ebreakS, ebreakU, Step});
|
||||
|
||||
assign DCSR = {4'b0100, 10'b0, ebreakVS, ebreakVU, ebreakM, 1'b0, ebreakS, ebreakU, StepIE,
|
||||
assign DCSR = {DebugVer, 10'b0, ebreakVS, ebreakVU, ebreakM, 1'b0, ebreakS, ebreakU, StepIE,
|
||||
StopCount, StopTime, Cause, V, MPrvEn, NMIP, Step, Prv};
|
||||
|
||||
assign DPCWriteVal = EnterDebugMode ? PCNextF : CSRWriteValM;
|
||||
flopenr #(P.XLEN) DPCreg (clk, reset, WriteDPCM | EnterDebugMode, DPCWriteVal, DPC);
|
||||
|
||||
always_comb begin
|
||||
CSRDReadValM = 0;
|
||||
IllegalCSRDAccessM = 0;
|
||||
case (CSRAdrM)
|
||||
DCSR_ADDR : CSRDReadValM = DCSR;
|
||||
DPC_ADDR : CSRDReadValM = DPC;
|
||||
default: IllegalCSRDAccessM = 1'b1;
|
||||
endcase
|
||||
CSRDReadValM = '0;
|
||||
IllegalCSRDAccessM = 1'b0;
|
||||
if (~((PrivilegeModeW == P.M_MODE) & DebugMode))
|
||||
IllegalCSRDAccessM = 1'b1;
|
||||
else
|
||||
case (CSRAdrM)
|
||||
DCSR_ADDR : CSRDReadValM = DCSR;
|
||||
DPC_ADDR : CSRDReadValM = DPC;
|
||||
default: IllegalCSRDAccessM = 1'b1;
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
@ -98,6 +98,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
|
||||
// Fault outputs
|
||||
output logic wfiM, IntPendingM, // Stall in Memory stage for WFI until interrupt pending or timeout
|
||||
// Debuge Mode
|
||||
input logic DebugMode,
|
||||
input logic [2:0] DebugCause,
|
||||
output logic Step,
|
||||
output logic [P.XLEN-1:0] DPC,
|
||||
@ -162,7 +163,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
|
||||
.SetFflagsM, .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_ADUE,
|
||||
.EPCM, .TrapVectorM,
|
||||
.CSRReadValW, .IllegalCSRAccessM, .BigEndianM,
|
||||
.DebugCause, .Step, .DPC, .PCNextF, .EnterDebugMode,
|
||||
.DebugMode, .DebugCause, .Step, .DPC, .PCNextF, .EnterDebugMode,
|
||||
.DebugSel, .DebugRegAddr, .DebugCapture, .DebugRegUpdate, .DebugScanEn, .DebugScanIn, .DebugScanOut);
|
||||
|
||||
// pipeline early-arriving trap sources
|
||||
|
@ -195,8 +195,8 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
logic [P.XLEN-1:0] DPC, PCNextF;
|
||||
logic ExitDebugMode;
|
||||
logic EnterDebugMode;
|
||||
logic ForceNOP;
|
||||
logic [2:0] DebugCause;
|
||||
logic ForceNOP;
|
||||
// Debug register scan chain interconnects
|
||||
logic [2:0] DebugScanReg;
|
||||
|
||||
@ -350,7 +350,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS,
|
||||
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
||||
.FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_ADUE, .wfiM, .IntPendingM, .BigEndianM,
|
||||
.DebugCause, .Step, .DPC, .PCNextF, .EnterDebugMode,
|
||||
.DebugMode, .DebugCause, .Step, .DPC, .PCNextF, .EnterDebugMode,
|
||||
.DebugSel(CSRSel), .DebugRegAddr, .DebugCapture, .DebugRegUpdate, .DebugScanEn(DebugScanEn & CSRSel), .DebugScanIn, .DebugScanOut(CSRScanOut));
|
||||
if (P.DEBUG_SUPPORTED) begin
|
||||
flopenrs #(1) scantrapm (.clk, .reset, .en(DebugCapture), .d(TrapM), .q(), .scan(DebugScanEn), .scanin(DebugScanIn), .scanout(DebugScanReg[0]));
|
||||
|
Loading…
Reference in New Issue
Block a user