Improved permissions for CSR access

This commit is contained in:
Matthew 2024-06-14 23:18:34 -05:00
parent 60f12a6f60
commit 679ff3455b
7 changed files with 58 additions and 43 deletions

View File

@ -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()

View File

@ -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

View File

@ -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],

View File

@ -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

View File

@ -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,35 +70,39 @@ 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;
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;

View File

@ -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

View File

@ -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]));