From f66f99c33044d852de914517941d4dddedb78634 Mon Sep 17 00:00:00 2001 From: Ryan Wolk Date: Thu, 11 Jun 2026 13:24:29 -0700 Subject: [PATCH 1/4] Update Sail to 0.12 Signed-off-by: Ryan Wolk --- bin/installation/sail-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/installation/sail-install.sh b/bin/installation/sail-install.sh index 34fb7f1b91..18c59fe43e 100755 --- a/bin/installation/sail-install.sh +++ b/bin/installation/sail-install.sh @@ -27,7 +27,7 @@ ## and limitations under the License. ################################################################################################ -RISCV_SAIL_MODEL_VERSION=0.10 # Last release as of Feb 16, 2026 +RISCV_SAIL_MODEL_VERSION=0.12 # Last release as of June 11, 2026 set -e # break on error # If run standalone, check environment. Otherwise, use info from main install script From 710fd2b3b42db806d2bbbdb4d905a35263523836 Mon Sep 17 00:00:00 2001 From: Ryan Wolk Date: Mon, 15 Jun 2026 10:38:11 -0700 Subject: [PATCH 2/4] Update Sail Config Files and Change --trace-all to --trace Signed-off-by: Ryan Wolk --- examples/exercises/lynn/Makefile | 2 +- tests/riscof/sail_cSim/riscof_sail_cSim.py | 2 +- tests/riscof/sail_cSim/rv32gc.json | 367 +++++++++++++++++++-- tests/riscof/sail_cSim/rv64gc.json | 367 +++++++++++++++++++-- 4 files changed, 666 insertions(+), 72 deletions(-) diff --git a/examples/exercises/lynn/Makefile b/examples/exercises/lynn/Makefile index 73fb813458..15c0d3515a 100644 --- a/examples/exercises/lynn/Makefile +++ b/examples/exercises/lynn/Makefile @@ -16,7 +16,7 @@ PROCESSOR_TOP ?= riscvsingle # top-level module name PROCESSOR_CONFIG ?= $(CURDIR)/sample_processor/config #--trace-all -SAIL_TRACE_FLAGS ?= --trace-all +SAIL_TRACE_FLAGS ?= --trace # ---- Synthesis Configuration ---- # SYNTH_TECH ?= sky130 #tsmc28 #tsmc28psyn diff --git a/tests/riscof/sail_cSim/riscof_sail_cSim.py b/tests/riscof/sail_cSim/riscof_sail_cSim.py index affe882a79..3f90719818 100644 --- a/tests/riscof/sail_cSim/riscof_sail_cSim.py +++ b/tests/riscof/sail_cSim/riscof_sail_cSim.py @@ -122,7 +122,7 @@ def runTests(self, testList, cgf_file=None): reference_output = re.sub("/src/", "/references/", re.sub(".S", ".reference_output", test)) execute += f"cut -c-{8:g} {reference_output} > {sig_file}" # use cut to remove comments when copying else: - execute += self.sail_exe[self.xlen] + f" --config {self.pluginpath}/rv{self.xlen}gc.json --trace-all --test-signature={sig_file} {elf} > {test_name}.log 2>&1;" + execute += self.sail_exe[self.xlen] + f" --config {self.pluginpath}/rv{self.xlen}gc.json --trace --test-signature={sig_file} {elf} > {test_name}.log 2>&1;" make.add_target(execute) # make.execute_all(self.work_dir) diff --git a/tests/riscof/sail_cSim/rv32gc.json b/tests/riscof/sail_cSim/rv32gc.json index 38f3d59318..ac77410947 100644 --- a/tests/riscof/sail_cSim/rv32gc.json +++ b/tests/riscof/sail_cSim/rv32gc.json @@ -2,13 +2,76 @@ "$schema": "/opt/riscv/share/sail-riscv/sail_riscv_config_schema.json", "base": { "xlen": 32, + // Whether the base ISA is E, in which case accessing + // x16-31 is reserved and in this implementation will + // raise an illegal instruction exception. "E": false, "writable_misa": false, "writable_fiom": true, + // The top 29 bits in this value control whether the corresponding + // HPM counters (hpmcounter31 .. hpmcounter3) are supported + // (i.e. are not read-only zero). A set bit specifies that the + // corresponding counter is supported. The lowest 3 bits + // (writable_hpm_counters[2 .. 0]) are ignored. "writable_hpm_counters": { "len": 32, "value": "0xFFFF_FFFF" }, + // The bits in this value control whether the corresponding bits + // of the `scounteren` CSR that control access to HPM counters, + // and `cycle`, `time` and `instret` registers, are read-only + // zero. A set bit specifies that the corresponding bit of + // `scounteren` is writable, otherwise the bit is read-only zero. + // If Sscounterenw is supported the top 29 bits must be a superset of + // the top 29 bits of `writable_hpm_counters`. + "scounteren_writable_bits": { + "len": 32, + "value": "0xFFFF_FFFF" + }, + // The bits in this value control whether the corresponding bits + // of the `mcounteren` CSR that control access to HPM counters, + // and `cycle`, `time` and `instret` registers at lower privilege + // modes, are read-only zero. A set bit specifies that the + // corresponding bit of `mcounteren` is writable, otherwise the + // bit is read-only zero. + "mcounteren_writable_bits": { + "len": 32, + "value": "0xFFFF_FFFF" + }, + // `mtvec.{direct,vectored}.supported` indicates whether the + // corresponding mode is supported for `mtvec`. At least one mode + // should be supported. If both modes are supported, the mode on + // reset is unspecified. + // The `mtvec.{direct,vectored}.base_alignment` parameters control the alignment + // of the trap vector base for each mode. The alignment is + // specified as the power of 2 of the desired byte alignment, and + // can range from a minimum of 2 upto a maximum of 24. If + // unaligned values are written to these CSRs, the lowest bits + // will be zeroed to respect the specified alignment. + "mtvec": { + "direct": { + "supported": true, + "base_alignment": 2 + }, + "vectored": { + "supported": true, + "base_alignment": 6 + } + }, + // Similar to `mtvec` above. If `S` mode is not supported, these + // values need to be present and legal but are ignored. + "stvec": { + // The spec requires `base_alignment` for `stvec.direct` to be 2 + // (i.e. 4-byte alignment), hence there is no configuration + // parameter for it. + "direct": { + "supported": true + }, + "vectored": { + "supported": true, + "base_alignment": 2 + } + }, // These settings control whether the specified exceptions // cause information to be written into the appropriate // `xtval` registers. @@ -49,10 +112,24 @@ // "Xenvcfg_Fatal" – raise a Sail exception, stopping execution. // "Xenvcfg_ClearPermissions" – convert CBIE with 0b10 to 0b00. "xenvcfg_cbie": "Xenvcfg_ClearPermissions", + // The configuration option determines how to handle the reserved behavior `xtvec[Mode] >= 2`. + // "Xtvec_Fatal" – raise a Sail exception, stopping execution. + // "Xtvec_Ignore" – use old Mode of xtvec. + "xtvec_mode": "Xtvec_Ignore", // The configuration option determines how to handle the reserved behavior: Odd-numbered registers for RV32Zdinx. // "Zdinx_Fatal" – raise a Sail exception, stopping execution. // "Zdinx_Illegal" – treat it as an illegal instruction. "rv32zdinx_odd_register": "Zdinx_Illegal" + }, + "mstatus": { + // The legal values for the FS and VS fields in this CSR are + // specified by the two fields below. Their values can be one + // of: + // - "ExtContext_FourState" allows all values {Off, Initial, Clean, Dirty}. + // - "ExtContext_TwoState" allows {Off, Dirty}, and writes of Initial and Clean get written as Dirty. + // - "ExtContext_Off" allows only {Off}. This makes the field read-only zero. + "fs_legal_states": "ExtContext_FourState", + "vs_legal_states": "ExtContext_Off" } }, "memory": { @@ -69,23 +146,66 @@ "na4_supported": false, "napot_supported": true }, - // This controls global support for misaligned access so it is + // These settings control global support for misaligned access so they are // checked before address translation. `misaligned_fault` in // `regions` is checked after address translation. "misaligned": { - "supported": false, + // `exceptions` specifies the treatment of misaligned accesses + // before address translation. If a fault is specified for an access, + // it will have a higher priority than memory-protection faults arising from + // that access if it were allowed to proceed. + "exceptions": { + // A misaligned scalar or vector load/store can either proceed + // without a fault (use `{"None" : null}`), or raise an access fault + // (use `{"Some": "AccessFault"}`) or a misaligned exception + // (use `{"Some": "AlignmentException"}`). + // This option controls scalar loads/stores. + "load_store": { + "Some": "AlignmentException" + }, + // A misaligned vector load/store can be configured + // independently of the scalar case above, but uses the same + // option values. + "vector": { + "Some": "AlignmentException" + }, + // A misaligned LR/SC currently always faults, and this field can specify + // whether it generates an access fault (use `"AccessFault"`) + // or a misaligned exception (use `"AlignmentException"`). + "lrsc": "AlignmentException", + // Similarly, a misaligned AMO currently always faults, and this field + // can specify either `"AccessFault"` or `"AlignmentException"`. + "amo": "AlignmentException" + }, + // If a misaligned access was specified to have no fault in `exceptions` above, the + // fields below specify how it is handled. + // + // Memory accesses that span multiple naturally aligned + // 2^allowed_within_exp sized regions will be split into multiple + // memory operations. 0 means all misaligned accesses will be split. + // The maximum value is 12 (one page). + "allowed_within_exp": 0, + // If the access gets split due to `allowed_within_exp` then the size + // of the operations will be one byte if `byte_by_byte` is set, otherwise + // they will be the maximum size possible based on the alignment. For + // example a 4-byte access to address 0x2 will use two 2-byte operations. "byte_by_byte": false, - "order_decreasing": false, - "allowed_within_exp": 0 - }, - "translation": { - "dirty_update": false - }, - // Address to write DTB to (if provided). + // If multiple memory operations are needed, this controls whether they + // are done in increasing or decreasing address order. This is architecturally + // observable because some store operations may succeed, and even for + // loads the resulting `xtval` may depend on this setting. + "order_decreasing": false + }, + // Address to write DTB to (if provided). This must be in a suitable memory + // region (see `memory.regions`). "dtb_address": { "len": 64, "value": "0x1000" }, + // The locations and sizes of memory regions and their PMAs. These regions + // are required to be aligned to 4K (page) boundaries. To specify + // the `misaligned` PMA attribute for a region, see the comments for + // `memory.misaligned.exceptions` above. "regions": [ // ROM { @@ -98,16 +218,28 @@ "value": "0x1000" }, "attributes": { + "mem_type": "IOMemory", "cacheable": true, - "coherent": true, + "coherent": false, "executable": false, "readable": true, "writable": false, "read_idempotent": true, "write_idempotent": true, - "misaligned_fault": "NoFault", + "misaligned_exceptions": { + "load_store": { + "None": null + }, + "vector": { + "None": null + }, + "amo": "AccessFault" + }, + "atomic_support": "AMONone", "reservability": "RsrvNone", - "supports_cbo_zero": false + "supports_cbo_zero": false, + "supports_pte_read": false, + "supports_pte_write": false }, "include_in_device_tree": false }, @@ -119,9 +251,10 @@ }, "size": { "len": 64, - "value": "0x2000000" + "value": "0x10000000" }, "attributes": { + "mem_type": "IOMemory", "cacheable": false, "coherent": true, "executable": false, @@ -129,9 +262,20 @@ "writable": true, "read_idempotent": false, "write_idempotent": false, - "misaligned_fault": "AlignmentFault", + "misaligned_exceptions": { + "load_store": { + "Some": "AlignmentException" + }, + "vector": { + "Some": "AlignmentException" + }, + "amo": "AccessFault" + }, + "atomic_support": "AMONone", "reservability": "RsrvNone", - "supports_cbo_zero": false + "supports_cbo_zero": false, + "supports_pte_read": false, + "supports_pte_write": false }, "include_in_device_tree": false }, @@ -146,6 +290,7 @@ "value": "0x80000000" }, "attributes": { + "mem_type": "MainMemory", "cacheable": true, "coherent": true, "executable": true, @@ -153,9 +298,20 @@ "writable": true, "read_idempotent": true, "write_idempotent": true, - "misaligned_fault": "NoFault", + "misaligned_exceptions": { + "load_store": { + "None": null + }, + "vector": { + "None": null + }, + "amo": "AccessFault" + }, + "atomic_support": "AMOArithmetic", "reservability": "RsrvEventual", - "supports_cbo_zero": true + "supports_cbo_zero": true, + "supports_pte_read": true, + "supports_pte_write": true }, "include_in_device_tree": true } @@ -168,18 +324,60 @@ "hartid": 0, // Cache block size, specified as a power of 2. "cache_block_size_exp": 6, - // This specifies both the size and alignment of the reservation set, specified as a power of 2. - // It must be at least 2 on RV32 and 3 on RV64 to support Zalrsc. It must not be more than - // 6 for Za64rs and 7 for Za128rs. In all cases, it must be less than or equal to 12. - "reservation_set_size_exp": 2, + "reservation": { + // This specifies both the size and alignment of the reservation set, specified as a power of 2. + // It must be at least 2 on RV32 and 3 on RV64 to support Zalrsc. It must not be more than + // 6 for Za64rs and 7 for Za128rs. In all cases, it must be less than or equal to 12. + "reservation_set_size_exp": 2, + // Some implementations (e.g. Spike) require the Store-Conditional to provide the same + // address as the matching Load-Reserve in order to succeed, regardless of the + // configured reservation set size. This controls whether such an exact address + // match is required for a Store-Conditional to succeed. + "require_exact_reservation_addr": false, + // Some implementations (e.g. SiFive U74) also invalidate the + // reservation on stores from the same hart. If this is set to `true`, the + // model invalidates the reservation if a store from the same hart lies within + // the reservation set. + "invalidate_on_same_hart_store": false + }, "clint": { - // This must be in a suitable memory region (see `memory.regions`). + // Whether the platform contains a CLINT. + "supported": true, + // If supported, this must be in a suitable IO memory region (see `memory.regions`). + // Otherwise, these values can be left as 0. "base": 33554432, "size": 786432 }, + // Very simple MMIO device to generate interrupts for testing + // purposes. See docs/SimpleInterruptGenerator.md for details. + "simple_interrupt_generator": { + // Whether the platform contains this device. + "supported": true, + // If supported, this must be in a suitable IO memory region (see `memory.regions`) + // and 4-byte aligned. The size is always 0x20. If not supported, this can be left + // as 0. + "base": 201326592 + }, "clock_frequency": 1000000000, "instructions_per_tick": 2, - "wfi_is_nop": true + "wfi_is_nop": false, + // WFI is optionally available to User mode. Note that even if + // `wfi_is_nop` is set to `true` above, it will still not be + // available to User mode unless `wfi_available_to_user_mode` is + // also `true`. + "wfi_available_to_user_mode": true, + // The maximum increment in the time CSR before a wait instruction + // (e.g. WFI, WRS.NTO, WRS.STO) that is not a NOP expires its + // wait. It is not possible to wait indefinitely. + // + // If WFI or WRS.STO (Short TimeOut) exceed this limit in + // non-machine privilege with mstatus[TW] set, an illegal + // instruction is raised. Otherwise they retire successfully. + // + // Note: it is also legal for these instructions to spuriously + // retire successfully at any point, but there is currently no + // configuration option for this behaviour. + "max_time_to_wait": 200 }, "extensions": { "M": { @@ -207,9 +405,45 @@ // Zve64x, Zve64f, and Zve64d require `elen_exp` >= 6, // and V requires `elen_exp` >= 6 and `vlen_exp` >= 7. "support_level": "Disabled", + // `vlen_exp` and `elen_exp` should be between 3 and 16, + // inclusive. If `support_level` is `"Disabled"`, then these + // should be left as 3 (or any other legal value). "vlen_exp": 8, "elen_exp": 6, - "vl_use_ceil": false + "reserved_behavior": { + // This determines how to handle attempts by vsetvli, vsetivli, + // and vsetvl to set an unsupported or reserved vtype. + // "IllegalVtype_SetVill" - set vtype.vill, set vl to zero, clear vstart, and write rd. + // "IllegalVtype_Illegal" - treat it as an illegal instruction. + // "IllegalVtype_Fatal" - raise a Sail exception, stopping execution. + "illegal_vtype": "IllegalVtype_SetVill", + // This determines how to handle an out-of-bounds vstart (vstart >= VLMAX), which the + // vector spec marks reserved and recommends, but does not require, trapping. + // "Vstart_Illegal" - raise an illegal instruction exception. + // "Vstart_Ignore" - treat as a no-op, the instruction writes nothing. + "vstart_out_of_bounds": "Vstart_Illegal" + }, + "vl_use_ceil": false, + // The maximum index EEW for indexed vector addressing mode, as + // a power of 2. This must be at least 3 but must not exceed + // the supported ELEN. + "max_index_eew_exp": 5, + "vstart": { + // The vector specification permits implementations to raise an + // illegal instruction exception when `vstart` is non-zero for + // instructions that cannot produce such a `vstart` value through + // normal execution. + "zero_required": { + // Whether vector arithmetic instructions raise an illegal instruction + // exception when `vstart` is non-zero. This also governs instructions + // from the Zvbb, Zvbc, Zvabd, Zvfbfmin, and Zvfbfwma extensions. + "arith": true, + // Whether the vector scalar move instructions (vmv.x.s, vmv.s.x, + // vfmv.f.s and vfmv.s.f) raise an illegal instruction exception when + // `vstart` is non-zero. + "scalar_move": true + } + } }, "B": { "supported": true @@ -223,6 +457,12 @@ "Zibi": { "supported": false }, + // This extension just asserts that the cache block size is 64 bytes. + // If you enable this you also need to ensure `platform.cache_block_size_exp` + // is 6, otherwise you will get a config validation error. + "Zic64b": { + "supported": true + }, "Zicbom": { "supported": true }, @@ -232,15 +472,27 @@ "Zicboz": { "supported": true }, - // This extension just asserts that the cache block size is 64 bytes. - // If you enable this you also need to ensure `platform.cache_block_size_exp` - // is 6, otherwise you will get a config validation error. - "Zic64b": { + "Ziccamoa": { + "supported": true + }, + "Ziccamoc": { + "supported": false + }, + "Ziccif": { + "supported": true + }, + "Zicclsm": { + "supported": false + }, + "Ziccrse": { "supported": true }, "Zicfilp": { "supported": false }, + "Zicfiss": { + "supported": false + }, "Zicond": { "supported": true }, @@ -266,10 +518,10 @@ "supported": false }, "Zmmul": { - "supported": false + "supported": true }, "Zaamo": { - "supported": false + "supported": true }, "Zabha": { "supported": false @@ -278,10 +530,14 @@ "supported": false }, "Zalrsc": { - "supported": false + "supported": true }, "Zawrs": { "supported": false, + // Whether `WRS.NTO` and `WRS.STO` behave as NOPS. If they do + // not, see above note for `platform.max_time_to_wait`. If + // Zawrs is not supported, these `is_nop` fields need to be + // present but their boolean values are ignored. "nto": { "is_nop": false }, @@ -299,7 +555,7 @@ "supported": true }, "Zfhmin": { - "supported": false + "supported": true }, "Zfinx": { "supported": false @@ -323,13 +579,13 @@ "supported": false }, "Zba": { - "supported": false + "supported": true }, "Zbb": { - "supported": false + "supported": true }, "Zbs": { - "supported": false + "supported": true }, "Zbc": { "supported": true @@ -354,6 +610,8 @@ }, "Zkr": { "supported": false, + // If Zkr is not supported, these fields need to be present but + // their boolean values are ignored. "sseed_reset_value": false, "useed_reset_value": false, "sseed_read_only_zero": false, @@ -419,9 +677,15 @@ "Zvkt": { "supported": false }, + "Ssccptr": { + "supported": true + }, "Sscofpmf": { "supported": false }, + "Sscounterenw": { + "supported": true + }, "Sstc": { "supported": true }, @@ -430,12 +694,36 @@ "Sstvala": { "supported": true }, + "Svade": { + "supported": true + }, + "Svadu": { + "supported": true + }, "Svinval": { "supported": true }, "Svrsw60t59b": { "supported": false }, + "Svnapot": { + "supported": false + }, + "Ssnpm": { + "supported": false, + "supported_pmlen_7": true, + "supported_pmlen_16": true + }, + "Smnpm": { + "supported": false, + "supported_pmlen_7": true, + "supported_pmlen_16": true + }, + "Smmpm": { + "supported": false, + "supported_pmlen_7": true, + "supported_pmlen_16": true + }, "Smcntrpmf": { "supported": false }, @@ -467,8 +755,17 @@ }, "Ssqosid": { "supported": false, + // These lengths should be between 1 and 12, inclusive. + // If Ssqosid is not supported, this should be left as 1 + // (or any other legal value). "rcid_length": 12, "mcid_length": 12 + }, + "Svpbmt": { + "supported": false + }, + "Svvptc": { + "supported": true } } } diff --git a/tests/riscof/sail_cSim/rv64gc.json b/tests/riscof/sail_cSim/rv64gc.json index 552e78968d..077ac4b530 100644 --- a/tests/riscof/sail_cSim/rv64gc.json +++ b/tests/riscof/sail_cSim/rv64gc.json @@ -2,13 +2,76 @@ "$schema": "/opt/riscv/share/sail-riscv/sail_riscv_config_schema.json", "base": { "xlen": 64, + // Whether the base ISA is E, in which case accessing + // x16-31 is reserved and in this implementation will + // raise an illegal instruction exception. "E": false, "writable_misa": false, "writable_fiom": true, + // The top 29 bits in this value control whether the corresponding + // HPM counters (hpmcounter31 .. hpmcounter3) are supported + // (i.e. are not read-only zero). A set bit specifies that the + // corresponding counter is supported. The lowest 3 bits + // (writable_hpm_counters[2 .. 0]) are ignored. "writable_hpm_counters": { "len": 32, "value": "0xFFFF_FFFF" }, + // The bits in this value control whether the corresponding bits + // of the `scounteren` CSR that control access to HPM counters, + // and `cycle`, `time` and `instret` registers, are read-only + // zero. A set bit specifies that the corresponding bit of + // `scounteren` is writable, otherwise the bit is read-only zero. + // If Sscounterenw is supported the top 29 bits must be a superset of + // the top 29 bits of `writable_hpm_counters`. + "scounteren_writable_bits": { + "len": 32, + "value": "0xFFFF_FFFF" + }, + // The bits in this value control whether the corresponding bits + // of the `mcounteren` CSR that control access to HPM counters, + // and `cycle`, `time` and `instret` registers at lower privilege + // modes, are read-only zero. A set bit specifies that the + // corresponding bit of `mcounteren` is writable, otherwise the + // bit is read-only zero. + "mcounteren_writable_bits": { + "len": 32, + "value": "0xFFFF_FFFF" + }, + // `mtvec.{direct,vectored}.supported` indicates whether the + // corresponding mode is supported for `mtvec`. At least one mode + // should be supported. If both modes are supported, the mode on + // reset is unspecified. + // The `mtvec.{direct,vectored}.base_alignment` parameters control the alignment + // of the trap vector base for each mode. The alignment is + // specified as the power of 2 of the desired byte alignment, and + // can range from a minimum of 2 upto a maximum of 24. If + // unaligned values are written to these CSRs, the lowest bits + // will be zeroed to respect the specified alignment. + "mtvec": { + "direct": { + "supported": true, + "base_alignment": 2 + }, + "vectored": { + "supported": true, + "base_alignment": 6 + } + }, + // Similar to `mtvec` above. If `S` mode is not supported, these + // values need to be present and legal but are ignored. + "stvec": { + // The spec requires `base_alignment` for `stvec.direct` to be 2 + // (i.e. 4-byte alignment), hence there is no configuration + // parameter for it. + "direct": { + "supported": true + }, + "vectored": { + "supported": true, + "base_alignment": 2 + } + }, // These settings control whether the specified exceptions // cause information to be written into the appropriate // `xtval` registers. @@ -49,10 +112,24 @@ // "Xenvcfg_Fatal" – raise a Sail exception, stopping execution. // "Xenvcfg_ClearPermissions" – convert CBIE with 0b10 to 0b00. "xenvcfg_cbie": "Xenvcfg_ClearPermissions", + // The configuration option determines how to handle the reserved behavior `xtvec[Mode] >= 2`. + // "Xtvec_Fatal" – raise a Sail exception, stopping execution. + // "Xtvec_Ignore" – use old Mode of xtvec. + "xtvec_mode": "Xtvec_Ignore", // The configuration option determines how to handle the reserved behavior: Odd-numbered registers for RV32Zdinx. // "Zdinx_Fatal" – raise a Sail exception, stopping execution. // "Zdinx_Illegal" – treat it as an illegal instruction. "rv32zdinx_odd_register": "Zdinx_Illegal" + }, + "mstatus": { + // The legal values for the FS and VS fields in this CSR are + // specified by the two fields below. Their values can be one + // of: + // - "ExtContext_FourState" allows all values {Off, Initial, Clean, Dirty}. + // - "ExtContext_TwoState" allows {Off, Dirty}, and writes of Initial and Clean get written as Dirty. + // - "ExtContext_Off" allows only {Off}. This makes the field read-only zero. + "fs_legal_states": "ExtContext_FourState", + "vs_legal_states": "ExtContext_Off" } }, "memory": { @@ -69,23 +146,66 @@ "na4_supported": false, "napot_supported": true }, - // This controls global support for misaligned access so it is + // These settings control global support for misaligned access so they are // checked before address translation. `misaligned_fault` in // `regions` is checked after address translation. "misaligned": { - "supported": true, + // `exceptions` specifies the treatment of misaligned accesses + // before address translation. If a fault is specified for an access, + // it will have a higher priority than memory-protection faults arising from + // that access if it were allowed to proceed. + "exceptions": { + // A misaligned scalar or vector load/store can either proceed + // without a fault (use `{"None" : null}`), or raise an access fault + // (use `{"Some": "AccessFault"}`) or a misaligned exception + // (use `{"Some": "AlignmentException"}`). + // This option controls scalar loads/stores. + "load_store": { + "None": null + }, + // A misaligned vector load/store can be configured + // independently of the scalar case above, but uses the same + // option values. + "vector": { + "None": null + }, + // A misaligned LR/SC currently always faults, and this field can specify + // whether it generates an access fault (use `"AccessFault"`) + // or a misaligned exception (use `"AlignmentException"`). + "lrsc": "AccessFault", + // Similarly, a misaligned AMO currently always faults, and this field + // can specify either `"AccessFault"` or `"AlignmentException"`. + "amo": "AccessFault" + }, + // If a misaligned access was specified to have no fault in `exceptions` above, the + // fields below specify how it is handled. + // + // Memory accesses that span multiple naturally aligned + // 2^allowed_within_exp sized regions will be split into multiple + // memory operations. 0 means all misaligned accesses will be split. + // The maximum value is 12 (one page). + "allowed_within_exp": 0, + // If the access gets split due to `allowed_within_exp` then the size + // of the operations will be one byte if `byte_by_byte` is set, otherwise + // they will be the maximum size possible based on the alignment. For + // example a 4-byte access to address 0x2 will use two 2-byte operations. "byte_by_byte": false, - "order_decreasing": false, - "allowed_within_exp": 0 - }, - "translation": { - "dirty_update": false - }, - // Address to write DTB to (if provided). + // If multiple memory operations are needed, this controls whether they + // are done in increasing or decreasing address order. This is architecturally + // observable because some store operations may succeed, and even for + // loads the resulting `xtval` may depend on this setting. + "order_decreasing": false + }, + // Address to write DTB to (if provided). This must be in a suitable memory + // region (see `memory.regions`). "dtb_address": { "len": 64, "value": "0x1000" }, + // The locations and sizes of memory regions and their PMAs. These regions + // are required to be aligned to 4K (page) boundaries. To specify + // the `misaligned` PMA attribute for a region, see the comments for + // `memory.misaligned.exceptions` above. "regions": [ // ROM { @@ -98,16 +218,28 @@ "value": "0x1000" }, "attributes": { + "mem_type": "IOMemory", "cacheable": true, - "coherent": true, + "coherent": false, "executable": false, "readable": true, "writable": false, "read_idempotent": true, "write_idempotent": true, - "misaligned_fault": "NoFault", + "misaligned_exceptions": { + "load_store": { + "None": null + }, + "vector": { + "None": null + }, + "amo": "AccessFault" + }, + "atomic_support": "AMONone", "reservability": "RsrvNone", - "supports_cbo_zero": false + "supports_cbo_zero": false, + "supports_pte_read": false, + "supports_pte_write": false }, "include_in_device_tree": false }, @@ -119,9 +251,10 @@ }, "size": { "len": 64, - "value": "0x2000000" + "value": "0x10000000" }, "attributes": { + "mem_type": "IOMemory", "cacheable": false, "coherent": true, "executable": false, @@ -129,9 +262,20 @@ "writable": true, "read_idempotent": false, "write_idempotent": false, - "misaligned_fault": "AlignmentFault", + "misaligned_exceptions": { + "load_store": { + "Some": "AlignmentException" + }, + "vector": { + "Some": "AlignmentException" + }, + "amo": "AccessFault" + }, + "atomic_support": "AMONone", "reservability": "RsrvNone", - "supports_cbo_zero": false + "supports_cbo_zero": false, + "supports_pte_read": false, + "supports_pte_write": false }, "include_in_device_tree": false }, @@ -146,6 +290,7 @@ "value": "0x80000000" }, "attributes": { + "mem_type": "MainMemory", "cacheable": true, "coherent": true, "executable": true, @@ -153,9 +298,20 @@ "writable": true, "read_idempotent": true, "write_idempotent": true, - "misaligned_fault": "NoFault", + "misaligned_exceptions": { + "load_store": { + "None": null + }, + "vector": { + "None": null + }, + "amo": "AccessFault" + }, + "atomic_support": "AMOArithmetic", "reservability": "RsrvEventual", - "supports_cbo_zero": true + "supports_cbo_zero": true, + "supports_pte_read": true, + "supports_pte_write": true }, "include_in_device_tree": true } @@ -168,18 +324,60 @@ "hartid": 0, // Cache block size, specified as a power of 2. "cache_block_size_exp": 6, - // This specifies both the size and alignment of the reservation set, specified as a power of 2. - // It must be at least 2 on RV32 and 3 on RV64 to support Zalrsc. It must not be more than - // 6 for Za64rs and 7 for Za128rs. In all cases, it must be less than or equal to 12. - "reservation_set_size_exp": 3, + "reservation": { + // This specifies both the size and alignment of the reservation set, specified as a power of 2. + // It must be at least 2 on RV32 and 3 on RV64 to support Zalrsc. It must not be more than + // 6 for Za64rs and 7 for Za128rs. In all cases, it must be less than or equal to 12. + "reservation_set_size_exp": 3, + // Some implementations (e.g. Spike) require the Store-Conditional to provide the same + // address as the matching Load-Reserve in order to succeed, regardless of the + // configured reservation set size. This controls whether such an exact address + // match is required for a Store-Conditional to succeed. + "require_exact_reservation_addr": false, + // Some implementations (e.g. SiFive U74) also invalidate the + // reservation on stores from the same hart. If this is set to `true`, the + // model invalidates the reservation if a store from the same hart lies within + // the reservation set. + "invalidate_on_same_hart_store": false + }, "clint": { - // This must be in a suitable memory region (see `memory.regions`). + // Whether the platform contains a CLINT. + "supported": true, + // If supported, this must be in a suitable IO memory region (see `memory.regions`). + // Otherwise, these values can be left as 0. "base": 33554432, "size": 786432 }, + // Very simple MMIO device to generate interrupts for testing + // purposes. See docs/SimpleInterruptGenerator.md for details. + "simple_interrupt_generator": { + // Whether the platform contains this device. + "supported": true, + // If supported, this must be in a suitable IO memory region (see `memory.regions`) + // and 4-byte aligned. The size is always 0x20. If not supported, this can be left + // as 0. + "base": 201326592 + }, "clock_frequency": 1000000000, "instructions_per_tick": 2, - "wfi_is_nop": true + "wfi_is_nop": false, + // WFI is optionally available to User mode. Note that even if + // `wfi_is_nop` is set to `true` above, it will still not be + // available to User mode unless `wfi_available_to_user_mode` is + // also `true`. + "wfi_available_to_user_mode": true, + // The maximum increment in the time CSR before a wait instruction + // (e.g. WFI, WRS.NTO, WRS.STO) that is not a NOP expires its + // wait. It is not possible to wait indefinitely. + // + // If WFI or WRS.STO (Short TimeOut) exceed this limit in + // non-machine privilege with mstatus[TW] set, an illegal + // instruction is raised. Otherwise they retire successfully. + // + // Note: it is also legal for these instructions to spuriously + // retire successfully at any point, but there is currently no + // configuration option for this behaviour. + "max_time_to_wait": 200 }, "extensions": { "M": { @@ -207,9 +405,45 @@ // Zve64x, Zve64f, and Zve64d require `elen_exp` >= 6, // and V requires `elen_exp` >= 6 and `vlen_exp` >= 7. "support_level": "Disabled", + // `vlen_exp` and `elen_exp` should be between 3 and 16, + // inclusive. If `support_level` is `"Disabled"`, then these + // should be left as 3 (or any other legal value). "vlen_exp": 8, "elen_exp": 6, - "vl_use_ceil": false + "reserved_behavior": { + // This determines how to handle attempts by vsetvli, vsetivli, + // and vsetvl to set an unsupported or reserved vtype. + // "IllegalVtype_SetVill" - set vtype.vill, set vl to zero, clear vstart, and write rd. + // "IllegalVtype_Illegal" - treat it as an illegal instruction. + // "IllegalVtype_Fatal" - raise a Sail exception, stopping execution. + "illegal_vtype": "IllegalVtype_SetVill", + // This determines how to handle an out-of-bounds vstart (vstart >= VLMAX), which the + // vector spec marks reserved and recommends, but does not require, trapping. + // "Vstart_Illegal" - raise an illegal instruction exception. + // "Vstart_Ignore" - treat as a no-op, the instruction writes nothing. + "vstart_out_of_bounds": "Vstart_Illegal" + }, + "vl_use_ceil": false, + // The maximum index EEW for indexed vector addressing mode, as + // a power of 2. This must be at least 3 but must not exceed + // the supported ELEN. + "max_index_eew_exp": 6, + "vstart": { + // The vector specification permits implementations to raise an + // illegal instruction exception when `vstart` is non-zero for + // instructions that cannot produce such a `vstart` value through + // normal execution. + "zero_required": { + // Whether vector arithmetic instructions raise an illegal instruction + // exception when `vstart` is non-zero. This also governs instructions + // from the Zvbb, Zvbc, Zvabd, Zvfbfmin, and Zvfbfwma extensions. + "arith": true, + // Whether the vector scalar move instructions (vmv.x.s, vmv.s.x, + // vfmv.f.s and vfmv.s.f) raise an illegal instruction exception when + // `vstart` is non-zero. + "scalar_move": true + } + } }, "B": { "supported": true @@ -223,6 +457,12 @@ "Zibi": { "supported": false }, + // This extension just asserts that the cache block size is 64 bytes. + // If you enable this you also need to ensure `platform.cache_block_size_exp` + // is 6, otherwise you will get a config validation error. + "Zic64b": { + "supported": true + }, "Zicbom": { "supported": true }, @@ -232,15 +472,27 @@ "Zicboz": { "supported": true }, - // This extension just asserts that the cache block size is 64 bytes. - // If you enable this you also need to ensure `platform.cache_block_size_exp` - // is 6, otherwise you will get a config validation error. - "Zic64b": { + "Ziccamoa": { + "supported": true + }, + "Ziccamoc": { + "supported": false + }, + "Ziccif": { + "supported": true + }, + "Zicclsm": { + "supported": true + }, + "Ziccrse": { "supported": true }, "Zicfilp": { "supported": false }, + "Zicfiss": { + "supported": false + }, "Zicond": { "supported": true }, @@ -266,10 +518,10 @@ "supported": false }, "Zmmul": { - "supported": false + "supported": true }, "Zaamo": { - "supported": false + "supported": true }, "Zabha": { "supported": false @@ -278,10 +530,14 @@ "supported": false }, "Zalrsc": { - "supported": false + "supported": true }, "Zawrs": { "supported": false, + // Whether `WRS.NTO` and `WRS.STO` behave as NOPS. If they do + // not, see above note for `platform.max_time_to_wait`. If + // Zawrs is not supported, these `is_nop` fields need to be + // present but their boolean values are ignored. "nto": { "is_nop": false }, @@ -299,7 +555,7 @@ "supported": true }, "Zfhmin": { - "supported": false + "supported": true }, "Zfinx": { "supported": false @@ -323,13 +579,13 @@ "supported": false }, "Zba": { - "supported": false + "supported": true }, "Zbb": { - "supported": false + "supported": true }, "Zbs": { - "supported": false + "supported": true }, "Zbc": { "supported": true @@ -354,6 +610,8 @@ }, "Zkr": { "supported": false, + // If Zkr is not supported, these fields need to be present but + // their boolean values are ignored. "sseed_reset_value": false, "useed_reset_value": false, "sseed_read_only_zero": false, @@ -419,9 +677,15 @@ "Zvkt": { "supported": false }, + "Ssccptr": { + "supported": true + }, "Sscofpmf": { "supported": false }, + "Sscounterenw": { + "supported": true + }, "Sstc": { "supported": true }, @@ -430,12 +694,36 @@ "Sstvala": { "supported": true }, + "Svade": { + "supported": true + }, + "Svadu": { + "supported": true + }, "Svinval": { "supported": true }, "Svrsw60t59b": { "supported": false }, + "Svnapot": { + "supported": true + }, + "Ssnpm": { + "supported": false, + "supported_pmlen_7": true, + "supported_pmlen_16": true + }, + "Smnpm": { + "supported": false, + "supported_pmlen_7": true, + "supported_pmlen_16": true + }, + "Smmpm": { + "supported": false, + "supported_pmlen_7": true, + "supported_pmlen_16": true + }, "Smcntrpmf": { "supported": false }, @@ -467,8 +755,17 @@ }, "Ssqosid": { "supported": false, + // These lengths should be between 1 and 12, inclusive. + // If Ssqosid is not supported, this should be left as 1 + // (or any other legal value). "rcid_length": 12, "mcid_length": 12 + }, + "Svpbmt": { + "supported": true + }, + "Svvptc": { + "supported": true } } } From 8b2e886da68482db02e7408b6983496193441e9f Mon Sep 17 00:00:00 2001 From: Ryan Wolk Date: Wed, 22 Jul 2026 15:05:36 -0700 Subject: [PATCH 3/4] Update Sail to 0.13 Signed-off-by: Ryan Wolk --- bin/installation/sail-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/installation/sail-install.sh b/bin/installation/sail-install.sh index 18c59fe43e..ab96bfa3fb 100755 --- a/bin/installation/sail-install.sh +++ b/bin/installation/sail-install.sh @@ -27,7 +27,7 @@ ## and limitations under the License. ################################################################################################ -RISCV_SAIL_MODEL_VERSION=0.12 # Last release as of June 11, 2026 +RISCV_SAIL_MODEL_VERSION=0.13 # Last release as of July 22, 2026 set -e # break on error # If run standalone, check environment. Otherwise, use info from main install script From 1bdc371c7c73284846fbf590129994851fe9b418 Mon Sep 17 00:00:00 2001 From: Ryan Wolk Date: Thu, 30 Jul 2026 12:31:05 -0700 Subject: [PATCH 4/4] Update Sail to 0.13.1 Signed-off-by: Ryan Wolk --- bin/installation/sail-install.sh | 2 +- tests/riscof/sail_cSim/rv32gc.json | 110 ++++++++++++++++++++++----- tests/riscof/sail_cSim/rv64gc.json | 117 ++++++++++++++++++++++++----- 3 files changed, 191 insertions(+), 38 deletions(-) diff --git a/bin/installation/sail-install.sh b/bin/installation/sail-install.sh index ab96bfa3fb..f35af005c1 100755 --- a/bin/installation/sail-install.sh +++ b/bin/installation/sail-install.sh @@ -27,7 +27,7 @@ ## and limitations under the License. ################################################################################################ -RISCV_SAIL_MODEL_VERSION=0.13 # Last release as of July 22, 2026 +RISCV_SAIL_MODEL_VERSION=0.13.1 # Last release as of July 30, 2026 set -e # break on error # If run standalone, check environment. Otherwise, use info from main install script diff --git a/tests/riscof/sail_cSim/rv32gc.json b/tests/riscof/sail_cSim/rv32gc.json index ac77410947..20093b3027 100644 --- a/tests/riscof/sail_cSim/rv32gc.json +++ b/tests/riscof/sail_cSim/rv32gc.json @@ -72,6 +72,33 @@ "base_alignment": 2 } }, + "medeleg": { + // A bit set to 1 in this value specifies that the corresponding + // bit of `medeleg` can be set to 1. It represents the subset of + // delegatable traps of the implementation. Bits should not be + // set for traps that cannot be delegated as per the + // specification, and delegation of reserved traps is not + // supported. This value is ignored when the `medeleg` CSR does + // not exist. + "delegatable_bits": { + "len": 64, + "value": "0x0000_0000_000c_b3FF" + } + }, + "mideleg": { + // A bit set to 1 in this value specifies that the corresponding + // bit of `mideleg` can be set to 1. It represents the subset of + // delegatable interrupts of the implementation. Bits should not + // be set for interrupts that cannot be delegated as per the + // specification, and delegation of reserved interrupts is not + // supported. Bits set for interrupts designated for platform + // use are ignored. This value is ignored when the `mideleg` CSR + // does not exist. + "delegatable_bits": { + "len": "xlen", + "value": "0x0000_2222" + } + }, // These settings control whether the specified exceptions // cause information to be written into the appropriate // `xtval` registers. @@ -130,9 +157,26 @@ // - "ExtContext_Off" allows only {Off}. This makes the field read-only zero. "fs_legal_states": "ExtContext_FourState", "vs_legal_states": "ExtContext_Off" - } + }, + // Set the version of the privileged ISA. `"Privileged_ISA_1_13"` + // is the latest that the Sail model supports. The other + // supported value for this field is: + // - `"Privileged_ISA_1_12"` + // - `"Privileged_ISA_1_11"` + // Note that currently, not all functionality for these versions + // is available currently, and not all versions of the privileged + // ISA can be specified. + "privileged_isa_version": "Privileged_ISA_1_12" }, "memory": { + // This specifies the number of implemented physical address bits. + // This is less than or equal to: 32 for RV32 without Sv32, 34 for + // RV32 with Sv32, and 64 for RV64. Architectural bits higher than + // `physaddr_bits` in physical addresses are effectively read-only zero. + // This is required to be 13 or higher to avoid representing empty + // bitvectors in the model and since it is unlikely real implementations + // will have lower values. + "physaddr_bits": 34, "pmp": { "grain": 4, // This specifies the number of PMP entries present. @@ -169,32 +213,38 @@ "vector": { "Some": "AlignmentException" }, + // Similarly, a misaligned AMO currently always faults, and this field + // can specify either `"AccessFault"` or `"AlignmentException"`. + "amo": { + "Some": "AlignmentException" + }, // A misaligned LR/SC currently always faults, and this field can specify // whether it generates an access fault (use `"AccessFault"`) // or a misaligned exception (use `"AlignmentException"`). - "lrsc": "AlignmentException", - // Similarly, a misaligned AMO currently always faults, and this field - // can specify either `"AccessFault"` or `"AlignmentException"`. - "amo": "AlignmentException" + "lrsc": "AlignmentException" }, - // If a misaligned access was specified to have no fault in `exceptions` above, the - // fields below specify how it is handled. + // If multiple memory operations are needed, this controls whether they + // are done in increasing or decreasing address order. This is architecturally + // observable because some store operations may succeed, and even for + // loads the resulting `xtval` may depend on this setting. + "order_decreasing": false, + // If a misaligned access was specified to have no fault in + // `exceptions` above, the PMAs for the access, including the + // optional Misaligned Atomicity Granule (MAG) PMA, specify how + // it is handled. If no MAG PMA is specified, or the MAG does + // not apply to the access, the `default_allowed_within_exp` + // value below specifies this handling. // // Memory accesses that span multiple naturally aligned - // 2^allowed_within_exp sized regions will be split into multiple - // memory operations. 0 means all misaligned accesses will be split. - // The maximum value is 12 (one page). - "allowed_within_exp": 0, + // 2^default_allowed_within_exp sized regions will be split into + // multiple memory operations. 0 means all misaligned accesses + // will be split. The maximum value is 12 (one page). + "default_allowed_within_exp": 0, // If the access gets split due to `allowed_within_exp` then the size // of the operations will be one byte if `byte_by_byte` is set, otherwise // they will be the maximum size possible based on the alignment. For // example a 4-byte access to address 0x2 will use two 2-byte operations. - "byte_by_byte": false, - // If multiple memory operations are needed, this controls whether they - // are done in increasing or decreasing address order. This is architecturally - // observable because some store operations may succeed, and even for - // loads the resulting `xtval` may depend on this setting. - "order_decreasing": false + "byte_by_byte": false }, // Address to write DTB to (if provided). This must be in a suitable memory // region (see `memory.regions`). @@ -236,6 +286,8 @@ "amo": "AccessFault" }, "atomic_support": "AMONone", + "misaligned_atomicity_granule_size_exp": 0, + "vector_misaligned_atomicity_granule_size_exp": 0, "reservability": "RsrvNone", "supports_cbo_zero": false, "supports_pte_read": false, @@ -272,6 +324,8 @@ "amo": "AccessFault" }, "atomic_support": "AMONone", + "misaligned_atomicity_granule_size_exp": 0, + "vector_misaligned_atomicity_granule_size_exp": 0, "reservability": "RsrvNone", "supports_cbo_zero": false, "supports_pte_read": false, @@ -308,6 +362,8 @@ "amo": "AccessFault" }, "atomic_support": "AMOArithmetic", + "misaligned_atomicity_granule_size_exp": 0, + "vector_misaligned_atomicity_granule_size_exp": 0, "reservability": "RsrvEventual", "supports_cbo_zero": true, "supports_pte_read": true, @@ -387,7 +443,17 @@ "supported": true }, "F": { - "supported": true + "supported": true, + // When to set mstatus[FS] and mstatus[SD] to 1, as a result of fflags + // being set. There are three options: + // + // - Fflags_Dirty_Precise: Only set FS/SD when absolutely required, because + // fflags has actually changed value. + // - Fflags_Dirty_Flag: Set FS/SD when the instruction sets a flag, even + // if that flag is already set. + // - Fflags_Dirty_Instruction: Set FS/SD when we execute an instruction that + // might set a flag, even if it actually doesn't. + "fflags_dirty_policy": "Fflags_Dirty_Precise" }, "D": { "supported": true @@ -532,6 +598,14 @@ "Zalrsc": { "supported": true }, + // This extension just asserts that each memory region has a MAG + // PMA of at least 16 bytes. If you enable this you also need to ensure + // `misaligned_atomicity_granule_size_exp` for each coherent and + // cacheable main memory region is >= 4, otherwise you will get a + // config validation error. + "Zama16b": { + "supported": false + }, "Zawrs": { "supported": false, // Whether `WRS.NTO` and `WRS.STO` behave as NOPS. If they do diff --git a/tests/riscof/sail_cSim/rv64gc.json b/tests/riscof/sail_cSim/rv64gc.json index 077ac4b530..5e37ae100c 100644 --- a/tests/riscof/sail_cSim/rv64gc.json +++ b/tests/riscof/sail_cSim/rv64gc.json @@ -72,6 +72,33 @@ "base_alignment": 2 } }, + "medeleg": { + // A bit set to 1 in this value specifies that the corresponding + // bit of `medeleg` can be set to 1. It represents the subset of + // delegatable traps of the implementation. Bits should not be + // set for traps that cannot be delegated as per the + // specification, and delegation of reserved traps is not + // supported. This value is ignored when the `medeleg` CSR does + // not exist. + "delegatable_bits": { + "len": 64, + "value": "0x0000_0000_000c_b3FF" + } + }, + "mideleg": { + // A bit set to 1 in this value specifies that the corresponding + // bit of `mideleg` can be set to 1. It represents the subset of + // delegatable interrupts of the implementation. Bits should not + // be set for interrupts that cannot be delegated as per the + // specification, and delegation of reserved interrupts is not + // supported. Bits set for interrupts designated for platform + // use are ignored. This value is ignored when the `mideleg` CSR + // does not exist. + "delegatable_bits": { + "len": "xlen", + "value": "0x0000_0000_0000_2222" + } + }, // These settings control whether the specified exceptions // cause information to be written into the appropriate // `xtval` registers. @@ -130,9 +157,26 @@ // - "ExtContext_Off" allows only {Off}. This makes the field read-only zero. "fs_legal_states": "ExtContext_FourState", "vs_legal_states": "ExtContext_Off" - } + }, + // Set the version of the privileged ISA. `"Privileged_ISA_1_13"` + // is the latest that the Sail model supports. The other + // supported value for this field is: + // - `"Privileged_ISA_1_12"` + // - `"Privileged_ISA_1_11"` + // Note that currently, not all functionality for these versions + // is available currently, and not all versions of the privileged + // ISA can be specified. + "privileged_isa_version": "Privileged_ISA_1_12" }, "memory": { + // This specifies the number of implemented physical address bits. + // This is less than or equal to: 32 for RV32 without Sv32, 34 for + // RV32 with Sv32, and 64 for RV64. Architectural bits higher than + // `physaddr_bits` in physical addresses are effectively read-only zero. + // This is required to be 13 or higher to avoid representing empty + // bitvectors in the model and since it is unlikely real implementations + // will have lower values. + "physaddr_bits": 56, "pmp": { "grain": 4, // This specifies the number of PMP entries present. @@ -169,32 +213,43 @@ "vector": { "None": null }, + // Similarly, a misaligned AMO currently always faults, and this field + // can specify either `"AccessFault"` or `"AlignmentException"`. + // Wally (mmu.sv) evaluates misaligned-AMO faults AFTER address + // translation: a TLB/page-walk miss produces a page fault, and only + // then does a cacheable region raise an access fault (non-cacheable + // raises an alignment fault). Use `None` here so the misalignment + // decision is deferred to the per-region PMA below, matching hardware. + "amo": { + "None": null + }, // A misaligned LR/SC currently always faults, and this field can specify // whether it generates an access fault (use `"AccessFault"`) // or a misaligned exception (use `"AlignmentException"`). - "lrsc": "AccessFault", - // Similarly, a misaligned AMO currently always faults, and this field - // can specify either `"AccessFault"` or `"AlignmentException"`. - "amo": "AccessFault" + "lrsc": "AccessFault" }, - // If a misaligned access was specified to have no fault in `exceptions` above, the - // fields below specify how it is handled. + // If multiple memory operations are needed, this controls whether they + // are done in increasing or decreasing address order. This is architecturally + // observable because some store operations may succeed, and even for + // loads the resulting `xtval` may depend on this setting. + "order_decreasing": false, + // If a misaligned access was specified to have no fault in + // `exceptions` above, the PMAs for the access, including the + // optional Misaligned Atomicity Granule (MAG) PMA, specify how + // it is handled. If no MAG PMA is specified, or the MAG does + // not apply to the access, the `default_allowed_within_exp` + // value below specifies this handling. // // Memory accesses that span multiple naturally aligned - // 2^allowed_within_exp sized regions will be split into multiple - // memory operations. 0 means all misaligned accesses will be split. - // The maximum value is 12 (one page). - "allowed_within_exp": 0, + // 2^default_allowed_within_exp sized regions will be split into + // multiple memory operations. 0 means all misaligned accesses + // will be split. The maximum value is 12 (one page). + "default_allowed_within_exp": 0, // If the access gets split due to `allowed_within_exp` then the size // of the operations will be one byte if `byte_by_byte` is set, otherwise // they will be the maximum size possible based on the alignment. For // example a 4-byte access to address 0x2 will use two 2-byte operations. - "byte_by_byte": false, - // If multiple memory operations are needed, this controls whether they - // are done in increasing or decreasing address order. This is architecturally - // observable because some store operations may succeed, and even for - // loads the resulting `xtval` may depend on this setting. - "order_decreasing": false + "byte_by_byte": false }, // Address to write DTB to (if provided). This must be in a suitable memory // region (see `memory.regions`). @@ -236,6 +291,8 @@ "amo": "AccessFault" }, "atomic_support": "AMONone", + "misaligned_atomicity_granule_size_exp": 0, + "vector_misaligned_atomicity_granule_size_exp": 0, "reservability": "RsrvNone", "supports_cbo_zero": false, "supports_pte_read": false, @@ -269,9 +326,11 @@ "vector": { "Some": "AlignmentException" }, - "amo": "AccessFault" + "amo": "AlignmentException" }, "atomic_support": "AMONone", + "misaligned_atomicity_granule_size_exp": 0, + "vector_misaligned_atomicity_granule_size_exp": 0, "reservability": "RsrvNone", "supports_cbo_zero": false, "supports_pte_read": false, @@ -308,6 +367,8 @@ "amo": "AccessFault" }, "atomic_support": "AMOArithmetic", + "misaligned_atomicity_granule_size_exp": 0, + "vector_misaligned_atomicity_granule_size_exp": 0, "reservability": "RsrvEventual", "supports_cbo_zero": true, "supports_pte_read": true, @@ -387,7 +448,17 @@ "supported": true }, "F": { - "supported": true + "supported": true, + // When to set mstatus[FS] and mstatus[SD] to 1, as a result of fflags + // being set. There are three options: + // + // - Fflags_Dirty_Precise: Only set FS/SD when absolutely required, because + // fflags has actually changed value. + // - Fflags_Dirty_Flag: Set FS/SD when the instruction sets a flag, even + // if that flag is already set. + // - Fflags_Dirty_Instruction: Set FS/SD when we execute an instruction that + // might set a flag, even if it actually doesn't. + "fflags_dirty_policy": "Fflags_Dirty_Precise" }, "D": { "supported": true @@ -532,6 +603,14 @@ "Zalrsc": { "supported": true }, + // This extension just asserts that each memory region has a MAG + // PMA of at least 16 bytes. If you enable this you also need to ensure + // `misaligned_atomicity_granule_size_exp` for each coherent and + // cacheable main memory region is >= 4, otherwise you will get a + // config validation error. + "Zama16b": { + "supported": false + }, "Zawrs": { "supported": false, // Whether `WRS.NTO` and `WRS.STO` behave as NOPS. If they do