-
Notifications
You must be signed in to change notification settings - Fork 188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added support of Smepmp #601
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still working on reading all the boolean logic...
model/riscv_pmp_regs.sail
Outdated
} | ||
|
||
register mseccfg : Mseccfg_ent | ||
register mseccfgh : bits(32) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Normally we don't treat this as a separate register, we just make bitfield Mseccfg : bits(64)
and then read/write the appropriate bits of it.
We have an implementation of mseccfg
like that internally; I'll make a PR for it.
/* Enable Smepmp */ | ||
val sys_enable_smepmp = pure "sys_enable_smepmp" : unit -> bool | ||
/* TODO: for extension smmpm and zkr to enable */ | ||
function sys_has_mseccfg() -> bool = sys_enable_smepmp() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can implement mseccfg
even if you don't have any of the extensions that use it (and that isn't a weird edge case). So ideally this would be
// Callback to C
val sys_have_mseccfg : "sys_have_mseccfg" unit -> bool
function have_mseccfg() -> bool = sys_have_mseccfg() | sys_enable_smepmp() | sys_enable_zkr() ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean we need to add an extra command line parameter to act as an extra switch to control the presence of mseccfg to make sure that even if we don't implement extensions that use this register, we can still implement this register, right ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah exactly. I don't think we need to actually bother hooking it up to a CLI arguments at the moment - we can wait until Alasdair's new config system exists and then it will be a whole lot less tedious. But we can just have a function that returns true
as a placeholder so we don't forget.
@@ -48,14 +48,43 @@ function pmpCheckRWX(ent, acc) = { | |||
} | |||
} | |||
|
|||
// this needs to be called with the effective current privilege. | |||
/* this needs to be called with the effective current privilege */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
//
style comments are nicer IMO. I don't see why we would change them back?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the part that was changed by @HamzaKh01, I didn't check this as I was too focused on the code implementation part, we can change it back if needed, but there are many one line comments like /* ... */
in Sail, we might need to declare it better in the codestyle after some discussion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah there is an experimental auto-formatter in the Sail compiler but I don't know what state it got to and I'd guess it doesn't change this sort of thing.
So does someone review this code and merge it in? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a bit more reviewing. I'll do more when it's been updated.
model/riscv_pmp_control.sail
Outdated
then pmpCheckRWX(ent, acc) | ||
else true, | ||
_ => pmpCheckRWX(ent, acc) | ||
if sys_has_mseccfg() & mseccfg[MML] == 0b1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a CPU doesn't have mseccfg
then I think we can just assume it behaves as if all bits are 0, so I would remove this check here (and in the other places). Instead it should be used for is_CSR_defined
.
model/riscv_pmp_control.sail
Outdated
} | ||
} | ||
else{ | ||
match priv { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can be simplified and clarified to
priv == Machine & not(pmpLocked(ent)) | pmpCheckRWX(ent, acc)
I feel like I made this comment somewhere else but I guess it hasn't been merged wherever it was.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah look it was me... #738 :-D
I've merged that now.
model/riscv_pmp_control.sail
Outdated
(_, _, _, _) => | ||
if (priv == Machine) == pmpLockBit(ent) | ||
then pmpCheckRWX(ent, acc) | ||
else false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would capture the lock bit from the match:
(L, _, _, _) => ((priv == machine) == (L == 0b1)) & pmpCheckRWX(ent, acc),
model/riscv_pmp_control.sail
Outdated
if priv == Machine then None() else Some(accessToFault(acc)) | ||
if priv == Machine | ||
then { | ||
if sys_has_mseccfg() & mseccfg[MMWP] == 0b1 /* Make Read, Write and execute denied by default, if condition meets for M mode */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move the comments to their own line with //
. These are too long, and end-of-line comments are kind of awkward.
} | ||
else None() | ||
} | ||
else Some(accessToFault(acc)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could be a lot simpler:
if priv == Machine & mseccfg[MMWP] != 0b1 & not(mseccfg[MML] == 0b1 & isExecute(acc))
then None() else Some(accesstoFault(acc)
(add isExecute()
as a helper)
model/riscv_pmp_regs.sail
Outdated
@@ -89,32 +98,48 @@ function pmpReadAddrReg(n : range(0, 63)) -> xlenbits = { | |||
} | |||
|
|||
/* Helpers to handle locked entries */ | |||
function pmpLocked(cfg: Pmpcfg_ent) -> bool = | |||
cfg[L] == 0b1 | |||
function pmpLockBit(cfg: Pmpcfg_ent) -> bool = cfg[L] == 0b1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I would just delete this and access cfg[L]
directly.
model/riscv_pmp_regs.sail
Outdated
/* To prevent adding a rule with execution privileges if MML is enabled unless RLB is set */ | ||
else { | ||
/* Constructing legal Pmpcfg_ent by making bit 5 and 6 zero */ | ||
let legal_v : Pmpcfg_ent = Mk_Pmpcfg_ent(v & 0x9f); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not your fault but we should use [v with 6 .. 5 = zeros()]
.
64e2143
to
1dc9cbb
Compare
model/riscv_pmp_regs.sail
Outdated
reg | ||
} | ||
|
||
mapping clause csr_name_map = 0x747 <-> "mseccfg" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of this mseccfg related code should probably move to sys_regs or another similar file because this CSR is not exclusive to pmp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that can be awkward, because mseccfg's RLB field depends on pmpNcfg's L field, and pmpNcfg's L field depends on the RLB field, and their highly coupled relationship would be difficult to handle if they were to be written separately
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this is an ongoing problem with these "global" CSRs (also menvcfg
, mstatus
, etc.). But I agree with @jordancarlin we should move it.
To solve the circular dependency you can forward-declare functions using val
. We'll hopefully come up with a better way of dealing with this after the new project system is in place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I've pushed the moved version.
…smepmp. Sail function: haveSmepmp Added support of Smepmp Co-authored-by: William McSpaddden <bill@riscv.org> Co-authored-by: Hamza Khan <hamza.khan@10xengineers.ai>
added command line support for Smepmp. command line switch: --enable-smepmp. Sail function: haveSmepmp
Added support of Smepmp
This pr was written by @HamzaKh01, merged with the command-line switch code provided by Bill, and adjusted by myself