diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 665ad5e150..0a3b6467e8 100755 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -119,6 +119,7 @@ repos: rev: v5.0.2 hooks: - id: reuse-lint-file + exclude: COMMIT_EDITMSG - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook rev: v9.22.0 diff --git a/Rakefile b/Rakefile index 95060bc632..1e16b20f3b 100755 --- a/Rakefile +++ b/Rakefile @@ -264,18 +264,15 @@ namespace :test do puts "All files validate against their schema" end - task idl: ["#{$root}/.stamps/resolve-rv32.stamp", "#{$root}/.stamps/resolve-rv64.stamp"] do - print "Parsing IDL code for RV32..." - cfg_arch32 = cfg_arch_for("rv32") - puts "done" - - cfg_arch32.type_check + task :idl do + cfg = ENV["CFG"] + raise "Missing CFG enviornment variable" if cfg.nil? - print "Parsing IDL code for RV64..." - cfg_arch64 = cfg_arch_for("rv64") + print "Parsing IDL code for #{cfg}..." + cfg_arch = cfg_arch_for(cfg) puts "done" - cfg_arch64.type_check + cfg_arch.type_check puts "All IDL passed type checking" end @@ -442,8 +439,14 @@ namespace :test do Rake::Task["test:lib"].invoke $logger.info "Running test:schema" Rake::Task["test:schema"].invoke - $logger.info "Running test:idl" + $logger.info "UPDATE: Running test:idl for rv32" + ENV["CFG"] = "rv32" + Rake::Task["test:idl"].invoke + $logger.info "UPDATE: Running test:idl for rv64" + ENV["CFG"] = "rv64" Rake::Task["test:idl"].invoke + $logger.info "UPDATE: Running test:idl for qc_iu" + ENV["CFG"] = "qc_iu" $logger.info "Running test:inst_encodings" Rake::Task["test:inst_encodings"].invoke $logger.info "Running test:llvm" diff --git a/arch/csr/F/fcsr.yaml b/arch/csr/F/fcsr.yaml index a44a5b39c7..d1cd315e8d 100644 --- a/arch/csr/F/fcsr.yaml +++ b/arch/csr/F/fcsr.yaml @@ -5,6 +5,7 @@ kind: csr name: fcsr long_name: Floating-point control and status register (`frm` + `fflags`) address: 0x003 +writeable: true description: | The floating-point control and status register, `fcsr`, is a RISC-V control and status register (CSR). It is a 32-bit read/write register diff --git a/arch/csr/H/henvcfg.yaml b/arch/csr/H/henvcfg.yaml index 462bc0f138..719a45345d 100644 --- a/arch/csr/H/henvcfg.yaml +++ b/arch/csr/H/henvcfg.yaml @@ -4,6 +4,7 @@ $schema: "csr_schema.json#" kind: csr name: henvcfg address: 0x60A +writeable: true long_name: Hypervisor Environment Configuration description: | The henvcfg CSR is a 64-bit read/write register that controls certain characteristics of the diff --git a/arch/csr/H/henvcfgh.yaml b/arch/csr/H/henvcfgh.yaml index 4f136fce3f..1b423c783e 100644 --- a/arch/csr/H/henvcfgh.yaml +++ b/arch/csr/H/henvcfgh.yaml @@ -4,6 +4,7 @@ $schema: "csr_schema.json#" kind: csr name: henvcfgh address: 0x61A +writeable: true base: 32 long_name: most-significant 32 bits of Hypervisor Environment Configuration description: | diff --git a/arch/csr/H/hgatp.yaml b/arch/csr/H/hgatp.yaml index 034b1d0178..b890bdc7cd 100644 --- a/arch/csr/H/hgatp.yaml +++ b/arch/csr/H/hgatp.yaml @@ -102,6 +102,7 @@ description: | HFENCE.GVMA instruction (see <>) before or after writing `hgatp`. address: 0x680 +writeable: true priv_mode: S definedBy: H length: SXLEN diff --git a/arch/csr/H/htimedelta.yaml b/arch/csr/H/htimedelta.yaml index 48de13f532..be9572cfa6 100644 --- a/arch/csr/H/htimedelta.yaml +++ b/arch/csr/H/htimedelta.yaml @@ -15,6 +15,7 @@ description: | `htimedelta` may be used to represent negative time offsets. address: 0x605 +writeable: true priv_mode: S definedBy: H length: 64 diff --git a/arch/csr/H/htimedeltah.yaml b/arch/csr/H/htimedeltah.yaml index 9aad2147e5..663b3e61be 100644 --- a/arch/csr/H/htimedeltah.yaml +++ b/arch/csr/H/htimedeltah.yaml @@ -8,6 +8,7 @@ description: | Upper half of the `htimedelta` CSR. address: 0x615 +writeable: true priv_mode: S definedBy: H length: 32 diff --git a/arch/csr/H/htinst.yaml b/arch/csr/H/htinst.yaml index f4a9df9e4a..6c1edf713b 100644 --- a/arch/csr/H/htinst.yaml +++ b/arch/csr/H/htinst.yaml @@ -4,6 +4,7 @@ $schema: "csr_schema.json#" kind: csr name: htinst address: 0x64a +writeable: true long_name: Hypervisor Trap Instruction Register description: | When a trap is taken into HS-mode, mtinst is written with a value that, if nonzero, diff --git a/arch/csr/H/htval.yaml b/arch/csr/H/htval.yaml index 39631dcfc2..2f3498e01d 100644 --- a/arch/csr/H/htval.yaml +++ b/arch/csr/H/htval.yaml @@ -4,6 +4,7 @@ $schema: "csr_schema.json#" kind: csr name: htval address: 0x643 +writeable: true long_name: Hypervisor Trap Value Register description: | When a trap is taken into HS-mode, htval is written with additional exception-specific information, alongside stval, to assist software in handling the trap. diff --git a/arch/csr/H/mtinst.yaml b/arch/csr/H/mtinst.yaml index bbfff0cd32..a145cb4124 100644 --- a/arch/csr/H/mtinst.yaml +++ b/arch/csr/H/mtinst.yaml @@ -4,6 +4,7 @@ $schema: "csr_schema.json#" kind: csr name: mtinst address: 0x34a +writeable: true long_name: Machine Trap Instruction Register description: | When a trap is taken into M-mode, mtinst is written with a value that, if nonzero, diff --git a/arch/csr/H/mtval2.yaml b/arch/csr/H/mtval2.yaml index 03d5db862f..fce637d5c1 100644 --- a/arch/csr/H/mtval2.yaml +++ b/arch/csr/H/mtval2.yaml @@ -4,6 +4,7 @@ $schema: "csr_schema.json#" kind: csr name: mtval2 address: 0x34b +writeable: true long_name: Machine Second Trap Value Register description: | When a trap is taken into M-mode from a virtual mode, mtval2 is written with additional exception-specific information, diff --git a/arch/csr/H/vsatp.yaml b/arch/csr/H/vsatp.yaml index f7a81242cb..07c6a30946 100644 --- a/arch/csr/H/vsatp.yaml +++ b/arch/csr/H/vsatp.yaml @@ -4,6 +4,7 @@ $schema: "csr_schema.json#" kind: csr name: vsatp address: 0x280 +writeable: true virtual_address: 0x180 long_name: Virtual Supervisor Address Translation and Protection description: | diff --git a/arch/csr/Smrnmi/mncause.yaml b/arch/csr/Smrnmi/mncause.yaml index fa0ad9cd63..d944135118 100644 --- a/arch/csr/Smrnmi/mncause.yaml +++ b/arch/csr/Smrnmi/mncause.yaml @@ -5,6 +5,7 @@ kind: csr name: mncause long_name: Resumable NMI cause address: 0x742 +writeable: true priv_mode: M length: MXLEN definedBy: Smrnmi diff --git a/arch/csr/Smrnmi/mnepc.yaml b/arch/csr/Smrnmi/mnepc.yaml index e249aa441b..5fefa12361 100644 --- a/arch/csr/Smrnmi/mnepc.yaml +++ b/arch/csr/Smrnmi/mnepc.yaml @@ -5,6 +5,7 @@ kind: csr name: mnepc long_name: Machine Exception Program Counter address: 0x741 +writeable: true priv_mode: M length: MXLEN description: | diff --git a/arch/csr/Smrnmi/mnscratch.yaml b/arch/csr/Smrnmi/mnscratch.yaml index b3d89c52b2..1cceddef16 100644 --- a/arch/csr/Smrnmi/mnscratch.yaml +++ b/arch/csr/Smrnmi/mnscratch.yaml @@ -5,9 +5,12 @@ kind: csr name: mnscratch long_name: Machine Scratch Register address: 0x740 +writeable: true priv_mode: M length: MXLEN -description: Scratch register for software use in NMI / double trap. Bits are not interpreted by hardware. +description: + Scratch register for software use in NMI / double trap. Bits are not + interpreted by hardware. definedBy: Smrnmi fields: SCRATCH: diff --git a/arch/csr/Smrnmi/mnstatus.yaml b/arch/csr/Smrnmi/mnstatus.yaml index 1ab64b3967..b79a2ec298 100644 --- a/arch/csr/Smrnmi/mnstatus.yaml +++ b/arch/csr/Smrnmi/mnstatus.yaml @@ -5,11 +5,14 @@ kind: csr name: mnstatus long_name: Machine NMI Status address: 0x744 +writeable: true priv_mode: M # length is MXLEN-bit length: MXLEN -description: The mnstatus register tracks and controls the hart's current NMI operating state. +description: + The mnstatus register tracks and controls the hart's current NMI operating + state. definedBy: Smrnmi fields: MNPP: diff --git a/arch/csr/Zihpm/hpmcounter10h.yaml b/arch/csr/Zihpm/hpmcounter10h.yaml index 81f80156af..8c27418868 100644 --- a/arch/csr/Zihpm/hpmcounter10h.yaml +++ b/arch/csr/Zihpm/hpmcounter10h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter10h.COUNT + location: 31-0 + alias: mhpmcounter10h.COUNT[63:32] description: Alias of `mhpmcounter10h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter11h.yaml b/arch/csr/Zihpm/hpmcounter11h.yaml index 5eefd08e03..e92df5366a 100644 --- a/arch/csr/Zihpm/hpmcounter11h.yaml +++ b/arch/csr/Zihpm/hpmcounter11h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter11h.COUNT + location: 31-0 + alias: mhpmcounter11h.COUNT[63:32] description: Alias of `mhpmcounter11h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter12h.yaml b/arch/csr/Zihpm/hpmcounter12h.yaml index 9007c8f506..97aabcb585 100644 --- a/arch/csr/Zihpm/hpmcounter12h.yaml +++ b/arch/csr/Zihpm/hpmcounter12h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter12h.COUNT + location: 31-0 + alias: mhpmcounter12h.COUNT[63:32] description: Alias of `mhpmcounter12h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter13h.yaml b/arch/csr/Zihpm/hpmcounter13h.yaml index fb684749df..f9da99fee4 100644 --- a/arch/csr/Zihpm/hpmcounter13h.yaml +++ b/arch/csr/Zihpm/hpmcounter13h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter13h.COUNT + location: 31-0 + alias: mhpmcounter13h.COUNT[63:32] description: Alias of `mhpmcounter13h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter14h.yaml b/arch/csr/Zihpm/hpmcounter14h.yaml index 9e38f55a14..e9c98969f7 100644 --- a/arch/csr/Zihpm/hpmcounter14h.yaml +++ b/arch/csr/Zihpm/hpmcounter14h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter14h.COUNT + location: 31-0 + alias: mhpmcounter14h.COUNT[63:32] description: Alias of `mhpmcounter14h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter15h.yaml b/arch/csr/Zihpm/hpmcounter15h.yaml index 745a8d284e..d584056c73 100644 --- a/arch/csr/Zihpm/hpmcounter15h.yaml +++ b/arch/csr/Zihpm/hpmcounter15h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter15h.COUNT + location: 31-0 + alias: mhpmcounter15h.COUNT[63:32] description: Alias of `mhpmcounter15h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter16h.yaml b/arch/csr/Zihpm/hpmcounter16h.yaml index 39f9043123..ba33b09e5e 100644 --- a/arch/csr/Zihpm/hpmcounter16h.yaml +++ b/arch/csr/Zihpm/hpmcounter16h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter16h.COUNT + location: 31-0 + alias: mhpmcounter16h.COUNT[63:32] description: Alias of `mhpmcounter16h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter17h.yaml b/arch/csr/Zihpm/hpmcounter17h.yaml index 6a55a4e1ec..4d4b83f564 100644 --- a/arch/csr/Zihpm/hpmcounter17h.yaml +++ b/arch/csr/Zihpm/hpmcounter17h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter17h.COUNT + location: 31-0 + alias: mhpmcounter17h.COUNT[63:32] description: Alias of `mhpmcounter17h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter18h.yaml b/arch/csr/Zihpm/hpmcounter18h.yaml index 4427ba61d7..2cd6676a39 100644 --- a/arch/csr/Zihpm/hpmcounter18h.yaml +++ b/arch/csr/Zihpm/hpmcounter18h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter18h.COUNT + location: 31-0 + alias: mhpmcounter18h.COUNT[63:32] description: Alias of `mhpmcounter18h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter19h.yaml b/arch/csr/Zihpm/hpmcounter19h.yaml index bc4872908c..59e0707f57 100644 --- a/arch/csr/Zihpm/hpmcounter19h.yaml +++ b/arch/csr/Zihpm/hpmcounter19h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter19h.COUNT + location: 31-0 + alias: mhpmcounter19h.COUNT[63:32] description: Alias of `mhpmcounter19h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter20h.yaml b/arch/csr/Zihpm/hpmcounter20h.yaml index 6b75ff97e6..e819e7a046 100644 --- a/arch/csr/Zihpm/hpmcounter20h.yaml +++ b/arch/csr/Zihpm/hpmcounter20h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter20h.COUNT + location: 31-0 + alias: mhpmcounter20h.COUNT[63:32] description: Alias of `mhpmcounter20h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter21h.yaml b/arch/csr/Zihpm/hpmcounter21h.yaml index d644bf0ca9..51dcd09706 100644 --- a/arch/csr/Zihpm/hpmcounter21h.yaml +++ b/arch/csr/Zihpm/hpmcounter21h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter21h.COUNT + location: 31-0 + alias: mhpmcounter21h.COUNT[63:32] description: Alias of `mhpmcounter21h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter22h.yaml b/arch/csr/Zihpm/hpmcounter22h.yaml index ab3836ad4a..5c2c51dce3 100644 --- a/arch/csr/Zihpm/hpmcounter22h.yaml +++ b/arch/csr/Zihpm/hpmcounter22h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter22h.COUNT + location: 31-0 + alias: mhpmcounter22h.COUNT[63:32] description: Alias of `mhpmcounter22h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter23h.yaml b/arch/csr/Zihpm/hpmcounter23h.yaml index 11c69f5e77..3c791da8b5 100644 --- a/arch/csr/Zihpm/hpmcounter23h.yaml +++ b/arch/csr/Zihpm/hpmcounter23h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter23h.COUNT + location: 31-0 + alias: mhpmcounter23h.COUNT[63:32] description: Alias of `mhpmcounter23h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter24h.yaml b/arch/csr/Zihpm/hpmcounter24h.yaml index d1223f183b..1b46ec08dd 100644 --- a/arch/csr/Zihpm/hpmcounter24h.yaml +++ b/arch/csr/Zihpm/hpmcounter24h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter24h.COUNT + location: 31-0 + alias: mhpmcounter24h.COUNT[63:32] description: Alias of `mhpmcounter24h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter25h.yaml b/arch/csr/Zihpm/hpmcounter25h.yaml index 891956a29d..35bde4eb49 100644 --- a/arch/csr/Zihpm/hpmcounter25h.yaml +++ b/arch/csr/Zihpm/hpmcounter25h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter25h.COUNT + location: 31-0 + alias: mhpmcounter25h.COUNT[63:32] description: Alias of `mhpmcounter25h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter26h.yaml b/arch/csr/Zihpm/hpmcounter26h.yaml index 267827d2ac..338fc2c07d 100644 --- a/arch/csr/Zihpm/hpmcounter26h.yaml +++ b/arch/csr/Zihpm/hpmcounter26h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter26h.COUNT + location: 31-0 + alias: mhpmcounter26h.COUNT[63:32] description: Alias of `mhpmcounter26h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter27h.yaml b/arch/csr/Zihpm/hpmcounter27h.yaml index ecc4f89d37..323ebb22c6 100644 --- a/arch/csr/Zihpm/hpmcounter27h.yaml +++ b/arch/csr/Zihpm/hpmcounter27h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter27h.COUNT + location: 31-0 + alias: mhpmcounter27h.COUNT[63:32] description: Alias of `mhpmcounter27h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter28h.yaml b/arch/csr/Zihpm/hpmcounter28h.yaml index ee3b013e17..e3935c1ba5 100644 --- a/arch/csr/Zihpm/hpmcounter28h.yaml +++ b/arch/csr/Zihpm/hpmcounter28h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter28h.COUNT + location: 31-0 + alias: mhpmcounter28h.COUNT[63:32] description: Alias of `mhpmcounter28h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter29h.yaml b/arch/csr/Zihpm/hpmcounter29h.yaml index f903b631f4..de92f4ba7b 100644 --- a/arch/csr/Zihpm/hpmcounter29h.yaml +++ b/arch/csr/Zihpm/hpmcounter29h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter29h.COUNT + location: 31-0 + alias: mhpmcounter29h.COUNT[63:32] description: Alias of `mhpmcounter29h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter30h.yaml b/arch/csr/Zihpm/hpmcounter30h.yaml index 4c370ead95..39a9b53e4e 100644 --- a/arch/csr/Zihpm/hpmcounter30h.yaml +++ b/arch/csr/Zihpm/hpmcounter30h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter30h.COUNT + location: 31-0 + alias: mhpmcounter30h.COUNT[63:32] description: Alias of `mhpmcounter30h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter31h.yaml b/arch/csr/Zihpm/hpmcounter31h.yaml index 397143b275..f9cb637033 100644 --- a/arch/csr/Zihpm/hpmcounter31h.yaml +++ b/arch/csr/Zihpm/hpmcounter31h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter31h.COUNT + location: 31-0 + alias: mhpmcounter31h.COUNT[63:32] description: Alias of `mhpmcounter31h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter3h.yaml b/arch/csr/Zihpm/hpmcounter3h.yaml index 6eb41a9e0f..70f68937f2 100644 --- a/arch/csr/Zihpm/hpmcounter3h.yaml +++ b/arch/csr/Zihpm/hpmcounter3h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter3h.COUNT + location: 31-0 + alias: mhpmcounter3h.COUNT[63:32] description: Alias of `mhpmcounter3h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter4h.yaml b/arch/csr/Zihpm/hpmcounter4h.yaml index 9faab3c5c0..08e24d5d9f 100644 --- a/arch/csr/Zihpm/hpmcounter4h.yaml +++ b/arch/csr/Zihpm/hpmcounter4h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter4h.COUNT + location: 31-0 + alias: mhpmcounter4h.COUNT[63:32] description: Alias of `mhpmcounter4h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter5h.yaml b/arch/csr/Zihpm/hpmcounter5h.yaml index 662458fdab..99d51b7b25 100644 --- a/arch/csr/Zihpm/hpmcounter5h.yaml +++ b/arch/csr/Zihpm/hpmcounter5h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter5h.COUNT + location: 31-0 + alias: mhpmcounter5h.COUNT[63:32] description: Alias of `mhpmcounter5h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter6h.yaml b/arch/csr/Zihpm/hpmcounter6h.yaml index e481365550..9d17286173 100644 --- a/arch/csr/Zihpm/hpmcounter6h.yaml +++ b/arch/csr/Zihpm/hpmcounter6h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter6h.COUNT + location: 31-0 + alias: mhpmcounter6h.COUNT[63:32] description: Alias of `mhpmcounter6h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter7h.yaml b/arch/csr/Zihpm/hpmcounter7h.yaml index 4b1e69a34d..97404a5411 100644 --- a/arch/csr/Zihpm/hpmcounter7h.yaml +++ b/arch/csr/Zihpm/hpmcounter7h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter7h.COUNT + location: 31-0 + alias: mhpmcounter7h.COUNT[63:32] description: Alias of `mhpmcounter7h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter8h.yaml b/arch/csr/Zihpm/hpmcounter8h.yaml index a71d48687a..75baff05ba 100644 --- a/arch/csr/Zihpm/hpmcounter8h.yaml +++ b/arch/csr/Zihpm/hpmcounter8h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter8h.COUNT + location: 31-0 + alias: mhpmcounter8h.COUNT[63:32] description: Alias of `mhpmcounter8h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounter9h.yaml b/arch/csr/Zihpm/hpmcounter9h.yaml index 9a751b36c8..c0189fd158 100644 --- a/arch/csr/Zihpm/hpmcounter9h.yaml +++ b/arch/csr/Zihpm/hpmcounter9h.yaml @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter9h.COUNT + location: 31-0 + alias: mhpmcounter9h.COUNT[63:32] description: Alias of `mhpmcounter9h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/Zihpm/hpmcounterNh.layout b/arch/csr/Zihpm/hpmcounterNh.layout index 95742beae1..b124937d7a 100644 --- a/arch/csr/Zihpm/hpmcounterNh.layout +++ b/arch/csr/Zihpm/hpmcounterNh.layout @@ -26,12 +26,12 @@ description: | ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U -length: 64 +length: 32 definedBy: Sscofpmf fields: COUNT: - location: 63-0 - alias: mhpmcounter<%= hpm_num %>h.COUNT + location: 31-0 + alias: mhpmcounter<%= hpm_num %>h.COUNT[63:32] description: Alias of `mhpmcounter<%= hpm_num %>h.COUNT`. type: RO-H reset_value: UNDEFINED_LEGAL diff --git a/arch/csr/cycle.yaml b/arch/csr/cycle.yaml index 0d7d975cf5..7d2b493245 100644 --- a/arch/csr/cycle.yaml +++ b/arch/csr/cycle.yaml @@ -5,6 +5,7 @@ kind: csr name: cycle long_name: Cycle counter for RDCYCLE Instruction address: 0xC00 +writeable: false description: | Alias for M-mode CSR `mcycle`. diff --git a/arch/csr/cycleh.yaml b/arch/csr/cycleh.yaml index 75ed1b438d..770a46e1b2 100644 --- a/arch/csr/cycleh.yaml +++ b/arch/csr/cycleh.yaml @@ -5,6 +5,7 @@ kind: csr name: cycleh long_name: High-half cycle counter for RDCYCLE Instruction address: 0xC80 +writeable: false base: 32 description: | Alias for M-mode CSR `mcycleh`. diff --git a/arch/csr/hedeleg.yaml b/arch/csr/hedeleg.yaml index f0eb50f396..e50da89a4e 100644 --- a/arch/csr/hedeleg.yaml +++ b/arch/csr/hedeleg.yaml @@ -5,6 +5,7 @@ kind: csr name: hedeleg long_name: Hypervisor Exception Delegation address: 0x602 +writeable: true priv_mode: S length: 64 description: | diff --git a/arch/csr/hedelegh.yaml b/arch/csr/hedelegh.yaml index fc1ad672eb..abe635b742 100644 --- a/arch/csr/hedelegh.yaml +++ b/arch/csr/hedelegh.yaml @@ -5,6 +5,7 @@ kind: csr name: hedelegh long_name: Hypervisor Exception Delegation High address: 0x612 +writeable: true base: 32 priv_mode: S length: 32 diff --git a/arch/csr/hstatus.yaml b/arch/csr/hstatus.yaml index ebfa1adebe..a822b8d652 100644 --- a/arch/csr/hstatus.yaml +++ b/arch/csr/hstatus.yaml @@ -5,6 +5,7 @@ kind: csr name: hstatus long_name: Hypervisor Status address: 0x600 +writeable: true priv_mode: S length: SXLEN description: | diff --git a/arch/csr/instret.yaml b/arch/csr/instret.yaml index b54fedf8d9..2e2be9a645 100644 --- a/arch/csr/instret.yaml +++ b/arch/csr/instret.yaml @@ -5,6 +5,7 @@ kind: csr name: instret long_name: Instructions retired counter for RDINSTRET Instruction address: 0xC02 +writeable: false description: | Alias for M-mode CSR `minstret`. diff --git a/arch/csr/instreth.yaml b/arch/csr/instreth.yaml index bb4df78053..0283bbc389 100644 --- a/arch/csr/instreth.yaml +++ b/arch/csr/instreth.yaml @@ -5,6 +5,7 @@ kind: csr name: instreth long_name: Instructions retired counter, high bits address: 0xC82 +writeable: false base: 32 description: | Alias for high bits of M-mode CSR `minstret`[63:32]. diff --git a/arch/csr/marchid.yaml b/arch/csr/marchid.yaml index fc7e8d8dd1..88e9f5ec1a 100644 --- a/arch/csr/marchid.yaml +++ b/arch/csr/marchid.yaml @@ -5,6 +5,7 @@ kind: csr name: marchid long_name: Machine Architecture ID address: 0xf12 +writeable: false priv_mode: M length: MXLEN description: | diff --git a/arch/csr/mcause.yaml b/arch/csr/mcause.yaml index 11b8b07d58..0f7666d662 100644 --- a/arch/csr/mcause.yaml +++ b/arch/csr/mcause.yaml @@ -5,6 +5,7 @@ kind: csr name: mcause long_name: Machine Cause address: 0x342 +writeable: true priv_mode: M length: MXLEN description: Reports the cause of the latest exception. diff --git a/arch/csr/mconfigptr.yaml b/arch/csr/mconfigptr.yaml index c9c644b053..4cf53f5874 100644 --- a/arch/csr/mconfigptr.yaml +++ b/arch/csr/mconfigptr.yaml @@ -5,6 +5,7 @@ kind: csr name: mconfigptr long_name: Machine Configuration Pointer address: 0xF15 +writeable: false description: | Holds a physical address pointer to the unified discovery data structure in Memory. @@ -45,7 +46,9 @@ fields: ADDRESS: location_rv32: 31-0 location_rv64: 63-0 - description: Pointer to physical address of the Unified Discovery configuration data structure. + description: + Pointer to physical address of the Unified Discovery configuration + data structure. type: RO reset_value(): | return CONFIG_PTR_ADDRESS; diff --git a/arch/csr/mcycle.yaml b/arch/csr/mcycle.yaml index 8fb8102f8b..c36433fcf4 100644 --- a/arch/csr/mcycle.yaml +++ b/arch/csr/mcycle.yaml @@ -6,6 +6,7 @@ name: mcycle long_name: Machine Cycle Counter definedBy: Zicntr address: 0xB00 +writeable: true description: | Counts the number of clock cycles executed by the processor core on which the hart is running. diff --git a/arch/csr/mcycleh.yaml b/arch/csr/mcycleh.yaml index fb1798174f..0de21583c1 100644 --- a/arch/csr/mcycleh.yaml +++ b/arch/csr/mcycleh.yaml @@ -6,6 +6,7 @@ name: mcycleh long_name: High-half machine Cycle Counter definedBy: Zicntr address: 0xB80 +writeable: true description: | High-half alias of `mcycle`. priv_mode: M diff --git a/arch/csr/medeleg.yaml b/arch/csr/medeleg.yaml index 94b6981d04..134ba8baaa 100644 --- a/arch/csr/medeleg.yaml +++ b/arch/csr/medeleg.yaml @@ -5,6 +5,7 @@ kind: csr name: medeleg long_name: Machine Exception Delegation address: 0x302 +writeable: true priv_mode: M length: 64 description: | diff --git a/arch/csr/medelegh.yaml b/arch/csr/medelegh.yaml index bff63b2b0f..e481d906af 100644 --- a/arch/csr/medelegh.yaml +++ b/arch/csr/medelegh.yaml @@ -5,6 +5,7 @@ kind: csr name: medelegh long_name: Machine Exception Delegation, High bits address: 0x312 +writeable: true priv_mode: M length: 32 base: 32 diff --git a/arch/csr/menvcfg.yaml b/arch/csr/menvcfg.yaml index 8feafff958..f2ea62adea 100644 --- a/arch/csr/menvcfg.yaml +++ b/arch/csr/menvcfg.yaml @@ -4,6 +4,7 @@ $schema: "csr_schema.json#" kind: csr name: menvcfg address: 0x30A +writeable: true long_name: Machine Environment Configuration description: | Contains fields that control certain characteristics of the execution environment diff --git a/arch/csr/menvcfgh.yaml b/arch/csr/menvcfgh.yaml index 3543f9ea6f..541ff71339 100644 --- a/arch/csr/menvcfgh.yaml +++ b/arch/csr/menvcfgh.yaml @@ -4,6 +4,7 @@ $schema: "csr_schema.json#" kind: csr name: menvcfgh address: 0x31A +writeable: true base: 32 long_name: Machine Environment Configuration description: Contains bits to enable/disable extensions diff --git a/arch/csr/mepc.yaml b/arch/csr/mepc.yaml index 3118fee37a..92ca5c9314 100644 --- a/arch/csr/mepc.yaml +++ b/arch/csr/mepc.yaml @@ -5,6 +5,7 @@ kind: csr name: mepc long_name: Machine Exception Program Counter address: 0x341 +writeable: true priv_mode: M length: MXLEN description: | diff --git a/arch/csr/mhartid.yaml b/arch/csr/mhartid.yaml index 8b5e50793d..6fb026ff41 100644 --- a/arch/csr/mhartid.yaml +++ b/arch/csr/mhartid.yaml @@ -5,6 +5,7 @@ kind: csr name: mhartid long_name: Machine Hart ID address: 0xf14 +writeable: false priv_mode: M length: MXLEN description: Reports the unique hart-specific ID in the system. diff --git a/arch/csr/mideleg.yaml b/arch/csr/mideleg.yaml index af53608a13..a6b0abf963 100644 --- a/arch/csr/mideleg.yaml +++ b/arch/csr/mideleg.yaml @@ -5,6 +5,7 @@ kind: csr name: mideleg long_name: Machine Interrupt Delegation address: 0x303 +writeable: true priv_mode: M length: MXLEN definedBy: diff --git a/arch/csr/mie.yaml b/arch/csr/mie.yaml index 4eca4d5187..52a4c2fcf0 100644 --- a/arch/csr/mie.yaml +++ b/arch/csr/mie.yaml @@ -5,6 +5,7 @@ kind: csr name: mie long_name: Machine Interrupt Enable address: 0x304 +writeable: true priv_mode: M length: MXLEN definedBy: Sm diff --git a/arch/csr/mimpid.yaml b/arch/csr/mimpid.yaml index 4d35e45c79..1c9bd58844 100644 --- a/arch/csr/mimpid.yaml +++ b/arch/csr/mimpid.yaml @@ -5,6 +5,7 @@ kind: csr name: mimpid long_name: Machine Implementation ID address: 0xf13 +writeable: false priv_mode: M length: MXLEN description: | diff --git a/arch/csr/minstret.yaml b/arch/csr/minstret.yaml index 9d4344a1c2..2c28fddf30 100644 --- a/arch/csr/minstret.yaml +++ b/arch/csr/minstret.yaml @@ -5,6 +5,7 @@ kind: csr name: minstret long_name: Machine Instructions Retired Counter address: 0xB02 +writeable: true description: | Counts the number of instructions retired by this hart from some arbitrary start point in the past. diff --git a/arch/csr/minstreth.yaml b/arch/csr/minstreth.yaml index 0df4282594..97cb2f6a27 100644 --- a/arch/csr/minstreth.yaml +++ b/arch/csr/minstreth.yaml @@ -5,6 +5,7 @@ kind: csr name: minstreth long_name: Machine Instructions Retired Counter address: 0xB82 +writeable: true description: | Upper half of 64-bit instructions retired counters. diff --git a/arch/csr/mip.yaml b/arch/csr/mip.yaml index 4d831856b4..954f27ff55 100644 --- a/arch/csr/mip.yaml +++ b/arch/csr/mip.yaml @@ -5,6 +5,7 @@ kind: csr name: mip long_name: Machine Interrupt Pending address: 0x344 +writeable: true priv_mode: M # Description is shared with mie CSR (it copies it from here). diff --git a/arch/csr/misa.yaml b/arch/csr/misa.yaml index 1853393ca4..8f7973ecd0 100644 --- a/arch/csr/misa.yaml +++ b/arch/csr/misa.yaml @@ -5,6 +5,7 @@ kind: csr name: misa long_name: Machine ISA Control address: 0x301 +writeable: true priv_mode: M length: MXLEN description: Reports the XLEN and "major" extensions supported by the ISA. diff --git a/arch/csr/mscratch.yaml b/arch/csr/mscratch.yaml index 544b6bce0c..9f126e1f0b 100644 --- a/arch/csr/mscratch.yaml +++ b/arch/csr/mscratch.yaml @@ -5,6 +5,7 @@ kind: csr name: mscratch long_name: Machine Scratch Register address: 0x340 +writeable: true priv_mode: M length: MXLEN description: Scratch register for software use. Bits are not interpreted by hardware. diff --git a/arch/csr/mseccfg.yaml b/arch/csr/mseccfg.yaml index bc76cd8864..209daa1047 100644 --- a/arch/csr/mseccfg.yaml +++ b/arch/csr/mseccfg.yaml @@ -5,6 +5,7 @@ kind: csr name: mseccfg long_name: Machine Security Configuration address: 0x747 +writeable: true priv_mode: M length: 64 description: Machine Security Configuration diff --git a/arch/csr/mseccfgh.yaml b/arch/csr/mseccfgh.yaml index 3f2330a5c7..b8f894eb05 100644 --- a/arch/csr/mseccfgh.yaml +++ b/arch/csr/mseccfgh.yaml @@ -6,6 +6,7 @@ name: mseccfgh long_name: Most significant 32 bits of Machine Security Configuration base: 32 address: 0x757 +writeable: true priv_mode: M length: 32 description: Machine Security Configuration diff --git a/arch/csr/mstatus.yaml b/arch/csr/mstatus.yaml index f4750626cb..b8ff0086e3 100644 --- a/arch/csr/mstatus.yaml +++ b/arch/csr/mstatus.yaml @@ -5,6 +5,7 @@ kind: csr name: mstatus long_name: Machine Status address: 0x300 +writeable: true priv_mode: M # length is MXLEN-bit @@ -12,7 +13,9 @@ priv_mode: M # MXLEN cannot change dynamically, so this will be converted to an integer # in the generated, configuration-dependent spec length: MXLEN -description: The mstatus register tracks and controls the hart's current operating state. +description: + The mstatus register tracks and controls the hart's current operating + state. definedBy: Sm fields: SD: diff --git a/arch/csr/mstatush.yaml b/arch/csr/mstatush.yaml index 350390e55e..b6ccea518c 100644 --- a/arch/csr/mstatush.yaml +++ b/arch/csr/mstatush.yaml @@ -5,10 +5,13 @@ kind: csr name: mstatush long_name: Machine Status High address: 0x310 +writeable: true priv_mode: M base: 32 length: 32 -description: The mstatus register tracks and controls the hart's current operating state. +description: + The mstatus register tracks and controls the hart's current operating + state. definedBy: name: Sm version: ">= 1.12" diff --git a/arch/csr/mtval.yaml b/arch/csr/mtval.yaml index 71b0b9f1e2..cec0138e65 100644 --- a/arch/csr/mtval.yaml +++ b/arch/csr/mtval.yaml @@ -5,6 +5,7 @@ kind: csr name: mtval long_name: Machine Trap Value address: 0x343 +writeable: true description: Holds trap-specific information priv_mode: M length: MXLEN diff --git a/arch/csr/mtvec.yaml b/arch/csr/mtvec.yaml index 265f39fd3e..bf850afc1a 100644 --- a/arch/csr/mtvec.yaml +++ b/arch/csr/mtvec.yaml @@ -5,6 +5,7 @@ kind: csr name: mtvec long_name: Machine Trap Vector Control address: 0x305 +writeable: true priv_mode: M length: MXLEN description: Controls where traps jump. diff --git a/arch/csr/mvendorid.yaml b/arch/csr/mvendorid.yaml index a752ece2da..afd5144f07 100644 --- a/arch/csr/mvendorid.yaml +++ b/arch/csr/mvendorid.yaml @@ -5,6 +5,7 @@ kind: csr name: mvendorid long_name: Machine Vendor ID address: 0xf11 +writeable: false priv_mode: M length: 32 description: Reports the JEDEC manufacturer ID of the core. diff --git a/arch/csr/satp.yaml b/arch/csr/satp.yaml index 36db54e445..0768cfbbb2 100644 --- a/arch/csr/satp.yaml +++ b/arch/csr/satp.yaml @@ -4,8 +4,11 @@ $schema: "csr_schema.json#" kind: csr name: satp address: 0x180 +writeable: true long_name: Supervisor Address Translation and Protection -description: Controls the translation mode in (H)S-mode and U-mode, and holds the current ASID and page table base pointer. +description: + Controls the translation mode in (H)S-mode and U-mode, and holds the + current ASID and page table base pointer. priv_mode: S length: SXLEN definedBy: S diff --git a/arch/csr/scause.yaml b/arch/csr/scause.yaml index c206cd60de..9d25a7906a 100644 --- a/arch/csr/scause.yaml +++ b/arch/csr/scause.yaml @@ -5,6 +5,7 @@ kind: csr name: scause long_name: Supervisor Cause address: 0x142 +writeable: true priv_mode: S length: SXLEN description: Reports the cause of the latest exception. diff --git a/arch/csr/senvcfg.yaml b/arch/csr/senvcfg.yaml index 6feb151349..a142d371ce 100644 --- a/arch/csr/senvcfg.yaml +++ b/arch/csr/senvcfg.yaml @@ -4,6 +4,7 @@ $schema: "csr_schema.json#" kind: csr name: senvcfg address: 0x10A +writeable: true long_name: Supervisor Environment Configuration description: | Contains fields that control certain characteristics of the U-mode execution environment. diff --git a/arch/csr/sepc.yaml b/arch/csr/sepc.yaml index 82fae3a4b3..861f8747f3 100644 --- a/arch/csr/sepc.yaml +++ b/arch/csr/sepc.yaml @@ -5,6 +5,7 @@ kind: csr name: sepc long_name: Supervisor Exception Program Counter address: 0x141 +writeable: true priv_mode: S length: 64 description: | diff --git a/arch/csr/sip.yaml b/arch/csr/sip.yaml index 6de22310d6..f307cc34c5 100644 --- a/arch/csr/sip.yaml +++ b/arch/csr/sip.yaml @@ -5,6 +5,7 @@ kind: csr name: sip long_name: Supervisor Interrupt Pending address: 0x144 +writeable: true priv_mode: S description: | A restricted view of the interrupt pending bits in `mip`. diff --git a/arch/csr/sscratch.yaml b/arch/csr/sscratch.yaml index dceaf14863..4a3c6d405b 100644 --- a/arch/csr/sscratch.yaml +++ b/arch/csr/sscratch.yaml @@ -5,6 +5,7 @@ kind: csr name: sscratch long_name: Supervisor Scratch Register address: 0x140 +writeable: true priv_mode: S length: 64 description: Scratch register for software use. Bits are not interpreted by hardware. diff --git a/arch/csr/sstatus.yaml b/arch/csr/sstatus.yaml index c9ae22e33c..34d644689f 100644 --- a/arch/csr/sstatus.yaml +++ b/arch/csr/sstatus.yaml @@ -5,6 +5,7 @@ kind: csr name: sstatus long_name: Supervisor Status address: 0x100 +writeable: true priv_mode: S length: SXLEN description: | diff --git a/arch/csr/stval.yaml b/arch/csr/stval.yaml index fb447e5059..dddff978c9 100644 --- a/arch/csr/stval.yaml +++ b/arch/csr/stval.yaml @@ -5,6 +5,7 @@ kind: csr name: stval long_name: Supervisor Trap Value address: 0x143 +writeable: true description: Holds trap-specific information priv_mode: S length: 64 diff --git a/arch/csr/stvec.yaml b/arch/csr/stvec.yaml index 3432f8a89a..a77ace47c0 100644 --- a/arch/csr/stvec.yaml +++ b/arch/csr/stvec.yaml @@ -5,6 +5,7 @@ kind: csr name: stvec long_name: Supervisor Trap Vector address: 0x105 +writeable: true priv_mode: S length: 64 description: Controls where traps jump. diff --git a/arch/csr/time.yaml b/arch/csr/time.yaml index 5ebccad92d..2e64103e43 100644 --- a/arch/csr/time.yaml +++ b/arch/csr/time.yaml @@ -5,6 +5,7 @@ kind: csr name: time long_name: Timer for RDTIME Instruction address: 0xC01 +writeable: false description: | [when,"TIME_CSR_IMPLEMENTED == false"] This CSR does not exist, and access will cause an IllegalInstruction exception. diff --git a/arch/csr/timeh.yaml b/arch/csr/timeh.yaml index cdf1ff35be..26a2671597 100644 --- a/arch/csr/timeh.yaml +++ b/arch/csr/timeh.yaml @@ -5,6 +5,7 @@ kind: csr name: timeh long_name: High-half timer for RDTIME Instruction address: 0xC81 +writeable: false base: 32 description: | [when,"TIME_CSR_IMPLEMENTED == false"] diff --git a/arch/csr/vscause.yaml b/arch/csr/vscause.yaml index cfaf02d1dd..6d4c26472e 100644 --- a/arch/csr/vscause.yaml +++ b/arch/csr/vscause.yaml @@ -5,6 +5,7 @@ kind: csr name: vscause long_name: Virtual Supervisor Cause address: 0x242 +writeable: true virtual_address: 0x142 priv_mode: VS length: VSXLEN diff --git a/arch/csr/vsepc.yaml b/arch/csr/vsepc.yaml index 68c7e77d6a..49ff1bbd3e 100644 --- a/arch/csr/vsepc.yaml +++ b/arch/csr/vsepc.yaml @@ -5,6 +5,7 @@ kind: csr name: vsepc long_name: Virtual Supervisor Exception Program Counter address: 0x241 +writeable: true virtual_address: 0x141 priv_mode: VS length: 64 diff --git a/arch/csr/vsstatus.yaml b/arch/csr/vsstatus.yaml index 357490a0c4..14e6b23255 100644 --- a/arch/csr/vsstatus.yaml +++ b/arch/csr/vsstatus.yaml @@ -5,6 +5,7 @@ kind: csr name: vsstatus long_name: Virtual Supervisor Status address: 0x200 +writeable: true virtual_address: 0x100 priv_mode: VS length: VSXLEN diff --git a/arch/csr/vstval.yaml b/arch/csr/vstval.yaml index 7baa9e8b16..131116cc5e 100644 --- a/arch/csr/vstval.yaml +++ b/arch/csr/vstval.yaml @@ -5,6 +5,7 @@ kind: csr name: vstval long_name: Virtual supervisor Trap Value address: 0x243 +writeable: true virtual_address: 0x143 description: Holds trap-specific information priv_mode: S diff --git a/arch/csr/vstvec.yaml b/arch/csr/vstvec.yaml index 4357ac5894..2405b748a8 100644 --- a/arch/csr/vstvec.yaml +++ b/arch/csr/vstvec.yaml @@ -5,6 +5,7 @@ kind: csr name: vstvec long_name: Supervisor Trap Vector address: 0x205 +writeable: true virtual_address: 0x105 priv_mode: S length: 64 diff --git a/arch/inst/Zicsr/csrrc.yaml b/arch/inst/Zicsr/csrrc.yaml index 8cfe163c0e..b0ee71c340 100644 --- a/arch/inst/Zicsr/csrrc.yaml +++ b/arch/inst/Zicsr/csrrc.yaml @@ -24,16 +24,26 @@ access: vu: always data_independent_timing: false operation(): | + Csr csr_handle = direct_csr_lookup(csr); + Boolean will_write = xs1 != 0; - check_csr(csr, will_write, $encoding); - XReg initial_csr_value = CSR[csr].sw_read(); + # permission checks + if (csr_handle.valid == false) { + unimplemented_csr($encoding); + } else if (!compatible_mode?(csr_handle.mode, mode())) { + raise (ExceptionCode::IllegalInstruction, mode(), $encoding); + } else if (will_write && csr_handle.writable == false) { + raise (ExceptionCode::IllegalInstruction, mode(), $encoding); + } + + XReg initial_csr_value = csr_sw_read(csr_handle); if (xs1 != 0) { # clear bits using the mask # performing any WARL transformations first XReg mask = X[xs1]; - CSR[csr].sw_write(initial_csr_value & ~mask); + csr_sw_write(csr_handle, initial_csr_value & ~mask); } X[xd] = initial_csr_value; diff --git a/arch/inst/Zicsr/csrrci.yaml b/arch/inst/Zicsr/csrrci.yaml index 76fbd993c5..d29e427d2c 100644 --- a/arch/inst/Zicsr/csrrci.yaml +++ b/arch/inst/Zicsr/csrrci.yaml @@ -25,15 +25,25 @@ access: data_independent_timing: false operation(): | Boolean will_write = uimm != 0; - check_csr(csr, will_write, $encoding); - XReg initial_csr_value = CSR[csr].sw_read(); + Csr csr_handle = direct_csr_lookup(csr); - if (uimm != 0) { + # permission checks + if (csr_handle.valid == false) { + unimplemented_csr($encoding); + } else if (!compatible_mode?(csr_handle.mode, mode())) { + raise (ExceptionCode::IllegalInstruction, mode(), $encoding); + } else if (will_write && csr_handle.writable == false) { + raise (ExceptionCode::IllegalInstruction, mode(), $encoding); + } + + XReg initial_csr_value = csr_sw_read(csr_handle); + + if (will_write) { # set bits using the mask # performing any WARL transformations first XReg mask = uimm; - CSR[csr].sw_write(initial_csr_value & ~mask); + csr_sw_write(csr_handle, initial_csr_value & ~mask); } X[xd] = initial_csr_value; diff --git a/arch/inst/Zicsr/csrrs.yaml b/arch/inst/Zicsr/csrrs.yaml index 10d81607c5..7c308eab56 100644 --- a/arch/inst/Zicsr/csrrs.yaml +++ b/arch/inst/Zicsr/csrrs.yaml @@ -31,15 +31,25 @@ access: vu: always operation(): | Boolean will_write = rs1 != 0; - check_csr(csr, will_write, $encoding); - XReg initial_csr_value = CSR[csr].sw_read(); + Csr csr_handle = direct_csr_lookup(csr); + + # permission checks + if (csr_handle.valid == false) { + unimplemented_csr($encoding); + } else if (!compatible_mode?(csr_handle.mode, mode())) { + raise (ExceptionCode::IllegalInstruction, mode(), $encoding); + } else if (will_write && csr_handle.writable == false) { + raise (ExceptionCode::IllegalInstruction, mode(), $encoding); + } + + XReg initial_csr_value = csr_sw_read(csr_handle); if (will_write) { # set bits using the mask # performing any WARL transformations first XReg mask = X[rs1]; - CSR[csr].sw_write(initial_csr_value | mask); + csr_sw_write(csr_handle, initial_csr_value | mask); } X[rd] = initial_csr_value; diff --git a/arch/inst/Zicsr/csrrsi.yaml b/arch/inst/Zicsr/csrrsi.yaml index 585a623756..4734fb3fd2 100644 --- a/arch/inst/Zicsr/csrrsi.yaml +++ b/arch/inst/Zicsr/csrrsi.yaml @@ -25,15 +25,25 @@ access: data_independent_timing: false operation(): | Boolean will_write = uimm != 0; - check_csr(csr, will_write, $encoding); - XReg initial_csr_value = CSR[csr].sw_read(); + Csr csr_handle = direct_csr_lookup(csr); + + # permission checks + if (csr_handle.valid == false) { + unimplemented_csr($encoding); + } else if (!compatible_mode?(csr_handle.mode, mode())) { + raise (ExceptionCode::IllegalInstruction, mode(), $encoding); + } else if (will_write && csr_handle.writable == false) { + raise (ExceptionCode::IllegalInstruction, mode(), $encoding); + } + + XReg initial_csr_value = csr_sw_read(csr_handle); if (will_write) { # set bits using the mask # performing any WARL transformations first XReg mask = uimm; - CSR[csr].sw_write(initial_csr_value | mask); + csr_sw_write(csr_handle, initial_csr_value | mask); } X[xd] = initial_csr_value; diff --git a/arch/inst/Zicsr/csrrw.yaml b/arch/inst/Zicsr/csrrw.yaml index 66bb09f41c..0179397948 100644 --- a/arch/inst/Zicsr/csrrw.yaml +++ b/arch/inst/Zicsr/csrrw.yaml @@ -29,17 +29,26 @@ access: vs: always vu: always operation(): | - check_csr(csr, true, $encoding); + Csr csr_handle = direct_csr_lookup(csr); Bits initial_value = X[xs1]; + # permission checks + if (csr_handle.valid == false) { + unimplemented_csr($encoding); + } else if (!compatible_mode?(csr_handle.mode, mode())) { + raise (ExceptionCode::IllegalInstruction, mode(), $encoding); + } else if (csr_handle.writable == false) { + raise (ExceptionCode::IllegalInstruction, mode(), $encoding); + } + if (xd != 0) { - X[xd] = CSR[csr].sw_read(); + X[xd] = csr_sw_read(csr_handle); } # writes the value in X[xs1] to the CSR, # performing any WARL transformations first - CSR[csr].sw_write(initial_value); + csr_sw_write(csr_handle, initial_value); # SPDX-SnippetBegin # SPDX-FileCopyrightText: 2017-2025 Contributors to the RISCV Sail Model diff --git a/arch/inst/Zicsr/csrrwi.yaml b/arch/inst/Zicsr/csrrwi.yaml index 04b8d9f1ef..e35113f859 100644 --- a/arch/inst/Zicsr/csrrwi.yaml +++ b/arch/inst/Zicsr/csrrwi.yaml @@ -29,15 +29,24 @@ access: vs: always vu: always operation(): | - check_csr(csr, true, $encoding); + Csr csr_handle = direct_csr_lookup(csr); + + # permission checks + if (csr_handle.valid == false) { + unimplemented_csr($encoding); + } else if (!compatible_mode?(csr_handle.mode, mode())) { + raise (ExceptionCode::IllegalInstruction, mode(), $encoding); + } else if (csr_handle.writable == false) { + raise (ExceptionCode::IllegalInstruction, mode(), $encoding); + } if (rd != 0) { - X[rd] = CSR[csr].sw_read(); + X[rd] = csr_sw_read(csr_handle); } # writes the zero-extended immediate to the CSR, # performing any WARL transformations first - CSR[csr].sw_write({{MXLEN-5{1'b0}}, imm}); + csr_sw_write(csr_handle, {{MXLEN-5{1'b0}}, imm}); # SPDX-SnippetBegin # SPDX-FileCopyrightText: 2017-2025 Contributors to the RISCV Sail Model diff --git a/arch/isa/builtin_functions.idl b/arch/isa/builtin_functions.idl index 8d0ad73e96..175fa55a42 100644 --- a/arch/isa/builtin_functions.idl +++ b/arch/isa/builtin_functions.idl @@ -24,6 +24,77 @@ generated function implemented_csr? { } } +enum CsrAddressType { + Direct # accessible with csrrw, etc. + Indirect # only accessible with csrind +} + +struct Csr { + Boolean valid; + String name; + CsrAddressType addr_type; + Bits address; # direct or indirect address + Bits<4> indirect_slot; # window slot, when addr_type == Indirect + PrivilegeMode mode; + Boolean writable; +} + +# implementation is generated from CSR YAML defintions +generated function direct_csr_lookup { + returns Csr + arguments + Bits<12> csr_addr + description { + Return CSR info for a CSR with direct address +csr_addr+. + + If no CSR exists, .valid == false + } +} + +# implementation is generated from CSR YAML defintions +generated function indirect_csr_lookup { + returns Csr + arguments + Bits csr_addr, + Bits<4> window_slot # 1-indexed "slot" in the window (corresponding to *ireg) + description { + Return CSR info for a CSR with indirect address +csr_addr+ at window slot +window_slot+. + + If no CSR exists, .valid == false + } +} + +generated function csr_hw_read { + returns Bits<64> # even in rv32, there are 64-bit CSRs + arguments + Csr csr + description { + Returns the raw value of csr + } +} + +# implementation is generated from CSR YAML defintions +generated function csr_sw_read { + returns Bits<64> # even in rv32, there are 64-bit CSRs + arguments + Csr csr + description { + Returns the result of CSR[csr].sw_read(); i.e., the software view of the register + } +} + +# implementation is generated from CSR YAML defintions +generated function csr_sw_write { + arguments + Csr csr, + Bits value + description { + Writes +value+ to +csr+, applying an WARL transformations first. + + Uses the sw_write(...) functions of CSR field definitions. + } +} + builtin function unpredictable { arguments String why description { diff --git a/arch/isa/globals.isa b/arch/isa/globals.isa index 08e7966617..218277450b 100644 --- a/arch/isa/globals.isa +++ b/arch/isa/globals.isa @@ -267,6 +267,41 @@ function set_mode { } } +function compatible_mode? { + returns Boolean + arguments + PrivilegeMode target_mode, + PrivilegeMode actual_mode + description { + Returns true if +target_mode+ is more privileged than +actual_mode+. + } + body { + if (target_mode == PrivilegeMode::M) { + return actual_mode == PrivilegeMode::M; + } else if (target_mode == PrivilegeMode::S) { + return + (actual_mode == PrivilegeMode::M) || + (actual_mode == PrivilegeMode::S); + } else if (target_mode == PrivilegeMode::U) { + return + (actual_mode == PrivilegeMode::M) || + (actual_mode == PrivilegeMode::S) || + (actual_mode == PrivilegeMode::U); + } else if (target_mode == PrivilegeMode::VS) { + return + (actual_mode == PrivilegeMode::M) || + (actual_mode == PrivilegeMode::S) || + (actual_mode == PrivilegeMode::VS); + } else if (target_mode == PrivilegeMode::VU) { + return + (actual_mode == PrivilegeMode::M) || + (actual_mode == PrivilegeMode::S) || + (actual_mode == PrivilegeMode::VS) || + (actual_mode == PrivilegeMode::VU); + } + } +} + function exception_handling_mode { returns PrivilegeMode arguments ExceptionCode exception_code @@ -515,79 +550,6 @@ function stval_for { } } -function csr? { - returns Boolean - arguments Bits<12> csr_addr - description { - Returns true if csr_addr is an implemented csr, and the defining extension is not disabled - } - body { - if (!implemented_csr?(csr_addr)) { - return false; - } - - if (implemented?(ExtensionName::S) - && !CSR[csr_addr].implemented_without?(ExtensionName::S)) { - - return CSR[misa].S == 1'b1; - - } else if (implemented?(ExtensionName::U) - && !CSR[csr_addr].implemented_without?(ExtensionName::U)) { - - return CSR[misa].U == 1'b1; - - } else if (implemented?(ExtensionName::H) - && !CSR[csr_addr].implemented_without?(ExtensionName::H)) { - - return CSR[misa].H == 1'b1; - } - - return true; - } -} - -function check_csr { - arguments Bits<12> csr_addr, Boolean for_write, Bits encoding - description { - Checks if 'csr_addr' is a valid address, can be read in the current mode, - and, if for_write is true, can be written in the current mode. - - If the check fails, will either raise IllegalInsruction or cause - unpredictable behavior, depending on TRAP_ON_UNIMPLEMENTED_CSR - } - body { - if (!csr?(csr_addr)) { - if (TRAP_ON_UNIMPLEMENTED_CSR) { - raise(ExceptionCode::IllegalInstruction, mode(), encoding); - } else { - unpredictable("Attempt to read unimplemented CSR"); - } - } - PrivilegeMode priv_mode; - if (csr_addr[9:8] == 2'b00) { - priv_mode = PrivilegeMode::M; - } else if (csr_addr[9:8] == 2'b01 || csr_addr[9:8] == 2'b10) { - priv_mode = PrivilegeMode::S; - } else { - priv_mode = PrivilegeMode::U; - } - if (priv_mode == PrivilegeMode::M) { - if (mode() != PrivilegeMode::M) { - raise(ExceptionCode::IllegalInstruction, mode(), encoding); - } - } else if (priv_mode == PrivilegeMode::S) { - if (mode() == PrivilegeMode::U || mode() == PrivilegeMode::VU) { - raise(ExceptionCode::IllegalInstruction, mode(), encoding); - } - } - - if (for_write && csr_addr[11:10] == 2'b11) { - # write to read-only CSR - raise(ExceptionCode::IllegalInstruction, mode(), encoding); - } - } -} - function vstval_for { returns XReg arguments ExceptionCode exception_code, XReg tval @@ -1024,8 +986,13 @@ function pmp_match_64 { # get the registers for this PMP entry Bits<12> pmpcfg_idx = pmpcfg0_addr + (i/8)*2; Bits<6> shamt = (i % 8)*8; - PmpCfg cfg = ($bits(CSR[pmpcfg0_addr]) >> shamt)[7:0]; + + Csr pmpcfg_csr = direct_csr_lookup(pmpcfg_idx); + PmpCfg cfg = (csr_hw_read(pmpcfg_csr) >> shamt)[7:0]; + Bits<12> pmpaddr_idx = pmpaddr0_addr + i; + Csr pmpaddr_csr = direct_csr_lookup(pmpaddr_idx); + Bits<64> pmpaddr_csr_value = csr_sw_read(pmpaddr_csr); # set up the default range limits, which will result in NoMatch when # compared to the access @@ -1038,9 +1005,10 @@ function pmp_match_64 { range_lo = 0; } else { # otherwise, it's the address in the next lowest pmpaddr register - range_lo = ($bits(CSR[pmpaddr_idx - 1]) << 2)[PHYS_ADDR_WIDTH-1:0]; + Csr tor_pmpaddr_csr = direct_csr_lookup(pmpaddr_idx - 1); + range_lo = (csr_sw_read(tor_pmpaddr_csr) << 2)[PHYS_ADDR_WIDTH-1:0]; } - range_hi = ($bits(CSR[pmpaddr_idx]) << 2)[PHYS_ADDR_WIDTH-1:0]; + range_hi = (pmpaddr_csr_value << 2)[PHYS_ADDR_WIDTH-1:0]; } else if (cfg.A == $bits(PmpCfg_A::NAPOT)) { # Example pmpaddr: 0b00010101111 @@ -1049,14 +1017,14 @@ function pmp_match_64 { # mask: 0b00000011111 # ~mask: 0b11111100000 # len = mask + 1: 0b00000100000 - Bits pmpaddr_value = CSR[pmpaddr_idx].sw_read()[PHYS_ADDR_WIDTH-3:0]; + Bits pmpaddr_value = pmpaddr_csr_value[PHYS_ADDR_WIDTH-3:0]; Bits mask = pmpaddr_value ^ (pmpaddr_value + 1); range_lo = (pmpaddr_value & ~mask) << 2; Bits len = mask + 1; range_hi = ((pmpaddr_value & ~mask) + len) << 2; } else if (cfg.A == $bits(PmpCfg_A::NA4)) { - range_lo = ($bits(CSR[pmpaddr_idx]) << 2)[PHYS_ADDR_WIDTH-1:0]; + range_lo = (pmpaddr_csr_value << 2)[PHYS_ADDR_WIDTH-1:0]; range_hi = range_lo + 4; } @@ -1091,8 +1059,13 @@ function pmp_match_32 { # get the registers for this PMP entry Bits<12> pmpcfg_idx = pmpcfg0_addr + (i/4); Bits<6> shamt = (i % 4)*8; - PmpCfg cfg = ($bits(CSR[pmpcfg0_addr]) >> shamt)[7:0]; + + Csr pmpcfg_csr = direct_csr_lookup(pmpcfg_idx); + PmpCfg cfg = (csr_hw_read(pmpcfg_csr) >> shamt)[7:0]; + Bits<12> pmpaddr_idx = pmpaddr0_addr + i; + Csr pmpaddr_csr = direct_csr_lookup(pmpaddr_idx); + Bits<32> pmpaddr_csr_value = csr_sw_read(pmpaddr_csr); # set up the default range limits, which will result in NoMatch when # compared to the access @@ -1105,9 +1078,10 @@ function pmp_match_32 { range_lo = 0; } else { # otherwise, it's the address in the next lowest pmpaddr register - range_lo = ($bits(CSR[pmpaddr_idx - 1]) << 2)[PHYS_ADDR_WIDTH-1:0]; + Csr tor_pmpaddr_csr = direct_csr_lookup(pmpaddr_idx - 1); + range_lo = (csr_sw_read(tor_pmpaddr_csr) << 2)[PHYS_ADDR_WIDTH-1:0]; } - range_hi = ($bits(CSR[pmpaddr_idx]) << 2)[PHYS_ADDR_WIDTH-1:0]; + range_hi = (pmpaddr_csr_value << 2)[PHYS_ADDR_WIDTH-1:0]; } else if (cfg.A == $bits(PmpCfg_A::NAPOT)) { # Example pmpaddr: 0b00010101111 @@ -1116,14 +1090,14 @@ function pmp_match_32 { # mask: 0b00000011111 # ~mask: 0b11111100000 # len = mask + 1: 0b00000100000 - Bits pmpaddr_value = CSR[pmpaddr_idx].sw_read()[PHYS_ADDR_WIDTH-3:0]; + Bits pmpaddr_value = pmpaddr_csr_value[PHYS_ADDR_WIDTH-3:0]; Bits mask = pmpaddr_value ^ (pmpaddr_value + 1); range_lo = (pmpaddr_value & ~mask) << 2; Bits len = mask + 1; range_hi = ((pmpaddr_value & ~mask) + len) << 2; } else if (cfg.A == $bits(PmpCfg_A::NA4)) { - range_lo = ($bits(CSR[pmpaddr_idx]) << 2)[PHYS_ADDR_WIDTH-1:0]; + range_lo = (pmpaddr_csr_value << 2)[PHYS_ADDR_WIDTH-1:0]; range_hi = range_lo + 4; } diff --git a/arch_overlay/qc_iu/inst/Xqci/qc.c.clrint.yaml b/arch_overlay/qc_iu/inst/Xqci/qc.c.clrint.yaml index 3be38f2786..cdd1b645e4 100644 --- a/arch_overlay/qc_iu/inst/Xqci/qc.c.clrint.yaml +++ b/arch_overlay/qc_iu/inst/Xqci/qc.c.clrint.yaml @@ -29,5 +29,5 @@ operation(): | XReg idx = rs1 / 32; XReg bit = rs1 % 32; - XReg pre_csr = CSR[MCLICIP0_ADDR + idx].sw_read(); - CSR[MCLICIP0_ADDR + idx].sw_write(pre_csr & ~(1 << bit)); + Csr pre_csr = direct_csr_lookup(MCLICIP0_ADDR + idx); + csr_sw_write(pre_csr, csr_sw_read(pre_csr) & ~(1 << bit)); diff --git a/arch_overlay/qc_iu/inst/Xqci/qc.c.setint.yaml b/arch_overlay/qc_iu/inst/Xqci/qc.c.setint.yaml index 074157bbc3..9f7b5e5e69 100644 --- a/arch_overlay/qc_iu/inst/Xqci/qc.c.setint.yaml +++ b/arch_overlay/qc_iu/inst/Xqci/qc.c.setint.yaml @@ -29,5 +29,5 @@ operation(): | XReg idx = rs1 / 32; XReg bit = rs1 % 32; - XReg pre_csr = CSR[MCLICIP0_ADDR + idx].sw_read(); - CSR[MCLICIP0_ADDR + idx].sw_write(pre_csr | (1 << bit)); + Csr pre_csr = direct_csr_lookup(MCLICIP0_ADDR + idx); + csr_sw_write(pre_csr, csr_sw_read(pre_csr) | (1 << bit)); diff --git a/arch_overlay/qc_iu/inst/Xqci/qc.clrinti.yaml b/arch_overlay/qc_iu/inst/Xqci/qc.clrinti.yaml index 86be3a762d..81e9b42c53 100644 --- a/arch_overlay/qc_iu/inst/Xqci/qc.clrinti.yaml +++ b/arch_overlay/qc_iu/inst/Xqci/qc.clrinti.yaml @@ -28,5 +28,5 @@ operation(): | XReg idx = imm / 32; XReg bit = imm % 32; - XReg pre_csr = CSR[MCLICIP0_ADDR + idx].sw_read(); - CSR[MCLICIP0_ADDR + idx].sw_write(pre_csr & ~(1 << bit)); + Csr pre_csr = direct_csr_lookup(MCLICIP0_ADDR + idx); + csr_sw_write(pre_csr, csr_sw_read(pre_csr) & ~(1 << bit)); diff --git a/arch_overlay/qc_iu/inst/Xqci/qc.csrrwr.yaml b/arch_overlay/qc_iu/inst/Xqci/qc.csrrwr.yaml index 47c7a9a49f..4edaa962e4 100644 --- a/arch_overlay/qc_iu/inst/Xqci/qc.csrrwr.yaml +++ b/arch_overlay/qc_iu/inst/Xqci/qc.csrrwr.yaml @@ -35,10 +35,11 @@ access: vs: always vu: always operation(): | - XReg csr = X[rs2]; + XReg csr_addr = X[rs2]; + Csr csr = direct_csr_lookup(csr_addr); if (rd != 0) { - X[rd] = CSR[csr].sw_read(); + X[rd] = csr_sw_read(csr); } # writes the value in X[rs1] to the CSR, # performing any WARL transformations first - CSR[csr].sw_write(X[rs1]); + csr_sw_write(csr, X[rs1]); diff --git a/arch_overlay/qc_iu/inst/Xqci/qc.csrrwri.yaml b/arch_overlay/qc_iu/inst/Xqci/qc.csrrwri.yaml index 1324b0f778..1e268cf76e 100644 --- a/arch_overlay/qc_iu/inst/Xqci/qc.csrrwri.yaml +++ b/arch_overlay/qc_iu/inst/Xqci/qc.csrrwri.yaml @@ -35,10 +35,11 @@ access: vs: always vu: always operation(): | - XReg csr = X[rs2]; + XReg csr_addr = X[rs2]; + Csr csr = direct_csr_lookup(csr_addr); if (rd != 0) { - X[rd] = CSR[csr].sw_read(); + X[rd] = csr_sw_read(csr_addr); } # writes the zero-extended immediate to the CSR, # performing any WARL transformations first - CSR[csr].sw_write({{MXLEN-5{1'b0}}, imm}); + csr_sw_write(csr, {{MXLEN-5{1'b0}}, imm}); diff --git a/arch_overlay/qc_iu/inst/Xqci/qc.setinti.yaml b/arch_overlay/qc_iu/inst/Xqci/qc.setinti.yaml index 537c311bde..9255bb8ac0 100644 --- a/arch_overlay/qc_iu/inst/Xqci/qc.setinti.yaml +++ b/arch_overlay/qc_iu/inst/Xqci/qc.setinti.yaml @@ -28,5 +28,5 @@ operation(): | XReg idx = imm / 32; XReg bit = imm % 32; - XReg pre_csr = CSR[MCLICIP0_ADDR + idx].sw_read(); - CSR[MCLICIP0_ADDR + idx].sw_write(pre_csr | (1 << bit)); + Csr pre_csr = direct_csr_lookup(MCLICIP0_ADDR + idx); + csr_sw_write(pre_csr, csr_sw_read(pre_csr) | (1 << bit)); diff --git a/backends/cpp_hart_gen/cpp/include/udb/csr.hpp b/backends/cpp_hart_gen/cpp/include/udb/csr.hpp index cfdf1cdeb7..5d4bd83723 100644 --- a/backends/cpp_hart_gen/cpp/include/udb/csr.hpp +++ b/backends/cpp_hart_gen/cpp/include/udb/csr.hpp @@ -84,6 +84,12 @@ namespace udb { virtual void reset() = 0; + // the most privileged mode that has access to this csr + virtual PrivilegeMode mode() const = 0; + + // false if the CSR is read only + virtual bool writable() const = 0; + // read the raw bits of a CSR value // // some CSRs are shorter than XLEN bits, but none are longer diff --git a/backends/cpp_hart_gen/lib/gen_cpp.rb b/backends/cpp_hart_gen/lib/gen_cpp.rb index c7d8bc7bbf..e9c81c6b89 100644 --- a/backends/cpp_hart_gen/lib/gen_cpp.rb +++ b/backends/cpp_hart_gen/lib/gen_cpp.rb @@ -313,9 +313,9 @@ def gen_cpp(symtab, indent, indent_spaces: 2) field = csr_field.field_def(symtab) if symtab.cfg_arch.multi_xlen? && field.dynamic_location? - "#{' '*indent}__UDB_CSR_BY_NAME(#{csr_field.csr_name(symtab)}).#{field.name}()._hw_write(#{write_value.gen_cpp(symtab, 0, indent_spaces:)}, __UDB_XLEN)" + "#{' '*indent}__UDB_CSR_BY_NAME(#{csr_field.csr_name}).#{field.name}()._hw_write(#{write_value.gen_cpp(symtab, 0, indent_spaces:)}, __UDB_XLEN)" else - "#{' '*indent}__UDB_CSR_BY_NAME(#{csr_field.csr_name(symtab)}).#{field.name}()._hw_write(#{write_value.gen_cpp(symtab, 0, indent_spaces:)})" + "#{' '*indent}__UDB_CSR_BY_NAME(#{csr_field.csr_name}).#{field.name}()._hw_write(#{write_value.gen_cpp(symtab, 0, indent_spaces:)})" end end end @@ -757,15 +757,10 @@ def gen_cpp(symtab, indent = 0, indent_spaces: 2) class CsrReadExpressionAst def gen_cpp(symtab, indent = 0, indent_spaces: 2) csr = csr_def(symtab) - if csr.nil? - # csr isn't known at runtime... - "#{' '*indent}__UDB_CSR_BY_ADDR(#{idx_expr.gen_cpp(symtab, 0, indent_spaces:)}).hw_read(__UDB_XLEN)" + if symtab.cfg_arch.multi_xlen? && csr.format_changes_with_xlen? + "#{' '*indent}__UDB_CSR_BY_NAME(#{csr.name})._hw_read(__UDB_XLEN)" else - if symtab.cfg_arch.multi_xlen? && csr.format_changes_with_xlen? - "#{' '*indent}__UDB_CSR_BY_NAME(#{csr.name})._hw_read(__UDB_XLEN)" - else - "#{' '*indent}__UDB_CSR_BY_NAME(#{csr.name})._hw_read()" - end + "#{' '*indent}__UDB_CSR_BY_NAME(#{csr.name})._hw_read()" end end end diff --git a/backends/cpp_hart_gen/templates/csrs.hxx.erb b/backends/cpp_hart_gen/templates/csrs.hxx.erb index 7bae01031f..2ecd720643 100644 --- a/backends/cpp_hart_gen/templates/csrs.hxx.erb +++ b/backends/cpp_hart_gen/templates/csrs.hxx.erb @@ -220,6 +220,8 @@ namespace udb { unsigned address() const override { return <%= csr.address %>; } static constexpr unsigned _address() { return <%= csr.address %>; } const std::string name() const override { return "<%= csr.name %>"; } + PrivilegeMode mode() const override { return PrivilegeMode::<%= csr.priv_mode %>; } + bool writable() const override { return <%= csr.writable %>; } void reset() override { <%- fields_for_xlen.each do |field| -%> diff --git a/backends/cpp_hart_gen/templates/hart.hxx.erb b/backends/cpp_hart_gen/templates/hart.hxx.erb index b1afd29f49..72bf77f563 100644 --- a/backends/cpp_hart_gen/templates/hart.hxx.erb +++ b/backends/cpp_hart_gen/templates/hart.hxx.erb @@ -225,7 +225,81 @@ namespace udb { return m_csr_addr_map.count(csr_addr) == 1; } + <%= name_of(:struct, "Csr", cfg_arch) %> direct_csr_lookup(const Bits<12>& csr_addr) { + <%= name_of(:struct, "Csr", cfg_arch) %> csr_handle; + + auto csr = m_csr_addr_map.find(csr_addr); + if (csr == m_csr_addr_map.end()) { + csr_handle.valid = false; + return csr_handle; + } else { + csr_handle.valid = true; + csr_handle.name = csr->name(); + csr_handle.addr_type = CsrAddressType::Direct; + csr_handle.address = csr_addr; + csr_handle.window_slot = 0; + csr_handle.mode = csr->mode(); + csr_handle.writable = csr->writable(); + return csr_handle; + } + } + <%= name_of(:struct, "Csr", cfg_arch) %> indirect_csr_lookup(const Bits<64>& csr_indirect_addr, const Bits<4>& window_slot) { + <%= name_of(:struct, "Csr", cfg_arch) %> csr_handle; + + udb_assert((window_slot > 0) && (window_slot <= 6), "Indirect slots must be between 1-6, inclusive"); + + auto csr = m_csr_indirect_addr_map.find(std::make_pair(csr_indirect_addr, window_slot)); + if (csr == m_csr_indirect_addr_map.end()) { + csr_handle.valid = false; + return csr_handle; + } else { + csr_handle.valid = true; + csr_handle.name = csr->name(); + csr_handle.addr_type = CsrAddressType::Indirect; + csr_handle.address = csr_indirect_addr; + csr_handle.window_slot = window_slot; + csr_handle.mode = csr->mode(); + csr_handle.writable = csr->writable(); + return csr_handle; + } + } + + PossiblyUnknownBits<64> csr_hw_read(const <%= name_of(:struct, "Csr", cfg_arch) %>& csr_handle) { + if (csr_handle.addr_type == CsrAddressType::Direct) { + auto csr = m_csr_addr_map.find(csr_handle.address); + udb_assert(csr != m_csr_addr_map.end(), "CSR not found"); + return csr.hw_read(xlen()); + } else { + auto csr = m_csr_indirect_addr_map.find(std::make_pair(csr_handle.address, csr_handle.indirect_slot)); + udb_assert(csr != m_csr_indirect_addr_map.end(), "CSR not found"); + return csr.hw_read(xlen()); + } + } + + PossiblyUnknownBits<64> csr_sw_read(const <%= name_of(:struct, "Csr", cfg_arch) %>& csr_handle) { + if (csr_handle.addr_type == CsrAddressType::Direct) { + auto csr = m_csr_addr_map.find(csr_handle.address); + udb_assert(csr != m_csr_addr_map.end(), "CSR not found"); + return csr.sw_read(xlen()); + } else { + auto csr = m_csr_indirect_addr_map.find(std::make_pair(csr_handle.address, csr_handle.indirect_slot)); + udb_assert(csr != m_csr_indirect_addr_map.end(), "CSR not found"); + return csr.sw_read(xlen()); + } + } + + void csr_sw_write(const <%= name_of(:struct, "Csr", cfg_arch) %>& csr_handle, const Bits<<%= cfg_arch.mxlen %>>& value) { + if (csr_handle.addr_type == CsrAddressType::Direct) { + auto csr = m_csr_addr_map.find(csr_handle.address); + udb_assert(csr != m_csr_addr_map.end(), "CSR not found"); + return csr.sw_write(value, xlen()); + } else { + auto csr = m_csr_indirect_addr_map.find(std::make_pair(csr_handle.address, csr_handle.indirect_slot)); + udb_assert(csr != m_csr_indirect_addr_map.end(), "CSR not found"); + return csr.sw_write(value, xlen()); + } + } void set_pc(uint64_t new_pc) override { m_pc = new_pc; @@ -379,6 +453,7 @@ namespace udb { <%= name_of(:params, cfg_arch) %> m_params; <%= name_of(:csr_container, cfg_arch) %> m_csrs; std::unordered_map, CsrBase*> m_csr_addr_map; + std::unordered_map, Bits<4>>, CsrBase*> m_csr_indirect_addr_map; std::map m_csr_name_map; std::array m_run_one_inst_storage; diff --git a/backends/cpp_hart_gen/templates/hart_impl.hxx.erb b/backends/cpp_hart_gen/templates/hart_impl.hxx.erb index 72207eb8dc..33230b50a7 100644 --- a/backends/cpp_hart_gen/templates/hart_impl.hxx.erb +++ b/backends/cpp_hart_gen/templates/hart_impl.hxx.erb @@ -43,6 +43,9 @@ namespace udb { <%- unless csr.address.nil? -%> m_csr_addr_map[<%= csr.address %>] = &m_csrs.<%= csr.name %>; <%- end -%> + <%- unless csr.indirect_address.nil? -%> + m_csr_indirect_addr_map[std::make_pair(<%= csr.indirect_address %>, <%= csr.indirect_slot %>)] = &m_csrs.<%= csr.name %>; + <%_ end -%> m_csr_name_map["<%= csr.name %>"] = &m_csrs.<%= csr.name %>; <%- end -%> } diff --git a/lib/arch_obj_models/csr.rb b/lib/arch_obj_models/csr.rb index fe0508b90d..bd088c4ed4 100644 --- a/lib/arch_obj_models/csr.rb +++ b/lib/arch_obj_models/csr.rb @@ -22,6 +22,21 @@ def address @data["address"] end + # @return [Boolean] Whether or not the CSR can be accessed by indirect address + def indirect? + @data.key?("indirect_address") + end + + # @return [Integer] The indirect address + def indirect_address + @data["indirect_address"] + end + + # @return [Integer] The indirect window slot + def indirect_slot + @data["indirect_slot"] + end + # @return [String] Least-privileged mode that can access this CSR. One of ['m', 's', 'u', 'vs', 'vu'] def priv_mode @data["priv_mode"] @@ -37,6 +52,10 @@ def virtual_address @data["virtual_address"] end + def writable + @data["writeable"] + end + # @return [Integer] 32 or 64, the XLEN this CSR is exclusively defined in # @return [nil] if this CSR is defined in all bases def base = @data["base"] diff --git a/lib/cfg_arch.rb b/lib/cfg_arch.rb index f0385ff090..91c7b703b2 100644 --- a/lib/cfg_arch.rb +++ b/lib/cfg_arch.rb @@ -219,10 +219,10 @@ def type_check(show_progress: true, io: $stdout) io.puts "Type checking IDL code for #{@config.name}..." if show_progress progressbar = if show_progress - ProgressBar.create(title: "Instructions", total: instructions.size) + ProgressBar.create(title: "Instructions", total: possible_instructions.size) end - instructions.each do |inst| + possible_instructions.each do |inst| progressbar.increment if show_progress if @mxlen == 32 inst.type_checked_operation_ast(32) if inst.rv32? @@ -234,10 +234,10 @@ def type_check(show_progress: true, io: $stdout) progressbar = if show_progress - ProgressBar.create(title: "CSRs", total: csrs.size) + ProgressBar.create(title: "CSRs", total: possible_csrs.size) end - csrs.each do |csr| + possible_csrs.each do |csr| progressbar.increment if show_progress if csr.has_custom_sw_read? if (possible_xlens.include?(32) && csr.defined_in_base32?) @@ -269,11 +269,12 @@ def type_check(show_progress: true, io: $stdout) end end + func_list = reachable_functions progressbar = if show_progress - ProgressBar.create(title: "Functions", total: functions.size) + ProgressBar.create(title: "Functions", total: func_list.size) end - functions.each do |func| + func_list.each do |func| progressbar.increment if show_progress func.type_check(@symtab) end diff --git a/lib/idl/ast.rb b/lib/idl/ast.rb index 2b1e1a83d6..2d513835b1 100644 --- a/lib/idl/ast.rb +++ b/lib/idl/ast.rb @@ -2377,7 +2377,9 @@ def type_check(symtab, add_sym = true) value_else(value_result) do # if this is a fully configured ConfiguredArchitecture, this is an error because all constants are supposed to be known if symtab.cfg_arch.fully_configured? - type_error "Array size (#{ary_size.text_value}) must be known at compile time" + unless ary_size.type(symtab).template_var? + type_error "Array size (#{ary_size.text_value}) must be known at compile time" + end else # otherwise, it's ok that we don't know the value yet, as long as the value is a const type_error "Array size (#{ary_size.text_value}) must be a constant" unless ary_size.type(symtab).const? @@ -4367,7 +4369,11 @@ def type_check(symtab) end end value_else(value_result) do - type_error "Bit width must be known at compile time" if symtab.cfg_arch.fully_configured? + unless bits_expression.type(symtab).template_var? + if symtab.cfg_arch.fully_configured? + type_error "Bit width (#{bits_expression.text_value}) must be known at compile time" + end + end end end unless ["Bits", "String", "XReg", "Boolean", "U32", "U64"].include?(@type_name) @@ -4906,6 +4912,16 @@ def value(symtab) value_error "maybe_cache_translation is not compile-time-knowable" elsif name == "invalidate_translations" value_error "invalidate_translations is not compile-time-knowable" + elsif name == "direct_csr_lookup" + value_error "direct_csr_lookup is not compile-time-knowable" + elsif name == "indirect_csr_lookup" + value_error "indirect_csr_lookup is not compile-time-knowable" + elsif name == "csr_hw_read" + value_error "csr_hw_read is not compile-time-knowable" + elsif name == "csr_sw_read" + value_error "csr_sw_read is not compile-time-knowable" + elsif name == "csr_sw_write" + value_error "csr_sw_write is not compile-time-knowable" else internal_error "Unimplemented generated: '#{name}'" end @@ -5361,7 +5377,7 @@ def type_check(symtab) symtab = symtab.deep_clone symtab.push(self) template_names.each_with_index do |tname, index| - symtab.add(tname, Var.new(tname, template_types(symtab)[index])) + symtab.add(tname, Var.new(tname, template_types(symtab)[index], template_index: index)) end type_check_return(symtab) @@ -5408,6 +5424,7 @@ def template_types(symtab) ttype = a.type(symtab) ttype = ttype.ref_type if ttype.kind == :enum ttypes << ttype.clone.make_const + ttypes.last.qualify(:template_var) end ttypes end @@ -6042,18 +6059,16 @@ def freeze_tree(symtab) def type_check(symtab) @csr.type_check(symtab) - type_error "CSR[#{csr_name(symtab)}] has no field named #{@field_name}" if field_def(symtab).nil? - type_error "CSR[#{csr_name(symtab)}].#{@field_name} is not defined in RV32" if symtab.cfg_arch.mxlen == 32 && !field_def(symtab).defined_in_base32? - type_error "CSR[#{csr_name(symtab)}].#{@field_name} is not defined in RV64" if symtab.cfg_arch.mxlen == 64 && !field_def(symtab).defined_in_base64? + type_error "CSR[#{csr_name}] has no field named #{@field_name}" if field_def(symtab).nil? + type_error "CSR[#{csr_name}].#{@field_name} is not defined in RV32" if symtab.cfg_arch.mxlen == 32 && !field_def(symtab).defined_in_base32? + type_error "CSR[#{csr_name}].#{@field_name} is not defined in RV64" if symtab.cfg_arch.mxlen == 64 && !field_def(symtab).defined_in_base64? end def csr_def(symtab) @csr_obj end - def csr_name(symtab) - csr_def(symtab).name - end + def csr_name = @csr.csr_name def field_def(symtab) @csr_obj.fields.find { |f| f.name == @field_name } @@ -6095,7 +6110,7 @@ def calc_type(symtab) # @!macro value def value(symtab) if @value.nil? - value_error "'#{csr_name(symtab)}.#{field_name(symtab)}' is not RO" + value_error "'#{csr_name}.#{field_name(symtab)}' is not RO" else @value end @@ -6107,7 +6122,7 @@ def calc_value(symtab) symtab.cfg_arch.possible_xlens.each do |effective_xlen| unless field_def(symtab).type(effective_xlen) == "RO" - value_error "'#{csr_name(symtab)}.#{field_name(symtab)}' is not RO" + value_error "'#{csr_name}.#{field_name(symtab)}' is not RO" end end @@ -6118,7 +6133,7 @@ def calc_value(symtab) class CsrReadExpressionSyntaxNode < Treetop::Runtime::SyntaxNode def to_ast - CsrReadExpressionAst.new(input, interval, idx.text_value) + CsrReadExpressionAst.new(input, interval, csr_name.text_value) end end @@ -6131,13 +6146,12 @@ def to_ast class CsrReadExpressionAst < AstNode include Rvalue - attr_reader :idx_text - attr_reader :idx_expr + attr_reader :csr_name - def initialize(input, interval, idx) + def initialize(input, interval, csr_name) super(input, interval, []) - @idx_text = idx + @csr_name = csr_name end def freeze_tree(symtab) @@ -6145,101 +6159,45 @@ def freeze_tree(symtab) @cfg_arch = symtab.cfg_arch # remember cfg_arch, used by gen_adoc pass - if symtab.cfg_arch.csr(@idx_text).nil? - parser = symtab.cfg_arch.idl_compiler.parser - expr = parser.parse(@idx_text, root: :expression) - - type_error "#{@idx_text} is not a CSR; it must be an expression" if expr.nil? + type_error "CSR '#{@csr_name}' is not defined" if symtab.cfg_arch.csr(@csr_name).nil? + @csr_obj = symtab.cfg_arch.csr(@csr_name) - @idx_expr = expr.to_ast - @children << @idx_expr - else - @csr_obj = symtab.cfg_arch.csr(@idx_text) - end + @type = CsrType.new(@csr_obj, symtab.cfg_arch) @children.each { |child| child.freeze_tree(symtab) } freeze end # @!macro type - def type(symtab) - cfg_arch = symtab.cfg_arch - - cd = csr_def(symtab) - if cd.nil? - # we don't know anything about this index, so we can only - # treat this as a generic - CsrType.new(:unknown, cfg_arch) - else - CsrType.new(cd, cfg_arch) - end - end + def type(symtab) = @type # @!macro type_check def type_check(symtab) - cfg_arch = symtab.cfg_arch - - if !@csr_obj.nil? - # this is a known csr name - # nothing else to check - - else - # this is an expression - @idx_expr.type_check(symtab) - type_error "Csr index must be integral" unless @idx_expr.type(symtab).integral? - - value_try do - idx_value = @idx_expr.value(symtab) - csr_index = cfg_arch.csrs.index { |csr| csr.address == idx_value } - type_error "No csr number '#{idx_value}' was found" if csr_index.nil? - :ok - end - # OK, index doesn't have to be known - end + type_error "CSR '#{@csr_name}' is not defined" if symtab.cfg_arch.csr(@csr_name).nil? end def csr_def(symtab) - cfg_arch = symtab.cfg_arch - if !@csr_obj.nil? - # this is a known csr name - @csr_obj - else - # this is an expression - value_try do - idx_value = @idx_expr.value(symtab) - return cfg_arch.csrs.find { |csr| csr.address == idx_value } - end - # || we don't know at compile time which CSR this is... - nil - end + @csr_obj end def csr_known?(symtab) !csr_def(symtab).nil? end - def csr_name(symtab) - internal_error "No CSR" unless csr_known?(symtab) - - csr_def(symtab).name - end - # @!macro value def value(symtab) - cd = csr_def(symtab) - value_error "CSR number not knowable" if cd.nil? if symtab.cfg_arch.fully_configured? - value_error "CSR is not implemented" unless symtab.cfg_arch.transitive_implemented_csrs.any? { |icsr| icsr.name == cd.name } + value_error "CSR is not implemented" unless symtab.cfg_arch.transitive_implemented_csrs.any? { |icsr| icsr.name == @csr_obj.name } else - value_error "CSR is not defined" unless symtab.cfg_arch.csrs.any? { |icsr| icsr.name == cd.name } + value_error "CSR is not defined" unless symtab.cfg_arch.csrs.any? { |icsr| icsr.name == @csr_obj.name } end - cd.fields.each { |f| value_error "#{csr_name(symtab)}.#{f.name} not RO" unless f.type == "RO" } + @csr_obj.fields.each { |f| value_error "#{csr_name}.#{f.name} not RO" unless f.type == "RO" } csr_def(symtab).fields.reduce(0) { |val, f| val | (f.value << f.location.begin) } end # @!macro to_idl - def to_idl = "CSR[#{@idx.to_idl}]" + def to_idl = "CSR[#{@csr_name}]" end class CsrSoftwareWriteSyntaxNode < Treetop::Runtime::SyntaxNode @@ -6274,9 +6232,7 @@ def csr_known?(symtab) csr.csr_known?(symtab) end - def csr_name(symtab) - csr.csr_name(symtab) - end + def csr_name = csr.csr_name # @!macro value def value(_symtab) @@ -6342,7 +6298,7 @@ def type(symtab) case function_name when "sw_read" if csr_known?(symtab) - l = cfg_arch.csr(csr.csr_name(symtab)).length + l = cfg_arch.csr(csr.csr_name).length Type.new(:bits, width: (l.nil? ? :unknown : l)) else Type.new(:bits, width: symtab.mxlen.nil? ? :unknown : symtab.mxlen) @@ -6360,9 +6316,7 @@ def csr_known?(symtab) csr.csr_known?(symtab) end - def csr_name(symtab) - csr.csr_name(symtab) - end + def csr_name = csr.csr_name def csr_def(symtab) csr.csr_def(symtab) @@ -6374,7 +6328,7 @@ def value(symtab) when "sw_read" value_error "CSR not knowable" unless csr_known?(symtab) cd = csr_def(symtab) - cd.fields.each { |f| value_error "#{csr_name(symtab)}.#{f.name} not RO" unless f.type == "RO" } + cd.fields.each { |f| value_error "#{csr_name}.#{f.name} not RO" unless f.type == "RO" } value_error "TODO: CSRs with sw_read function" when "address" diff --git a/lib/idl/idl.treetop b/lib/idl/idl.treetop index 0107b1ea48..3dd01c736d 100644 --- a/lib/idl/idl.treetop +++ b/lib/idl/idl.treetop @@ -275,7 +275,7 @@ grammar Idl rule csr_register_access_expression # CSR register access - 'CSR' space* '[' space* idx:(expression / csr_name) space* ']' + 'CSR' space* '[' space* csr_name space* ']' end rule field_access_eligible_expression @@ -652,7 +652,7 @@ grammar Idl end rule var_write - 'CSR' space* '[' space* idx:(csr_name / int) space* ']' + 'CSR' space* '[' space* csr_name space* ']' / id end diff --git a/lib/idl/passes/gen_adoc.rb b/lib/idl/passes/gen_adoc.rb index 5dde948cd6..6b6fa43f00 100644 --- a/lib/idl/passes/gen_adoc.rb +++ b/lib/idl/passes/gen_adoc.rb @@ -299,24 +299,8 @@ def gen_adoc(indent = 0, indent_spaces: 2) class CsrReadExpressionAst def gen_adoc(indent = 0, indent_spaces: 2) - idx = - if @idx_expr.nil? - @idx_text - else - @idx_expr.gen_adoc(0) - end - - csr_text = "CSR[#{idx}]" - if idx_text =~ /[0-9]+/ - # we don't have the symtab to map this to a csr name - "#{' '*indent}#{csr_text}" - else - if @cfg_arch.csr(csr_text).nil? - "#{' '*indent}#{csr_text}" - else - "#{' '*indent}%%LINK%csr;#{idx};#{csr_text}%%" - end - end + csr_text = "CSR[#{csr_name}]" + "#{' '*indent}%%LINK%csr;#{csr_name};#{csr_text}%%" end end diff --git a/lib/idl/symbol_table.rb b/lib/idl/symbol_table.rb index 97d9296ced..6cf6714452 100644 --- a/lib/idl/symbol_table.rb +++ b/lib/idl/symbol_table.rb @@ -14,6 +14,7 @@ def initialize(name, type, value = nil, decode_var: false, template_index: nil, raise ArgumentError, "Expecting a Type, got #{type.class.name}" unless type.is_a?(Type) @type = type + @type.qualify(:template_var) @type.freeze @value = value raise "unexpected" unless decode_var.is_a?(TrueClass) || decode_var.is_a?(FalseClass) diff --git a/lib/idl/type.rb b/lib/idl/type.rb index 2bea234eda..a993d1541b 100644 --- a/lib/idl/type.rb +++ b/lib/idl/type.rb @@ -22,7 +22,8 @@ class Type QUALIFIERS = [ :const, :signed, - :global + :global, + :template_var ].freeze # true for any type that can generally be treated as a scalar integer @@ -394,6 +395,10 @@ def global? @qualifiers.include?(:global) end + def template_var? + @qualifiers.include?(:template_var) + end + def make_signed @qualifiers.append(:signed).uniq! self diff --git a/schemas/csr_schema.json b/schemas/csr_schema.json index d7bc918933..12874c67b0 100644 --- a/schemas/csr_schema.json +++ b/schemas/csr_schema.json @@ -78,14 +78,22 @@ "alias": { "oneOf": [ { - "type": "string", - "pattern": "^[a-z][a-z0-9]+\\.[A-Z0-9]+(\\[[0-9]+(:[0-9]+)?\\])?$" + "$ref": "schema_defs.json#/$defs/csr_field" + }, + { + "$ref": "schema_defs.json#/$defs/csr_field_bits" }, { "type": "array", "items": { - "type": "string", - "pattern": "^[a-z][a-z0-9]+\\.[A-Z0-9]+(\\[[0-9]+(:[0-9]+)?\\])?$" + "oneOf": [ + { + "$ref": "schema_defs.json#/$defs/csr_field" + }, + { + "$ref": "schema_defs.json#/$defs/csr_field_bits" + } + ] } } ], @@ -199,9 +207,7 @@ "description": "Object type" }, "name": { - "type": "string", - "pattern": "^[a-z][a-z0-9_.]+$", - "description": "CSR name" + "$ref": "schema_defs.json#/$defs/csr_name" }, "base": { "type": "integer", @@ -231,10 +237,15 @@ "type": "integer", "description": "Indirect address of the CSR, as given to the indirect CSRs of the `Smcsrind`/`Sscdrind` extensions" }, - "indirect": { + "indirect_slot": { + "type": "integer", + "minimum": 1, + "maximum": 6, + "description": "Indirect window slot of the CSR, corresponding to its appearance in *ireg" + }, + "writeable": { "type": "boolean", - "default": false, - "description": "Whether or not the CSR is accessible via an indirect address" + "description": "Whether or not the CSR can be written by software (i.e., is read-write)" }, "virtual_address": true, "$comment": "Conditionally required; see below", @@ -295,20 +306,16 @@ } }, { - "oneOf": [ - { - "properties": { - "indirect": { "const": false } - }, - "required": ["address"] - }, - { + "if": { + "not": { "properties": { - "indirect": { "const": true } - }, - "required": ["indirect_address"] + "indirect_address": { "const": null } + } } - ] + }, + "then": { + "required": ["indirect_slot"] + } } ] } diff --git a/schemas/schema_defs.json b/schemas/schema_defs.json index 47e70e66cb..8560534e62 100644 --- a/schemas/schema_defs.json +++ b/schemas/schema_defs.json @@ -17,6 +17,21 @@ "type": "string", "pattern": "^[0-9]+(\\.[0-9]+(\\.[0-9]+(-pre)?)?)?$" }, + "csr_name": { + "type": "string", + "pattern": "^[a-z][a-z0-9_.]+$", + "description": "CSR name" + }, + "csr_field": { + "type": "string", + "pattern": "^[a-z][a-z0-9_.]+\\.[A-Z0-9]+$", + "description": "CSR field" + }, + "csr_field_bits": { + "type": "string", + "pattern": "^[a-z][a-z0-9_.]+\\.[A-Z0-9]+\\[[0-9]+(:[0-9]+)?\\]$", + "description": "CSR field" + }, "field_location": { "oneOf": [ { "type": "number", "description": "Location of a single bit" },