Skip to content

Conversation

@challenger1024
Copy link
Contributor

Zicclsm Misaligned loads and stores to main memory regions with both the cacheability and coherence PMAs must be supported.
as specified in RVA23.


function check_misaligned(vaddr : virtaddr, width : word_width) -> bool = {
if plat_enable_misaligned_access then {
if plat_enable_misaligned_access | hartSupports(Ext_Zicclsm) then {
Copy link
Collaborator

@nadime15 nadime15 Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m afraid it’s not that simple. As you mentioned in your PR message, this applies only to RAM that is coherent and cacheable, so I assume you need to check whether the current RAM meets those criteria (see the config file with memory.region.ram), right?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Zicclsm itself should not change any behavior. It should behave more like Zic64b and just enforce additional configuration checks. In this case, any memory region that has both coherent and cacheable set to true must also have misaligned_fault set to NoFault.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah even better! So this would mean @challenger1024 you just have to check for coherent and cacheble in check_extension_param_constraints() as part of validate_config.sail.

@jordancarlin Just to clarify we talk only about RAM not other memory regions (ROM, MMIO, etc.)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nadime15 The PMA config options don't have the concept of "RAM".

The Zicclsm spec specifies "main memory regions with both the cacheability and coherence PMAs" and the PMA section of the priv spec says that main memory regions support read and write of all access widths, are assumed to be idempotent, and have constraints on the memory ordering PMA.

We don't support the memory ordering PMA yet, so I think for Zicclsm we want to ensure that regions with all of the following properties have misaligned_fault set to NoFault:

  • cacheable
  • coherent
  • readable
  • writable
  • read_idempotent
  • write_idempotent

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh ok that makes sense now, I was confused by the comments in our config file 😄 So basically a RAM region is implicitly defined by having all those attributes set to true. And the Zicclsm validation just checks, if the extension is enabled, any region matching those attributes must have misaligned_fault == NoFault.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be simpler for this PR to just do the validation as @jordancarlin suggests. Later, we could repurpose the plat_enable_misaligned_access (and suitably rename it) to configure privileged emulation and relax the validation check. With this PR, plat_enable_misaligned_access will be redundant as it will mean essentially the same thing as Zicclsm. Or, in this PR, we could just remove plat_enable_misaligned_access, and then add the parameter @nadime15 suggests in a later PR.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting development a few days ago related to this: Spike just removed its --misaligned flag and misaligned accesses are now enabled by including Zicclsm in the isa string passed with the --isa flag. See riscv-software-src/riscv-isa-sim#2193.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @jordancarlin - at least that's what I implemented at Codasip for our check for this requirement.

I always found the description of "main memory" very vague in the ISA manual. Now that I re-read it I think technically our PMAs should have a flag to indicate whether they are "main memory" or "I/O memory", since you can't actually infer it from the other PMAs. You can have an I/O memory region that supports all the same requirements as main memory but you just are declaring that it's actually I/O memory.

However, I think in practice anything that supports read and write and is idempotent (the most important requirements of "main memory") is going to be main memory.

So I would do something like this:

enum MemoryRegionType {
  MainMemory,
  IOMemory,
}

// Technically you can have a region that satisfies these properties
// but is still declared as IOMemory but we don't support that yet.
function memory_region_type(pma : PMA) -> MemoryRegionType =
  if pma.readable & pma.writable & pma.read_idempotent & pma.write_idempotent then MainMemory else IOMemory

private function check_pma_regions_zicclsm(pmas : list(PMA_Region)) -> bool =
  match pmas {
    [||] => true,
    pma :: rest => {
      let attr = pma.attributes;
      if memory_region_type(attr) == MainMemory & attr.cachable & attr.coherent & attr.misaligned_fault != NoFault then {
        print_endline("nice error message goes here");
        return false;
      };
      check_pma_regions_zicclsm(rest)
    },
  }

// In validate_config.sail
function check_zicclsm() -> bool = {
  var valid : bool = true;
  if hartSupports(Ext_Zicclsm) then {
    if not(plat_enable_misaligned_access) then {
      valid = false;
      print_endline("Zicclsm is enabled but misaligned accesses are globally disabled.");
    } else not(check_pma_regions_zicclsm(pma_regions)) then {
      valid = false;
    };
  };
  valid
}

And as @jordancarlin said this shouldn't change any behaviour; it should only be for validation.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a random thought but ROM is now classified as IOMemory here but ROM isnt really IOMemory. Maybe the enum should be MainMemory vs NotMainMemory (the debug module adds another region for the program buffer), or we add a third enum entry?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I always found the description of "main memory" very vague in the ISA manual. Now that I re-read it I think technically our PMAs should have a flag to indicate whether they are "main memory" or "I/O memory", since you can't actually infer it from the other PMAs. You can have an I/O memory region that supports all the same requirements as main memory but you just are declaring that it's actually I/O memory.

@Timmmm I think the memory ordering PMA unambiguously determines if a region is main memory or IO:

Regions of the address space are classified as either main memory or I/O for the purposes of ordering by the FENCE instruction and atomic-instruction ordering bits.

@nadime15 I think it is correct to classify ROM as IOMemory according to the spec. It specifies that there are only two types of memory:

Regular main memory is required to have a number of properties, specified below, whereas I/O devices can have a much broader range of attributes. Memory regions that do not fit into regular main memory, for example, device scratchpad RAMs, are categorized as I/O regions.

Main memory is required to be writable, so a ROM must be IO memory.

// Main memory supports misaligned loads/stores
enum clause extension = Ext_Zicclsm
mapping clause extensionName = Ext_Zicclsm <-> "zicclsm"
function clause hartSupports(Ext_ZicClsm) = config extensions.Zicclsm.supported
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
function clause hartSupports(Ext_ZicClsm) = config extensions.Zicclsm.supported
function clause hartSupports(Ext_Zicclsm) = config extensions.Zicclsm.supported

mapping clause extensionName = Ext_Smcntrpmf <-> "smcntrpmf"
function clause hartSupports(Ext_Smcntrpmf) = config extensions.Smcntrpmf.supported
// Main memory supports misaligned loads/stores
enum clause extension = Ext_Zicclsm
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this up to be with the other Zi* extensions.

Ext_Zvbb => 2, // > Zve32x
Ext_Zve32f => 2, // > Zve32x
Ext_Zve64x => 2, // > Zve32x
Ext_Zicclsm => 2,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary and not part of any dependency chain. The base case of 2 is fine for Zicclsm.

// Main memory supports misaligned loads/stores
enum clause extension = Ext_Zicclsm
mapping clause extensionName = Ext_Zicclsm <-> "zicclsm"
function clause hartSupports(Ext_ZicClsm) = config extensions.Zicclsm.supported
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing a currentlyEnabled clause. For Zicclsm, I think that can just be

function clause currentlyEnabled(Ext_Zicclsm) = hartSupports(Ext_Zicclsm)


function check_misaligned(vaddr : virtaddr, width : word_width) -> bool = {
if plat_enable_misaligned_access then {
if plat_enable_misaligned_access | hartSupports(Ext_Zicclsm) then {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Zicclsm itself should not change any behavior. It should behave more like Zic64b and just enforce additional configuration checks. In this case, any memory region that has both coherent and cacheable set to true must also have misaligned_fault set to NoFault.

@github-actions
Copy link

github-actions bot commented Jan 6, 2026

Test Results

2 115 tests  ±0   2 115 ✅ ±0   23m 23s ⏱️ -2s
    1 suites ±0       0 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit 99c99b7. ± Comparison against base commit 13a6693.

♻️ This comment has been updated with latest results.

@allenjbaum
Copy link
Collaborator

allenjbaum commented Jan 6, 2026 via email

@jordancarlin jordancarlin added the extension Adds support for a RISC-V extension label Jan 6, 2026
@allenjbaum
Copy link
Collaborator

allenjbaum commented Jan 7, 2026 via email

@Timmmm
Copy link
Collaborator

Timmmm commented Jan 7, 2026

Hmm I think you're right. Now that I double checked the profiles it says

Only user-mode (RVA23U64) and supervisor-mode (RVA23S64) profiles are specified in this family.

So as long as it is possible for machine mode to emulate misaligned access it's fine. So I think the only thing we can check here is that the PMA doesn't cause an access fault on misaligned access (which wouldn't allow emulation).

@challenger1024
Copy link
Contributor Author

Recently update:

  • add currentlyEnabled function for Zicclsm.
  • add check_pma_regions_zicclsm() function.
  • remove plat_enable_misaligned_access.

@jordancarlin

};
if hartSupports(Ext_Zicclsm) & not(check_pma_regions_zicclsm(pma_regions)) then {
valid = false;
print_endline("Zicclsm is enabled but cacheable and coherent memory regions are not set to NoFault.");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe something like?

Suggested change
print_endline("Zicclsm is enabled but cacheable and coherent memory regions are not set to NoFault.");
print_endline("The extension Zicclsm is enabled but at least one main memory region that is cacheable and coherent and has misaligned_fault = NoFault is required.");

@challenger1024
Copy link
Contributor Author

I think you are right. I have change this message.
@nadime15

[||] => true,
pma :: rest => {
let attr = pma.attributes;
if attr.cacheable & attr.coherent & attr.misaligned_fault != NoFault then {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't right. Like we discussed above, Zicclsm only requires main memory regions that are cacheable and coherent to support misaligned. This is checking all regions that are cacheable and coherent. It needs to only checks regions that have all of the following properties:

  • cacheable
  • coherent
  • readable
  • writable
  • read_idempotent
  • write_idempotent

};
if hartSupports(Ext_Zicclsm) & not(check_pma_regions_zicclsm(pma_regions)) then {
valid = false;
print_endline("The extension Zicclsm is enabled but at least one main memory region that is cacheable and coherent and has misaligned_fault = NoFault is required.");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Zicclsm requires all main memory regions that are cacheable and coherent to support misaligned, not just one of them.

Suggested change
print_endline("The extension Zicclsm is enabled but at least one main memory region that is cacheable and coherent and has misaligned_fault = NoFault is required.");
print_endline("The Zicclsm extension is enabled but at least one main memory region that is cacheable and coherent does not support misaligned accesses (misaligned_fault is not NoFault).");

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ups, my bad!

@challenger1024
Copy link
Contributor Author

I have added these conditions and changed that message.

@jordancarlin

if attr.cacheable & attr.coherent
& attr.readable & attr.writable
& attr.read_idempotent & attr.write_idempotent
& attr.misaligned_fault != NoFault then {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than having this all inline, break the read/write/idempotent check out into a helper function that determines whether a region is main memory like @Timmmm suggested. There are several other extensions that impose constraints on main memory, and that would let use reuse the function.

@challenger1024
Copy link
Contributor Author

I also think Timmmm's suggestion is very good, but I'm not sure where mainMemoryRegion and the memory_region_type function should be placed.

@jordancarlin
Copy link
Collaborator

I also think Timmmm's suggestion is very good, but I'm not sure where mainMemoryRegion and the memory_region_type function should be placed.

pma.sail seems like a reasonable place. They could also go in validate_config.sail since that’s the only place they’d be used (at least for now).

@challenger1024
Copy link
Contributor Author

I have added MemoryRegionType enum.
@jordancarlin

Comment on lines 32 to 35
// whether the platform supports misaligned accesses without trapping to M-mode. if false,
// misaligned loads/stores are trapped to Machine mode.
let plat_enable_misaligned_access : bool = config memory.misaligned.supported

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps you re-introduced this by mistake?

// checked before address translation. `misaligned_fault` in
// `regions` is checked after address translation.
"misaligned": {
"supported": true,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps you re-introduced this by mistake? I thought the plan was to remove this and use Zicclsm instead? See #1468 (comment)


function check_misaligned(vaddr : virtaddr, width : word_width) -> bool = {
if currentlyEnabled(Ext_Zicclsm) then {
if plat_enable_misaligned_access then {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extension Adds support for a RISC-V extension

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants