From b786813e21fcd9f314398baebcd0cbeead5bbf4a Mon Sep 17 00:00:00 2001 From: Derek Hower Date: Thu, 15 Aug 2024 10:08:56 -0700 Subject: [PATCH] Multiple enhancements: * fix *counteren CSR defintiions * Fix nested table separator bug * Improve CSR HTML display * Add paramter list to Extension HTML display * Improve IDL highlighting for Antora --- arch/csr/H/hcounteren.layout | 137 ++- arch/csr/H/hcounteren.yaml | 1007 ++++++++++++----- arch/csr/I/mcounteren.yaml | 158 +-- arch/csr/I/pmpcfg0.yaml | 16 +- arch/csr/I/pmpcfg1.yaml | 8 +- arch/csr/I/pmpcfg10.yaml | 16 +- arch/csr/I/pmpcfg11.yaml | 8 +- arch/csr/I/pmpcfg12.yaml | 16 +- arch/csr/I/pmpcfg13.yaml | 8 +- arch/csr/I/pmpcfg14.yaml | 16 +- arch/csr/I/pmpcfg15.yaml | 8 +- arch/csr/I/pmpcfg2.yaml | 16 +- arch/csr/I/pmpcfg3.yaml | 8 +- arch/csr/I/pmpcfg4.yaml | 16 +- arch/csr/I/pmpcfg5.yaml | 8 +- arch/csr/I/pmpcfg6.yaml | 16 +- arch/csr/I/pmpcfg7.yaml | 8 +- arch/csr/I/pmpcfg8.yaml | 16 +- arch/csr/I/pmpcfg9.yaml | 8 +- arch/csr/I/pmpcfgN.layout | 2 +- arch/csr/S/scounteren.layout | 106 +- arch/csr/S/scounteren.yaml | 862 +++++++------- arch/csr/Zicntr/mcountinhibit.layout | 2 +- arch/csr/Zicntr/mcountinhibit.yaml | 58 +- arch/csr/hstatus.yaml | 3 +- arch/csr/mcause.yaml | 11 +- arch/csr/medeleg.yaml | 60 +- arch/csr/menvcfg.yaml | 4 +- arch/csr/mtval.yaml | 1 + arch/csr/satp.yaml | 2 +- arch/csr/scause.yaml | 11 +- arch/csr/senvcfg.yaml | 8 +- arch/csr/sip.yaml | 8 +- arch/csr/stval.yaml | 1 + arch/csr/stvec.yaml | 3 +- arch/csr/time.yaml | 39 +- arch/csr/vscause.yaml | 12 +- arch/csr/vstval.yaml | 1 + arch/csr/vstvec.yaml | 3 +- arch/ext/H.yaml | 16 + arch/ext/I.yaml | 26 +- arch/ext/S.yaml | 18 +- arch/isa/builtin_functions.idl | 7 + backends/cfg_html_doc/adoc_gen.rake | 3 +- backends/cfg_html_doc/html_gen.rake | 7 + .../cfg_html_doc/templates/config.adoc.erb | 2 +- backends/cfg_html_doc/templates/csr.adoc.erb | 58 +- backends/cfg_html_doc/templates/ext.adoc.erb | 21 +- backends/cfg_html_doc/templates/func.adoc.erb | 4 +- backends/ext_pdf_doc/idl_lexer.rb | 6 +- .../ext_pdf_doc/templates/ext_pdf.adoc.erb | 195 +++- cfgs/generic_rv64/params.yaml | 86 +- lib/arch_def.rb | 356 +++++- lib/idl/ast.rb | 56 +- lib/idl/idl.treetop | 2 +- lib/idl/passes/gen_adoc.rb | 6 +- .../passes/reachable_functions_unevaluated.rb | 50 + lib/idl/symbol_table.rb | 15 +- 58 files changed, 2475 insertions(+), 1150 deletions(-) create mode 100644 lib/idl/passes/reachable_functions_unevaluated.rb diff --git a/arch/csr/H/hcounteren.layout b/arch/csr/H/hcounteren.layout index 931f0c08e..d72fcad71 100644 --- a/arch/csr/H/hcounteren.layout +++ b/arch/csr/H/hcounteren.layout @@ -21,19 +21,73 @@ hcounteren: When `mcounteren.CY` and `hcounteren.CY` are set, the `cycle` CSR (an alias of `mcycle`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.CY` is clear. + When `hcounteren.CY` is clear and `mcounteren.CY` is set, then any access to `cycle` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",cols="1,1,1,4,4"] !=== - ! `mcounteren.CY` ! `hcounteren.CY` behavior + .2+h! [.rotate]#`hcounteren.CY`# .2+h! [.rotate]#`mcounteren.CY`# .2+h! [.rotate]#`scounteren.CY`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed + !=== + definedBy: Zicntr + type(): | + if (HCOUNTENABLE_EN[0]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[0]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + TM: + location: 1 + description: | + When all of `scounteren.TM`, `mcounteren.TM`, and `hcounteren.TM` are set, + the `time` CSR (an alias of `mtime` memory-mapped CSR) is accessible to VU-mode. + + When `mcounteren.TM` and `hcounteren.TM` are set, + the `time` CSR (an alias of `mtime`) is accessible to VS-mode. + + When `hcounteren.TM` is clear and `mcounteren.TM` is set, then any access to `time` in + VU-mode or VS-mode causes a VirtualInstruction execption. + + Summary: - ! 0 ! read-only 0 - ! 1 ! writeable + [separator="!",%autowidth] + !=== + .2+h! [.rotate]#`hcounteren.TM`# .2+h! [.rotate]#`mcounteren.TM`# .2+h! [.rotate]#`scounteren.TM`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== definedBy: Zicntr - type: RW-H - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[1]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[1]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } IR: location: 2 description: | @@ -43,20 +97,34 @@ hcounteren: When `mcounteren.IR` and `hcounteren.IR` are set, the `instret` CSR (an alias of `minstret`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.IR` is clear. + When `hcounteren.IR` is clear and `mcounteren.IR` is set, then any access to `instret` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.IR` ! `hcounteren.IR` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.IR`# .2+h! [.rotate]#`mcounteren.IR`# .2+h! [.rotate]#`scounteren.IR`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - - type: RW-H - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[2]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[2]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } <%- (3..31).each do |hpm_num| -%> HPM<%= hpm_num %>: location: <%= hpm_num %> @@ -67,25 +135,32 @@ hcounteren: When `mcounteren.HPM<%= hpm_num %>` and `hcounteren.HPM<%= hpm_num %>` are set, the `hpmcounter<%= hpm_num %>` CSR (an alias of `mhpmconuter<%= hpm_num %>`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM<%= hpm_num %>` is clear. + When `hcounteren.HPM<%= hpm_num %>` is clear and `mcounteren.HPM<%= hpm_num %>` is set, then any access to `hpmcounter<%= hpm_num %>` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM<%= hpm_num %>` ! `hcounteren.HPM<%= hpm_num %>` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM<%= hpm_num %>`# .2+h! [.rotate]#`mcounteren.HPM<%= hpm_num %>`# .2+h! [.rotate]#`scounteren.HPM<%= hpm_num %>`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[<%= hpm_num %>]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[<%= hpm_num %>]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } <%- end -%> - sw_read(): | - if (!implemented?(ExtensionName::Zicntr) && !implemented?(ExtensionName::Zihpm)) { - # this CSR isn't supposed to exist when Zicntr and Zihpm are not implemented - raise(ExceptionCode::IllegalInstruction, $encoding); - } - - # any bit of mcounteren that is zero forces that same bit of hcounteren to 0 - return $bits(CSR[hcounteren]) & $bits(CSR[mcounteren]); \ No newline at end of file diff --git a/arch/csr/H/hcounteren.yaml b/arch/csr/H/hcounteren.yaml index c3da8d737..0e045f0be 100644 --- a/arch/csr/H/hcounteren.yaml +++ b/arch/csr/H/hcounteren.yaml @@ -12,7 +12,7 @@ hcounteren: Together with `scounteren`, delegates control of the hardware performance-monitoring counters to VS/VU-mode - See `cycle` for a table describing how exceptions occur. + See `cycle` for a table of how exceptions occur across all modes. definedBy: H fields: CY: @@ -24,19 +24,73 @@ hcounteren: When `mcounteren.CY` and `hcounteren.CY` are set, the `cycle` CSR (an alias of `mcycle`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.CY` is clear. + When `hcounteren.CY` is clear and `mcounteren.CY` is set, then any access to `cycle` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",cols="1,1,1,4,4"] !=== - ! `mcounteren.CY` ! `hcounteren.CY` behavior + .2+h! [.rotate]#`hcounteren.CY`# .2+h! [.rotate]#`mcounteren.CY`# .2+h! [.rotate]#`scounteren.CY`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed + !=== + definedBy: Zicntr + type(): | + if (HCOUNTENABLE_EN[0]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[0]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + TM: + location: 1 + description: | + When all of `scounteren.TM`, `mcounteren.TM`, and `hcounteren.TM` are set, + the `time` CSR (an alias of `mtime` memory-mapped CSR) is accessible to VU-mode. + + When `mcounteren.TM` and `hcounteren.TM` are set, + the `time` CSR (an alias of `mtime`) is accessible to VS-mode. + + When `hcounteren.TM` is clear and `mcounteren.TM` is set, then any access to `time` in + VU-mode or VS-mode causes a VirtualInstruction execption. - ! 0 ! read-only 0 - ! 1 ! writeable + Summary: + + [separator="!",%autowidth] + !=== + .2+h! [.rotate]#`hcounteren.TM`# .2+h! [.rotate]#`mcounteren.TM`# .2+h! [.rotate]#`scounteren.TM`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== definedBy: Zicntr - type: RW-H - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[1]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[1]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } IR: location: 2 description: | @@ -46,20 +100,34 @@ hcounteren: When `mcounteren.IR` and `hcounteren.IR` are set, the `instret` CSR (an alias of `minstret`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.IR` is clear. + When `hcounteren.IR` is clear and `mcounteren.IR` is set, then any access to `instret` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.IR` ! `hcounteren.IR` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.IR`# .2+h! [.rotate]#`mcounteren.IR`# .2+h! [.rotate]#`scounteren.IR`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - - type: RW-H - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[2]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[2]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM3: location: 3 description: | @@ -69,19 +137,34 @@ hcounteren: When `mcounteren.HPM3` and `hcounteren.HPM3` are set, the `hpmcounter3` CSR (an alias of `mhpmconuter3`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM3` is clear. + When `hcounteren.HPM3` is clear and `mcounteren.HPM3` is set, then any access to `hpmcounter3` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM3` ! `hcounteren.HPM3` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM3`# .2+h! [.rotate]#`mcounteren.HPM3`# .2+h! [.rotate]#`scounteren.HPM3`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[3]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[3]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM4: location: 4 description: | @@ -91,19 +174,34 @@ hcounteren: When `mcounteren.HPM4` and `hcounteren.HPM4` are set, the `hpmcounter4` CSR (an alias of `mhpmconuter4`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM4` is clear. + When `hcounteren.HPM4` is clear and `mcounteren.HPM4` is set, then any access to `hpmcounter4` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM4` ! `hcounteren.HPM4` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM4`# .2+h! [.rotate]#`mcounteren.HPM4`# .2+h! [.rotate]#`scounteren.HPM4`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[4]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[4]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM5: location: 5 description: | @@ -113,19 +211,34 @@ hcounteren: When `mcounteren.HPM5` and `hcounteren.HPM5` are set, the `hpmcounter5` CSR (an alias of `mhpmconuter5`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM5` is clear. + When `hcounteren.HPM5` is clear and `mcounteren.HPM5` is set, then any access to `hpmcounter5` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM5` ! `hcounteren.HPM5` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM5`# .2+h! [.rotate]#`mcounteren.HPM5`# .2+h! [.rotate]#`scounteren.HPM5`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[5]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[5]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM6: location: 6 description: | @@ -135,19 +248,34 @@ hcounteren: When `mcounteren.HPM6` and `hcounteren.HPM6` are set, the `hpmcounter6` CSR (an alias of `mhpmconuter6`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM6` is clear. + When `hcounteren.HPM6` is clear and `mcounteren.HPM6` is set, then any access to `hpmcounter6` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM6` ! `hcounteren.HPM6` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM6`# .2+h! [.rotate]#`mcounteren.HPM6`# .2+h! [.rotate]#`scounteren.HPM6`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[6]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[6]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM7: location: 7 description: | @@ -157,19 +285,34 @@ hcounteren: When `mcounteren.HPM7` and `hcounteren.HPM7` are set, the `hpmcounter7` CSR (an alias of `mhpmconuter7`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM7` is clear. + When `hcounteren.HPM7` is clear and `mcounteren.HPM7` is set, then any access to `hpmcounter7` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM7` ! `hcounteren.HPM7` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM7`# .2+h! [.rotate]#`mcounteren.HPM7`# .2+h! [.rotate]#`scounteren.HPM7`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[7]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[7]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM8: location: 8 description: | @@ -179,19 +322,34 @@ hcounteren: When `mcounteren.HPM8` and `hcounteren.HPM8` are set, the `hpmcounter8` CSR (an alias of `mhpmconuter8`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM8` is clear. + When `hcounteren.HPM8` is clear and `mcounteren.HPM8` is set, then any access to `hpmcounter8` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM8` ! `hcounteren.HPM8` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM8`# .2+h! [.rotate]#`mcounteren.HPM8`# .2+h! [.rotate]#`scounteren.HPM8`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[8]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[8]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM9: location: 9 description: | @@ -201,19 +359,34 @@ hcounteren: When `mcounteren.HPM9` and `hcounteren.HPM9` are set, the `hpmcounter9` CSR (an alias of `mhpmconuter9`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM9` is clear. + When `hcounteren.HPM9` is clear and `mcounteren.HPM9` is set, then any access to `hpmcounter9` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM9` ! `hcounteren.HPM9` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM9`# .2+h! [.rotate]#`mcounteren.HPM9`# .2+h! [.rotate]#`scounteren.HPM9`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[9]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[9]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM10: location: 10 description: | @@ -223,19 +396,34 @@ hcounteren: When `mcounteren.HPM10` and `hcounteren.HPM10` are set, the `hpmcounter10` CSR (an alias of `mhpmconuter10`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM10` is clear. + When `hcounteren.HPM10` is clear and `mcounteren.HPM10` is set, then any access to `hpmcounter10` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM10` ! `hcounteren.HPM10` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM10`# .2+h! [.rotate]#`mcounteren.HPM10`# .2+h! [.rotate]#`scounteren.HPM10`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[10]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[10]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM11: location: 11 description: | @@ -245,19 +433,34 @@ hcounteren: When `mcounteren.HPM11` and `hcounteren.HPM11` are set, the `hpmcounter11` CSR (an alias of `mhpmconuter11`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM11` is clear. + When `hcounteren.HPM11` is clear and `mcounteren.HPM11` is set, then any access to `hpmcounter11` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM11` ! `hcounteren.HPM11` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM11`# .2+h! [.rotate]#`mcounteren.HPM11`# .2+h! [.rotate]#`scounteren.HPM11`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[11]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[11]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM12: location: 12 description: | @@ -267,19 +470,34 @@ hcounteren: When `mcounteren.HPM12` and `hcounteren.HPM12` are set, the `hpmcounter12` CSR (an alias of `mhpmconuter12`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM12` is clear. + When `hcounteren.HPM12` is clear and `mcounteren.HPM12` is set, then any access to `hpmcounter12` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM12` ! `hcounteren.HPM12` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM12`# .2+h! [.rotate]#`mcounteren.HPM12`# .2+h! [.rotate]#`scounteren.HPM12`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[12]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[12]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM13: location: 13 description: | @@ -289,19 +507,34 @@ hcounteren: When `mcounteren.HPM13` and `hcounteren.HPM13` are set, the `hpmcounter13` CSR (an alias of `mhpmconuter13`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM13` is clear. + When `hcounteren.HPM13` is clear and `mcounteren.HPM13` is set, then any access to `hpmcounter13` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM13` ! `hcounteren.HPM13` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM13`# .2+h! [.rotate]#`mcounteren.HPM13`# .2+h! [.rotate]#`scounteren.HPM13`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[13]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[13]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM14: location: 14 description: | @@ -311,19 +544,34 @@ hcounteren: When `mcounteren.HPM14` and `hcounteren.HPM14` are set, the `hpmcounter14` CSR (an alias of `mhpmconuter14`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM14` is clear. + When `hcounteren.HPM14` is clear and `mcounteren.HPM14` is set, then any access to `hpmcounter14` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM14` ! `hcounteren.HPM14` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM14`# .2+h! [.rotate]#`mcounteren.HPM14`# .2+h! [.rotate]#`scounteren.HPM14`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[14]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[14]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM15: location: 15 description: | @@ -333,19 +581,34 @@ hcounteren: When `mcounteren.HPM15` and `hcounteren.HPM15` are set, the `hpmcounter15` CSR (an alias of `mhpmconuter15`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM15` is clear. + When `hcounteren.HPM15` is clear and `mcounteren.HPM15` is set, then any access to `hpmcounter15` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM15` ! `hcounteren.HPM15` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM15`# .2+h! [.rotate]#`mcounteren.HPM15`# .2+h! [.rotate]#`scounteren.HPM15`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[15]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[15]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM16: location: 16 description: | @@ -355,19 +618,34 @@ hcounteren: When `mcounteren.HPM16` and `hcounteren.HPM16` are set, the `hpmcounter16` CSR (an alias of `mhpmconuter16`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM16` is clear. + When `hcounteren.HPM16` is clear and `mcounteren.HPM16` is set, then any access to `hpmcounter16` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM16` ! `hcounteren.HPM16` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM16`# .2+h! [.rotate]#`mcounteren.HPM16`# .2+h! [.rotate]#`scounteren.HPM16`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[16]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[16]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM17: location: 17 description: | @@ -377,19 +655,34 @@ hcounteren: When `mcounteren.HPM17` and `hcounteren.HPM17` are set, the `hpmcounter17` CSR (an alias of `mhpmconuter17`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM17` is clear. + When `hcounteren.HPM17` is clear and `mcounteren.HPM17` is set, then any access to `hpmcounter17` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM17` ! `hcounteren.HPM17` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM17`# .2+h! [.rotate]#`mcounteren.HPM17`# .2+h! [.rotate]#`scounteren.HPM17`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[17]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[17]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM18: location: 18 description: | @@ -399,19 +692,34 @@ hcounteren: When `mcounteren.HPM18` and `hcounteren.HPM18` are set, the `hpmcounter18` CSR (an alias of `mhpmconuter18`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM18` is clear. + When `hcounteren.HPM18` is clear and `mcounteren.HPM18` is set, then any access to `hpmcounter18` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM18` ! `hcounteren.HPM18` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM18`# .2+h! [.rotate]#`mcounteren.HPM18`# .2+h! [.rotate]#`scounteren.HPM18`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[18]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[18]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM19: location: 19 description: | @@ -421,19 +729,34 @@ hcounteren: When `mcounteren.HPM19` and `hcounteren.HPM19` are set, the `hpmcounter19` CSR (an alias of `mhpmconuter19`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM19` is clear. + When `hcounteren.HPM19` is clear and `mcounteren.HPM19` is set, then any access to `hpmcounter19` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM19` ! `hcounteren.HPM19` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM19`# .2+h! [.rotate]#`mcounteren.HPM19`# .2+h! [.rotate]#`scounteren.HPM19`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[19]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[19]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM20: location: 20 description: | @@ -443,19 +766,34 @@ hcounteren: When `mcounteren.HPM20` and `hcounteren.HPM20` are set, the `hpmcounter20` CSR (an alias of `mhpmconuter20`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM20` is clear. + When `hcounteren.HPM20` is clear and `mcounteren.HPM20` is set, then any access to `hpmcounter20` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM20` ! `hcounteren.HPM20` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM20`# .2+h! [.rotate]#`mcounteren.HPM20`# .2+h! [.rotate]#`scounteren.HPM20`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[20]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[20]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM21: location: 21 description: | @@ -465,19 +803,34 @@ hcounteren: When `mcounteren.HPM21` and `hcounteren.HPM21` are set, the `hpmcounter21` CSR (an alias of `mhpmconuter21`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM21` is clear. + When `hcounteren.HPM21` is clear and `mcounteren.HPM21` is set, then any access to `hpmcounter21` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM21` ! `hcounteren.HPM21` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM21`# .2+h! [.rotate]#`mcounteren.HPM21`# .2+h! [.rotate]#`scounteren.HPM21`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[21]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[21]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM22: location: 22 description: | @@ -487,19 +840,34 @@ hcounteren: When `mcounteren.HPM22` and `hcounteren.HPM22` are set, the `hpmcounter22` CSR (an alias of `mhpmconuter22`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM22` is clear. + When `hcounteren.HPM22` is clear and `mcounteren.HPM22` is set, then any access to `hpmcounter22` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM22` ! `hcounteren.HPM22` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM22`# .2+h! [.rotate]#`mcounteren.HPM22`# .2+h! [.rotate]#`scounteren.HPM22`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[22]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[22]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM23: location: 23 description: | @@ -509,19 +877,34 @@ hcounteren: When `mcounteren.HPM23` and `hcounteren.HPM23` are set, the `hpmcounter23` CSR (an alias of `mhpmconuter23`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM23` is clear. + When `hcounteren.HPM23` is clear and `mcounteren.HPM23` is set, then any access to `hpmcounter23` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM23` ! `hcounteren.HPM23` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM23`# .2+h! [.rotate]#`mcounteren.HPM23`# .2+h! [.rotate]#`scounteren.HPM23`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[23]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[23]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM24: location: 24 description: | @@ -531,19 +914,34 @@ hcounteren: When `mcounteren.HPM24` and `hcounteren.HPM24` are set, the `hpmcounter24` CSR (an alias of `mhpmconuter24`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM24` is clear. + When `hcounteren.HPM24` is clear and `mcounteren.HPM24` is set, then any access to `hpmcounter24` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM24` ! `hcounteren.HPM24` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM24`# .2+h! [.rotate]#`mcounteren.HPM24`# .2+h! [.rotate]#`scounteren.HPM24`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[24]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[24]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM25: location: 25 description: | @@ -553,19 +951,34 @@ hcounteren: When `mcounteren.HPM25` and `hcounteren.HPM25` are set, the `hpmcounter25` CSR (an alias of `mhpmconuter25`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM25` is clear. + When `hcounteren.HPM25` is clear and `mcounteren.HPM25` is set, then any access to `hpmcounter25` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM25` ! `hcounteren.HPM25` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM25`# .2+h! [.rotate]#`mcounteren.HPM25`# .2+h! [.rotate]#`scounteren.HPM25`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[25]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[25]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM26: location: 26 description: | @@ -575,19 +988,34 @@ hcounteren: When `mcounteren.HPM26` and `hcounteren.HPM26` are set, the `hpmcounter26` CSR (an alias of `mhpmconuter26`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM26` is clear. + When `hcounteren.HPM26` is clear and `mcounteren.HPM26` is set, then any access to `hpmcounter26` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM26` ! `hcounteren.HPM26` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM26`# .2+h! [.rotate]#`mcounteren.HPM26`# .2+h! [.rotate]#`scounteren.HPM26`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[26]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[26]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM27: location: 27 description: | @@ -597,19 +1025,34 @@ hcounteren: When `mcounteren.HPM27` and `hcounteren.HPM27` are set, the `hpmcounter27` CSR (an alias of `mhpmconuter27`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM27` is clear. + When `hcounteren.HPM27` is clear and `mcounteren.HPM27` is set, then any access to `hpmcounter27` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM27` ! `hcounteren.HPM27` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM27`# .2+h! [.rotate]#`mcounteren.HPM27`# .2+h! [.rotate]#`scounteren.HPM27`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[27]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[27]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM28: location: 28 description: | @@ -619,19 +1062,34 @@ hcounteren: When `mcounteren.HPM28` and `hcounteren.HPM28` are set, the `hpmcounter28` CSR (an alias of `mhpmconuter28`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM28` is clear. + When `hcounteren.HPM28` is clear and `mcounteren.HPM28` is set, then any access to `hpmcounter28` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM28` ! `hcounteren.HPM28` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM28`# .2+h! [.rotate]#`mcounteren.HPM28`# .2+h! [.rotate]#`scounteren.HPM28`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[28]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[28]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM29: location: 29 description: | @@ -641,19 +1099,34 @@ hcounteren: When `mcounteren.HPM29` and `hcounteren.HPM29` are set, the `hpmcounter29` CSR (an alias of `mhpmconuter29`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM29` is clear. + When `hcounteren.HPM29` is clear and `mcounteren.HPM29` is set, then any access to `hpmcounter29` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM29` ! `hcounteren.HPM29` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM29`# .2+h! [.rotate]#`mcounteren.HPM29`# .2+h! [.rotate]#`scounteren.HPM29`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[29]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[29]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM30: location: 30 description: | @@ -663,19 +1136,34 @@ hcounteren: When `mcounteren.HPM30` and `hcounteren.HPM30` are set, the `hpmcounter30` CSR (an alias of `mhpmconuter30`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM30` is clear. + When `hcounteren.HPM30` is clear and `mcounteren.HPM30` is set, then any access to `hpmcounter30` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM30` ! `hcounteren.HPM30` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM30`# .2+h! [.rotate]#`mcounteren.HPM30`# .2+h! [.rotate]#`scounteren.HPM30`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL + type(): | + if (HCOUNTENABLE_EN[30]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[30]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM31: location: 31 description: | @@ -685,24 +1173,31 @@ hcounteren: When `mcounteren.HPM31` and `hcounteren.HPM31` are set, the `hpmcounter31` CSR (an alias of `mhpmconuter31`) is accessible to VS-mode. - This bit is read-only 0 when `mcounteren.HPM31` is clear. + When `hcounteren.HPM31` is clear and `mcounteren.HPM31` is set, then any access to `hpmcounter31` in + VU-mode or VS-mode causes a VirtualInstruction execption. Summary: + [separator="!",%autowidth] !=== - ! `mcounteren.HPM31` ! `hcounteren.HPM31` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable + .2+h! [.rotate]#`hcounteren.HPM31`# .2+h! [.rotate]#`mcounteren.HPM31`# .2+h! [.rotate]#`scounteren.HPM31`# 2+^.>! `cycle` access behavior + .>h! VS-mode .>h! VU-mode + + ! 0 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 0 ! 1 ! - ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! - ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 1 ! 0 ! allowed ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! allowed ! allowed !=== - - type: RW - reset_value: UNDEFINED_LEGAL - sw_read(): | - if (!implemented?(ExtensionName::Zicntr) && !implemented?(ExtensionName::Zihpm)) { - # this CSR isn't supposed to exist when Zicntr and Zihpm are not implemented - raise(ExceptionCode::IllegalInstruction, $encoding); - } - - # any bit of mcounteren that is zero forces that same bit of hcounteren to 0 - return $bits(CSR[hcounteren]) & $bits(CSR[mcounteren]); \ No newline at end of file + type(): | + if (HCOUNTENABLE_EN[31]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (HCOUNTENABLE_EN[31]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/I/mcounteren.yaml b/arch/csr/I/mcounteren.yaml index 4bc0daedd..f83737652 100644 --- a/arch/csr/I/mcounteren.yaml +++ b/arch/csr/I/mcounteren.yaml @@ -1,4 +1,4 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json +# yaml-language-server: $schema=../../../schemas/csr_schema.json # WARNING: This file is auto-generated from arch/csr/I/mcounteren.layout @@ -105,13 +105,13 @@ mcounteren: When `hcounteren.CY` && `scounteren.CY` are both set, `cycle` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[2]) { + if (MCOUNTENABLE_EN[0]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[2]) { + if (MCOUNTENABLE_EN[0]) { return UNDEFINED_LEGAL; } else { return 0; @@ -119,10 +119,34 @@ mcounteren: TM: location: 1 description: | - Placeholder for delegating `time` to less-privileged modes; however, since `time` - is memory-mapped rather than a CSR, this field is always read-only zero. - type: RO - reset_value: 0 + When set, the `time` CSR (an alias of the `mtime` memory-mapped CSR) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.TM` is also set, `time` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.TM` is also set, `time` is futher accessible to VS-mode. + + When `hcounteren.TM` && `scounteren.TM` are both set, `time` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (MCOUNTENABLE_EN[1]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (MCOUNTENABLE_EN[1]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } IR: location: 2 description: | @@ -143,13 +167,13 @@ mcounteren: When `hcounteren.IR` && `scounteren.IR` are both set, `instret` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[2]) { + if (MCOUNTENABLE_EN[2]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[2]) { + if (MCOUNTENABLE_EN[2]) { return UNDEFINED_LEGAL; } else { return 0; @@ -174,13 +198,13 @@ mcounteren: When `hcounteren.HPM3` && `scounteren.HPM3` are both set, `hpmcounter3` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[3]) { + if (MCOUNTENABLE_EN[3]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[3]) { + if (MCOUNTENABLE_EN[3]) { return UNDEFINED_LEGAL; } else { return 0; @@ -205,13 +229,13 @@ mcounteren: When `hcounteren.HPM4` && `scounteren.HPM4` are both set, `hpmcounter4` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[4]) { + if (MCOUNTENABLE_EN[4]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[4]) { + if (MCOUNTENABLE_EN[4]) { return UNDEFINED_LEGAL; } else { return 0; @@ -236,13 +260,13 @@ mcounteren: When `hcounteren.HPM5` && `scounteren.HPM5` are both set, `hpmcounter5` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[5]) { + if (MCOUNTENABLE_EN[5]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[5]) { + if (MCOUNTENABLE_EN[5]) { return UNDEFINED_LEGAL; } else { return 0; @@ -267,13 +291,13 @@ mcounteren: When `hcounteren.HPM6` && `scounteren.HPM6` are both set, `hpmcounter6` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[6]) { + if (MCOUNTENABLE_EN[6]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[6]) { + if (MCOUNTENABLE_EN[6]) { return UNDEFINED_LEGAL; } else { return 0; @@ -298,13 +322,13 @@ mcounteren: When `hcounteren.HPM7` && `scounteren.HPM7` are both set, `hpmcounter7` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[7]) { + if (MCOUNTENABLE_EN[7]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[7]) { + if (MCOUNTENABLE_EN[7]) { return UNDEFINED_LEGAL; } else { return 0; @@ -329,13 +353,13 @@ mcounteren: When `hcounteren.HPM8` && `scounteren.HPM8` are both set, `hpmcounter8` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[8]) { + if (MCOUNTENABLE_EN[8]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[8]) { + if (MCOUNTENABLE_EN[8]) { return UNDEFINED_LEGAL; } else { return 0; @@ -360,13 +384,13 @@ mcounteren: When `hcounteren.HPM9` && `scounteren.HPM9` are both set, `hpmcounter9` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[9]) { + if (MCOUNTENABLE_EN[9]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[9]) { + if (MCOUNTENABLE_EN[9]) { return UNDEFINED_LEGAL; } else { return 0; @@ -391,13 +415,13 @@ mcounteren: When `hcounteren.HPM10` && `scounteren.HPM10` are both set, `hpmcounter10` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[10]) { + if (MCOUNTENABLE_EN[10]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[10]) { + if (MCOUNTENABLE_EN[10]) { return UNDEFINED_LEGAL; } else { return 0; @@ -422,13 +446,13 @@ mcounteren: When `hcounteren.HPM11` && `scounteren.HPM11` are both set, `hpmcounter11` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[11]) { + if (MCOUNTENABLE_EN[11]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[11]) { + if (MCOUNTENABLE_EN[11]) { return UNDEFINED_LEGAL; } else { return 0; @@ -453,13 +477,13 @@ mcounteren: When `hcounteren.HPM12` && `scounteren.HPM12` are both set, `hpmcounter12` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[12]) { + if (MCOUNTENABLE_EN[12]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[12]) { + if (MCOUNTENABLE_EN[12]) { return UNDEFINED_LEGAL; } else { return 0; @@ -484,13 +508,13 @@ mcounteren: When `hcounteren.HPM13` && `scounteren.HPM13` are both set, `hpmcounter13` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[13]) { + if (MCOUNTENABLE_EN[13]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[13]) { + if (MCOUNTENABLE_EN[13]) { return UNDEFINED_LEGAL; } else { return 0; @@ -515,13 +539,13 @@ mcounteren: When `hcounteren.HPM14` && `scounteren.HPM14` are both set, `hpmcounter14` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[14]) { + if (MCOUNTENABLE_EN[14]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[14]) { + if (MCOUNTENABLE_EN[14]) { return UNDEFINED_LEGAL; } else { return 0; @@ -546,13 +570,13 @@ mcounteren: When `hcounteren.HPM15` && `scounteren.HPM15` are both set, `hpmcounter15` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[15]) { + if (MCOUNTENABLE_EN[15]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[15]) { + if (MCOUNTENABLE_EN[15]) { return UNDEFINED_LEGAL; } else { return 0; @@ -577,13 +601,13 @@ mcounteren: When `hcounteren.HPM16` && `scounteren.HPM16` are both set, `hpmcounter16` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[16]) { + if (MCOUNTENABLE_EN[16]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[16]) { + if (MCOUNTENABLE_EN[16]) { return UNDEFINED_LEGAL; } else { return 0; @@ -608,13 +632,13 @@ mcounteren: When `hcounteren.HPM17` && `scounteren.HPM17` are both set, `hpmcounter17` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[17]) { + if (MCOUNTENABLE_EN[17]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[17]) { + if (MCOUNTENABLE_EN[17]) { return UNDEFINED_LEGAL; } else { return 0; @@ -639,13 +663,13 @@ mcounteren: When `hcounteren.HPM18` && `scounteren.HPM18` are both set, `hpmcounter18` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[18]) { + if (MCOUNTENABLE_EN[18]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[18]) { + if (MCOUNTENABLE_EN[18]) { return UNDEFINED_LEGAL; } else { return 0; @@ -670,13 +694,13 @@ mcounteren: When `hcounteren.HPM19` && `scounteren.HPM19` are both set, `hpmcounter19` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[19]) { + if (MCOUNTENABLE_EN[19]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[19]) { + if (MCOUNTENABLE_EN[19]) { return UNDEFINED_LEGAL; } else { return 0; @@ -701,13 +725,13 @@ mcounteren: When `hcounteren.HPM20` && `scounteren.HPM20` are both set, `hpmcounter20` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[20]) { + if (MCOUNTENABLE_EN[20]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[20]) { + if (MCOUNTENABLE_EN[20]) { return UNDEFINED_LEGAL; } else { return 0; @@ -732,13 +756,13 @@ mcounteren: When `hcounteren.HPM21` && `scounteren.HPM21` are both set, `hpmcounter21` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[21]) { + if (MCOUNTENABLE_EN[21]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[21]) { + if (MCOUNTENABLE_EN[21]) { return UNDEFINED_LEGAL; } else { return 0; @@ -763,13 +787,13 @@ mcounteren: When `hcounteren.HPM22` && `scounteren.HPM22` are both set, `hpmcounter22` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[22]) { + if (MCOUNTENABLE_EN[22]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[22]) { + if (MCOUNTENABLE_EN[22]) { return UNDEFINED_LEGAL; } else { return 0; @@ -794,13 +818,13 @@ mcounteren: When `hcounteren.HPM23` && `scounteren.HPM23` are both set, `hpmcounter23` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[23]) { + if (MCOUNTENABLE_EN[23]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[23]) { + if (MCOUNTENABLE_EN[23]) { return UNDEFINED_LEGAL; } else { return 0; @@ -825,13 +849,13 @@ mcounteren: When `hcounteren.HPM24` && `scounteren.HPM24` are both set, `hpmcounter24` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[24]) { + if (MCOUNTENABLE_EN[24]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[24]) { + if (MCOUNTENABLE_EN[24]) { return UNDEFINED_LEGAL; } else { return 0; @@ -856,13 +880,13 @@ mcounteren: When `hcounteren.HPM25` && `scounteren.HPM25` are both set, `hpmcounter25` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[25]) { + if (MCOUNTENABLE_EN[25]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[25]) { + if (MCOUNTENABLE_EN[25]) { return UNDEFINED_LEGAL; } else { return 0; @@ -887,13 +911,13 @@ mcounteren: When `hcounteren.HPM26` && `scounteren.HPM26` are both set, `hpmcounter26` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[26]) { + if (MCOUNTENABLE_EN[26]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[26]) { + if (MCOUNTENABLE_EN[26]) { return UNDEFINED_LEGAL; } else { return 0; @@ -918,13 +942,13 @@ mcounteren: When `hcounteren.HPM27` && `scounteren.HPM27` are both set, `hpmcounter27` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[27]) { + if (MCOUNTENABLE_EN[27]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[27]) { + if (MCOUNTENABLE_EN[27]) { return UNDEFINED_LEGAL; } else { return 0; @@ -949,13 +973,13 @@ mcounteren: When `hcounteren.HPM28` && `scounteren.HPM28` are both set, `hpmcounter28` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[28]) { + if (MCOUNTENABLE_EN[28]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[28]) { + if (MCOUNTENABLE_EN[28]) { return UNDEFINED_LEGAL; } else { return 0; @@ -980,13 +1004,13 @@ mcounteren: When `hcounteren.HPM29` && `scounteren.HPM29` are both set, `hpmcounter29` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[29]) { + if (MCOUNTENABLE_EN[29]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[29]) { + if (MCOUNTENABLE_EN[29]) { return UNDEFINED_LEGAL; } else { return 0; @@ -1011,13 +1035,13 @@ mcounteren: When `hcounteren.HPM30` && `scounteren.HPM30` are both set, `hpmcounter30` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[30]) { + if (MCOUNTENABLE_EN[30]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[30]) { + if (MCOUNTENABLE_EN[30]) { return UNDEFINED_LEGAL; } else { return 0; @@ -1042,13 +1066,13 @@ mcounteren: When `hcounteren.HPM31` && `scounteren.HPM31` are both set, `hpmcounter31` is futher accessible to VU-mode. <%- end -%> type(): | - if (COUNTENABLE_EN[31]) { + if (MCOUNTENABLE_EN[31]) { return CsrFieldType::RW; } else { return CsrFieldType::RO; } reset_value(): | - if (COUNTENABLE_EN[31]) { + if (MCOUNTENABLE_EN[31]) { return UNDEFINED_LEGAL; } else { return 0; diff --git a/arch/csr/I/pmpcfg0.yaml b/arch/csr/I/pmpcfg0.yaml index c23e52e8b..6e52cd838 100644 --- a/arch/csr/I/pmpcfg0.yaml +++ b/arch/csr/I/pmpcfg0.yaml @@ -19,7 +19,7 @@ pmpcfg0: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -78,7 +78,7 @@ pmpcfg0: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -137,7 +137,7 @@ pmpcfg0: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -196,7 +196,7 @@ pmpcfg0: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -256,7 +256,7 @@ pmpcfg0: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -316,7 +316,7 @@ pmpcfg0: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -376,7 +376,7 @@ pmpcfg0: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -436,7 +436,7 @@ pmpcfg0: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/I/pmpcfg1.yaml b/arch/csr/I/pmpcfg1.yaml index 238763041..e9bcfc293 100644 --- a/arch/csr/I/pmpcfg1.yaml +++ b/arch/csr/I/pmpcfg1.yaml @@ -20,7 +20,7 @@ pmpcfg1: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -79,7 +79,7 @@ pmpcfg1: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -138,7 +138,7 @@ pmpcfg1: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -197,7 +197,7 @@ pmpcfg1: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/I/pmpcfg10.yaml b/arch/csr/I/pmpcfg10.yaml index 0cf24709d..71a74f0ef 100644 --- a/arch/csr/I/pmpcfg10.yaml +++ b/arch/csr/I/pmpcfg10.yaml @@ -19,7 +19,7 @@ pmpcfg10: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -78,7 +78,7 @@ pmpcfg10: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -137,7 +137,7 @@ pmpcfg10: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -196,7 +196,7 @@ pmpcfg10: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -256,7 +256,7 @@ pmpcfg10: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -316,7 +316,7 @@ pmpcfg10: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -376,7 +376,7 @@ pmpcfg10: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -436,7 +436,7 @@ pmpcfg10: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/I/pmpcfg11.yaml b/arch/csr/I/pmpcfg11.yaml index 703044db0..8b2e1de16 100644 --- a/arch/csr/I/pmpcfg11.yaml +++ b/arch/csr/I/pmpcfg11.yaml @@ -20,7 +20,7 @@ pmpcfg11: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -79,7 +79,7 @@ pmpcfg11: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -138,7 +138,7 @@ pmpcfg11: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -197,7 +197,7 @@ pmpcfg11: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/I/pmpcfg12.yaml b/arch/csr/I/pmpcfg12.yaml index bfb540a3d..19bf3e8e8 100644 --- a/arch/csr/I/pmpcfg12.yaml +++ b/arch/csr/I/pmpcfg12.yaml @@ -19,7 +19,7 @@ pmpcfg12: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -78,7 +78,7 @@ pmpcfg12: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -137,7 +137,7 @@ pmpcfg12: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -196,7 +196,7 @@ pmpcfg12: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -256,7 +256,7 @@ pmpcfg12: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -316,7 +316,7 @@ pmpcfg12: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -376,7 +376,7 @@ pmpcfg12: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -436,7 +436,7 @@ pmpcfg12: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/I/pmpcfg13.yaml b/arch/csr/I/pmpcfg13.yaml index c44e89920..fbacf90cb 100644 --- a/arch/csr/I/pmpcfg13.yaml +++ b/arch/csr/I/pmpcfg13.yaml @@ -20,7 +20,7 @@ pmpcfg13: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -79,7 +79,7 @@ pmpcfg13: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -138,7 +138,7 @@ pmpcfg13: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -197,7 +197,7 @@ pmpcfg13: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/I/pmpcfg14.yaml b/arch/csr/I/pmpcfg14.yaml index 3ef37226d..d427aa9d0 100644 --- a/arch/csr/I/pmpcfg14.yaml +++ b/arch/csr/I/pmpcfg14.yaml @@ -19,7 +19,7 @@ pmpcfg14: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -78,7 +78,7 @@ pmpcfg14: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -137,7 +137,7 @@ pmpcfg14: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -196,7 +196,7 @@ pmpcfg14: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -256,7 +256,7 @@ pmpcfg14: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -316,7 +316,7 @@ pmpcfg14: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -376,7 +376,7 @@ pmpcfg14: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -436,7 +436,7 @@ pmpcfg14: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/I/pmpcfg15.yaml b/arch/csr/I/pmpcfg15.yaml index ec2cb3493..c69c48751 100644 --- a/arch/csr/I/pmpcfg15.yaml +++ b/arch/csr/I/pmpcfg15.yaml @@ -20,7 +20,7 @@ pmpcfg15: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -79,7 +79,7 @@ pmpcfg15: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -138,7 +138,7 @@ pmpcfg15: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -197,7 +197,7 @@ pmpcfg15: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/I/pmpcfg2.yaml b/arch/csr/I/pmpcfg2.yaml index 894720486..0c56b3f42 100644 --- a/arch/csr/I/pmpcfg2.yaml +++ b/arch/csr/I/pmpcfg2.yaml @@ -19,7 +19,7 @@ pmpcfg2: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -78,7 +78,7 @@ pmpcfg2: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -137,7 +137,7 @@ pmpcfg2: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -196,7 +196,7 @@ pmpcfg2: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -256,7 +256,7 @@ pmpcfg2: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -316,7 +316,7 @@ pmpcfg2: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -376,7 +376,7 @@ pmpcfg2: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -436,7 +436,7 @@ pmpcfg2: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/I/pmpcfg3.yaml b/arch/csr/I/pmpcfg3.yaml index 536e90288..08a50c283 100644 --- a/arch/csr/I/pmpcfg3.yaml +++ b/arch/csr/I/pmpcfg3.yaml @@ -20,7 +20,7 @@ pmpcfg3: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -79,7 +79,7 @@ pmpcfg3: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -138,7 +138,7 @@ pmpcfg3: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -197,7 +197,7 @@ pmpcfg3: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/I/pmpcfg4.yaml b/arch/csr/I/pmpcfg4.yaml index 320846dc3..6a34e1df0 100644 --- a/arch/csr/I/pmpcfg4.yaml +++ b/arch/csr/I/pmpcfg4.yaml @@ -19,7 +19,7 @@ pmpcfg4: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -78,7 +78,7 @@ pmpcfg4: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -137,7 +137,7 @@ pmpcfg4: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -196,7 +196,7 @@ pmpcfg4: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -256,7 +256,7 @@ pmpcfg4: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -316,7 +316,7 @@ pmpcfg4: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -376,7 +376,7 @@ pmpcfg4: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -436,7 +436,7 @@ pmpcfg4: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/I/pmpcfg5.yaml b/arch/csr/I/pmpcfg5.yaml index 480a41997..a3af7fc57 100644 --- a/arch/csr/I/pmpcfg5.yaml +++ b/arch/csr/I/pmpcfg5.yaml @@ -20,7 +20,7 @@ pmpcfg5: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -79,7 +79,7 @@ pmpcfg5: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -138,7 +138,7 @@ pmpcfg5: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -197,7 +197,7 @@ pmpcfg5: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/I/pmpcfg6.yaml b/arch/csr/I/pmpcfg6.yaml index 469a1cf08..7465d542f 100644 --- a/arch/csr/I/pmpcfg6.yaml +++ b/arch/csr/I/pmpcfg6.yaml @@ -19,7 +19,7 @@ pmpcfg6: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -78,7 +78,7 @@ pmpcfg6: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -137,7 +137,7 @@ pmpcfg6: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -196,7 +196,7 @@ pmpcfg6: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -256,7 +256,7 @@ pmpcfg6: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -316,7 +316,7 @@ pmpcfg6: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -376,7 +376,7 @@ pmpcfg6: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -436,7 +436,7 @@ pmpcfg6: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/I/pmpcfg7.yaml b/arch/csr/I/pmpcfg7.yaml index 8650cba0b..df1aad0df 100644 --- a/arch/csr/I/pmpcfg7.yaml +++ b/arch/csr/I/pmpcfg7.yaml @@ -20,7 +20,7 @@ pmpcfg7: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -79,7 +79,7 @@ pmpcfg7: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -138,7 +138,7 @@ pmpcfg7: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -197,7 +197,7 @@ pmpcfg7: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/I/pmpcfg8.yaml b/arch/csr/I/pmpcfg8.yaml index 4b53355f9..510c28109 100644 --- a/arch/csr/I/pmpcfg8.yaml +++ b/arch/csr/I/pmpcfg8.yaml @@ -19,7 +19,7 @@ pmpcfg8: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -78,7 +78,7 @@ pmpcfg8: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -137,7 +137,7 @@ pmpcfg8: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -196,7 +196,7 @@ pmpcfg8: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -256,7 +256,7 @@ pmpcfg8: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -316,7 +316,7 @@ pmpcfg8: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -376,7 +376,7 @@ pmpcfg8: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -436,7 +436,7 @@ pmpcfg8: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/I/pmpcfg9.yaml b/arch/csr/I/pmpcfg9.yaml index b1fe5a35d..76f4bc3aa 100644 --- a/arch/csr/I/pmpcfg9.yaml +++ b/arch/csr/I/pmpcfg9.yaml @@ -20,7 +20,7 @@ pmpcfg9: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -79,7 +79,7 @@ pmpcfg9: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -138,7 +138,7 @@ pmpcfg9: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description @@ -197,7 +197,7 @@ pmpcfg9: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/I/pmpcfgN.layout b/arch/csr/I/pmpcfgN.layout index 7ad94e1e1..984ded610 100644 --- a/arch/csr/I/pmpcfgN.layout +++ b/arch/csr/I/pmpcfgN.layout @@ -24,7 +24,7 @@ pmpcfg<%= pmpcfg_num %>: The bits are as follows: - [%autowidth] + [separator="!",%autowidth] !=== ! Name ! Location ! Description diff --git a/arch/csr/S/scounteren.layout b/arch/csr/S/scounteren.layout index 7605c8aba..eecf21dbf 100644 --- a/arch/csr/S/scounteren.layout +++ b/arch/csr/S/scounteren.layout @@ -15,40 +15,55 @@ scounteren: description: | When both `scounteren.CY` and `mcounteren.CY` are set, the `cycle` CSR (an alias of `mcycle`) is accessible to U-mode <%% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.CY`)<%% end %>. - - This bit is read-only 0 when `mcounteren.CY` is clear. - - Summary: - - !=== - ! `mcounteren.CY` ! `scounteren.CY` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== definedBy: Zicntr - type: RW-H - reset_value: UNDEFINED_LEGAL + type(): | + if (SCOUNTENABLE_EN[0]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[0]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + TM: + location: 1 + description: | + When both `scounteren.TM` and `mcounteren.TM` are set, the `time` CSR (an alias of `mtime` memory-mapped CSR) is accessible to U-mode + <%% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.TM`)<%% end %>. + definedBy: Zicntr + type(): | + if (SCOUNTENABLE_EN[1]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[1]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } IR: location: 2 description: | When both `scounteren.IR` and `mcounteren.IR` are set, the `instret` CSR (an alias of memory-mapped `minstret`) is accessible to U-mode <%% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.IR`)<%% end %>. - - This bit is read-only 0 when `mcounteren.IR` is clear. - - Summary: - - !=== - ! `mcounteren.IR` ! `scounteren.IR` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - - type: RW-H - reset_value: UNDEFINED_LEGAL + definedBy: Zicntr + type(): | + if (SCOUNTENABLE_EN[2]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[2]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } <%- (3..31).each do |hpm_num| -%> HPM<%= hpm_num %>: location: <%= hpm_num %> @@ -56,26 +71,17 @@ scounteren: When both `scounteren.HPM<%= hpm_num %>` and `mcounteren.HPM<%= hpm_num %>` are set, the `hpmcounter<%= hpm_num %>` CSR (an alias of `mhpmcounter<%= hpm_num %>`) is accessible to U-mode <%% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM<%= hpm_num %>`)<%% end %>. - - This bit is read-only 0 when `mcounteren.HPM<%= hpm_num %>` is clear. - - Summary: - - !=== - ! `mcounteren.HPM<%= hpm_num %>` ! `scounteren.HPM<%= hpm_num %>` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[<%= hpm_num %>]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[<%= hpm_num %>]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } <%- end -%> - sw_read(): | - if (!implemented?(ExtensionName::Zicntr) && !implemented?(ExtensionName::Zihpm)) { - # this CSR isn't supposed to exist when Zicntr and Zihpm are not implemented - raise(ExceptionCode::IllegalInstruction, $encoding); - } - - # any bit of mcounteren that is zero forces that same bit of scounteren to 0 - return $bits(CSR[scounteren]) & $bits(CSR[mcounteren]); \ No newline at end of file diff --git a/arch/csr/S/scounteren.yaml b/arch/csr/S/scounteren.yaml index b69f84e81..385d53997 100644 --- a/arch/csr/S/scounteren.yaml +++ b/arch/csr/S/scounteren.yaml @@ -18,625 +18,603 @@ scounteren: description: | When both `scounteren.CY` and `mcounteren.CY` are set, the `cycle` CSR (an alias of `mcycle`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.CY`)<% end %>. - - This bit is read-only 0 when `mcounteren.CY` is clear. - - Summary: - - !=== - ! `mcounteren.CY` ! `scounteren.CY` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== definedBy: Zicntr - type: RW-H - reset_value: UNDEFINED_LEGAL + type(): | + if (SCOUNTENABLE_EN[0]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[0]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + TM: + location: 1 + description: | + When both `scounteren.TM` and `mcounteren.TM` are set, the `time` CSR (an alias of `mtime` memory-mapped CSR) is accessible to U-mode + <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.TM`)<% end %>. + definedBy: Zicntr + type(): | + if (SCOUNTENABLE_EN[1]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[1]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } IR: location: 2 description: | When both `scounteren.IR` and `mcounteren.IR` are set, the `instret` CSR (an alias of memory-mapped `minstret`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.IR`)<% end %>. - - This bit is read-only 0 when `mcounteren.IR` is clear. - - Summary: - - !=== - ! `mcounteren.IR` ! `scounteren.IR` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - - type: RW-H - reset_value: UNDEFINED_LEGAL + definedBy: Zicntr + type(): | + if (SCOUNTENABLE_EN[2]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[2]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM3: location: 3 description: | When both `scounteren.HPM3` and `mcounteren.HPM3` are set, the `hpmcounter3` CSR (an alias of `mhpmcounter3`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM3`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM3` is clear. - - Summary: - - !=== - ! `mcounteren.HPM3` ! `scounteren.HPM3` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[3]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[3]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM4: location: 4 description: | When both `scounteren.HPM4` and `mcounteren.HPM4` are set, the `hpmcounter4` CSR (an alias of `mhpmcounter4`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM4`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM4` is clear. - - Summary: - - !=== - ! `mcounteren.HPM4` ! `scounteren.HPM4` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[4]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[4]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM5: location: 5 description: | When both `scounteren.HPM5` and `mcounteren.HPM5` are set, the `hpmcounter5` CSR (an alias of `mhpmcounter5`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM5`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM5` is clear. - - Summary: - - !=== - ! `mcounteren.HPM5` ! `scounteren.HPM5` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[5]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[5]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM6: location: 6 description: | When both `scounteren.HPM6` and `mcounteren.HPM6` are set, the `hpmcounter6` CSR (an alias of `mhpmcounter6`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM6`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM6` is clear. - - Summary: - - !=== - ! `mcounteren.HPM6` ! `scounteren.HPM6` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[6]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[6]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM7: location: 7 description: | When both `scounteren.HPM7` and `mcounteren.HPM7` are set, the `hpmcounter7` CSR (an alias of `mhpmcounter7`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM7`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM7` is clear. - - Summary: - - !=== - ! `mcounteren.HPM7` ! `scounteren.HPM7` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[7]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[7]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM8: location: 8 description: | When both `scounteren.HPM8` and `mcounteren.HPM8` are set, the `hpmcounter8` CSR (an alias of `mhpmcounter8`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM8`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM8` is clear. - - Summary: - - !=== - ! `mcounteren.HPM8` ! `scounteren.HPM8` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[8]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[8]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM9: location: 9 description: | When both `scounteren.HPM9` and `mcounteren.HPM9` are set, the `hpmcounter9` CSR (an alias of `mhpmcounter9`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM9`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM9` is clear. - - Summary: - - !=== - ! `mcounteren.HPM9` ! `scounteren.HPM9` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[9]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[9]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM10: location: 10 description: | When both `scounteren.HPM10` and `mcounteren.HPM10` are set, the `hpmcounter10` CSR (an alias of `mhpmcounter10`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM10`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM10` is clear. - - Summary: - - !=== - ! `mcounteren.HPM10` ! `scounteren.HPM10` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[10]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[10]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM11: location: 11 description: | When both `scounteren.HPM11` and `mcounteren.HPM11` are set, the `hpmcounter11` CSR (an alias of `mhpmcounter11`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM11`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM11` is clear. - - Summary: - - !=== - ! `mcounteren.HPM11` ! `scounteren.HPM11` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[11]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[11]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM12: location: 12 description: | When both `scounteren.HPM12` and `mcounteren.HPM12` are set, the `hpmcounter12` CSR (an alias of `mhpmcounter12`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM12`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM12` is clear. - - Summary: - - !=== - ! `mcounteren.HPM12` ! `scounteren.HPM12` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[12]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[12]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM13: location: 13 description: | When both `scounteren.HPM13` and `mcounteren.HPM13` are set, the `hpmcounter13` CSR (an alias of `mhpmcounter13`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM13`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM13` is clear. - - Summary: - - !=== - ! `mcounteren.HPM13` ! `scounteren.HPM13` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[13]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[13]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM14: location: 14 description: | When both `scounteren.HPM14` and `mcounteren.HPM14` are set, the `hpmcounter14` CSR (an alias of `mhpmcounter14`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM14`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM14` is clear. - - Summary: - - !=== - ! `mcounteren.HPM14` ! `scounteren.HPM14` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[14]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[14]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM15: location: 15 description: | When both `scounteren.HPM15` and `mcounteren.HPM15` are set, the `hpmcounter15` CSR (an alias of `mhpmcounter15`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM15`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM15` is clear. - - Summary: - - !=== - ! `mcounteren.HPM15` ! `scounteren.HPM15` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[15]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[15]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM16: location: 16 description: | When both `scounteren.HPM16` and `mcounteren.HPM16` are set, the `hpmcounter16` CSR (an alias of `mhpmcounter16`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM16`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM16` is clear. - - Summary: - - !=== - ! `mcounteren.HPM16` ! `scounteren.HPM16` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[16]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[16]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM17: location: 17 description: | When both `scounteren.HPM17` and `mcounteren.HPM17` are set, the `hpmcounter17` CSR (an alias of `mhpmcounter17`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM17`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM17` is clear. - - Summary: - - !=== - ! `mcounteren.HPM17` ! `scounteren.HPM17` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[17]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[17]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM18: location: 18 description: | When both `scounteren.HPM18` and `mcounteren.HPM18` are set, the `hpmcounter18` CSR (an alias of `mhpmcounter18`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM18`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM18` is clear. - - Summary: - - !=== - ! `mcounteren.HPM18` ! `scounteren.HPM18` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[18]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[18]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM19: location: 19 description: | When both `scounteren.HPM19` and `mcounteren.HPM19` are set, the `hpmcounter19` CSR (an alias of `mhpmcounter19`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM19`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM19` is clear. - - Summary: - - !=== - ! `mcounteren.HPM19` ! `scounteren.HPM19` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[19]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[19]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM20: location: 20 description: | When both `scounteren.HPM20` and `mcounteren.HPM20` are set, the `hpmcounter20` CSR (an alias of `mhpmcounter20`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM20`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM20` is clear. - - Summary: - - !=== - ! `mcounteren.HPM20` ! `scounteren.HPM20` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[20]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[20]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM21: location: 21 description: | When both `scounteren.HPM21` and `mcounteren.HPM21` are set, the `hpmcounter21` CSR (an alias of `mhpmcounter21`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM21`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM21` is clear. - - Summary: - - !=== - ! `mcounteren.HPM21` ! `scounteren.HPM21` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[21]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[21]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM22: location: 22 description: | When both `scounteren.HPM22` and `mcounteren.HPM22` are set, the `hpmcounter22` CSR (an alias of `mhpmcounter22`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM22`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM22` is clear. - - Summary: - - !=== - ! `mcounteren.HPM22` ! `scounteren.HPM22` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[22]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[22]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM23: location: 23 description: | When both `scounteren.HPM23` and `mcounteren.HPM23` are set, the `hpmcounter23` CSR (an alias of `mhpmcounter23`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM23`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM23` is clear. - - Summary: - - !=== - ! `mcounteren.HPM23` ! `scounteren.HPM23` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[23]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[23]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM24: location: 24 description: | When both `scounteren.HPM24` and `mcounteren.HPM24` are set, the `hpmcounter24` CSR (an alias of `mhpmcounter24`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM24`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM24` is clear. - - Summary: - - !=== - ! `mcounteren.HPM24` ! `scounteren.HPM24` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[24]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[24]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM25: location: 25 description: | When both `scounteren.HPM25` and `mcounteren.HPM25` are set, the `hpmcounter25` CSR (an alias of `mhpmcounter25`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM25`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM25` is clear. - - Summary: - - !=== - ! `mcounteren.HPM25` ! `scounteren.HPM25` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[25]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[25]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM26: location: 26 description: | When both `scounteren.HPM26` and `mcounteren.HPM26` are set, the `hpmcounter26` CSR (an alias of `mhpmcounter26`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM26`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM26` is clear. - - Summary: - - !=== - ! `mcounteren.HPM26` ! `scounteren.HPM26` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[26]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[26]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM27: location: 27 description: | When both `scounteren.HPM27` and `mcounteren.HPM27` are set, the `hpmcounter27` CSR (an alias of `mhpmcounter27`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM27`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM27` is clear. - - Summary: - - !=== - ! `mcounteren.HPM27` ! `scounteren.HPM27` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[27]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[27]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM28: location: 28 description: | When both `scounteren.HPM28` and `mcounteren.HPM28` are set, the `hpmcounter28` CSR (an alias of `mhpmcounter28`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM28`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM28` is clear. - - Summary: - - !=== - ! `mcounteren.HPM28` ! `scounteren.HPM28` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[28]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[28]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM29: location: 29 description: | When both `scounteren.HPM29` and `mcounteren.HPM29` are set, the `hpmcounter29` CSR (an alias of `mhpmcounter29`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM29`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM29` is clear. - - Summary: - - !=== - ! `mcounteren.HPM29` ! `scounteren.HPM29` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[29]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[29]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM30: location: 30 description: | When both `scounteren.HPM30` and `mcounteren.HPM30` are set, the `hpmcounter30` CSR (an alias of `mhpmcounter30`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM30`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM30` is clear. - - Summary: - - !=== - ! `mcounteren.HPM30` ! `scounteren.HPM30` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[30]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[30]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } HPM31: location: 31 description: | When both `scounteren.HPM31` and `mcounteren.HPM31` are set, the `hpmcounter31` CSR (an alias of `mhpmcounter31`) is accessible to U-mode <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.HPM31`)<% end %>. - - This bit is read-only 0 when `mcounteren.HPM31` is clear. - - Summary: - - !=== - ! `mcounteren.HPM31` ! `scounteren.HPM31` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL - sw_read(): | - if (!implemented?(ExtensionName::Zicntr) && !implemented?(ExtensionName::Zihpm)) { - # this CSR isn't supposed to exist when Zicntr and Zihpm are not implemented - raise(ExceptionCode::IllegalInstruction, $encoding); - } - - # any bit of mcounteren that is zero forces that same bit of scounteren to 0 - return $bits(CSR[scounteren]) & $bits(CSR[mcounteren]); \ No newline at end of file + definedBy: Zihpm + type(): | + if (SCOUNTENABLE_EN[31]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (SCOUNTENABLE_EN[31]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zicntr/mcountinhibit.layout b/arch/csr/Zicntr/mcountinhibit.layout index a1a052450..e0a80bd1d 100644 --- a/arch/csr/Zicntr/mcountinhibit.layout +++ b/arch/csr/Zicntr/mcountinhibit.layout @@ -57,7 +57,7 @@ mcountinhibit: HPM<%= hpm_num %>: location: <%= hpm_num %> description: | - <%%- if NUM_HPM_COUNTERS > <%= hpm_num - 3%> -%> + <%%- if COUNTINHIBIT_EN[<%= hpm_num %>] -%> When set, `hpmcounter<%= hpm_num %>.COUNT` stops counting in all privilege modes. <%%- else -%> Since hpmcounter<%= hpm_num %> is not implemented, this field is read-only zero. diff --git a/arch/csr/Zicntr/mcountinhibit.yaml b/arch/csr/Zicntr/mcountinhibit.yaml index 0c5f3176e..6e9ed7594 100644 --- a/arch/csr/Zicntr/mcountinhibit.yaml +++ b/arch/csr/Zicntr/mcountinhibit.yaml @@ -59,7 +59,7 @@ mcountinhibit: HPM3: location: 3 description: | - <%- if NUM_HPM_COUNTERS > 0 -%> + <%- if COUNTINHIBIT_EN[3] -%> When set, `hpmcounter3.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter3 is not implemented, this field is read-only zero. @@ -71,7 +71,7 @@ mcountinhibit: HPM4: location: 4 description: | - <%- if NUM_HPM_COUNTERS > 1 -%> + <%- if COUNTINHIBIT_EN[4] -%> When set, `hpmcounter4.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter4 is not implemented, this field is read-only zero. @@ -83,7 +83,7 @@ mcountinhibit: HPM5: location: 5 description: | - <%- if NUM_HPM_COUNTERS > 2 -%> + <%- if COUNTINHIBIT_EN[5] -%> When set, `hpmcounter5.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter5 is not implemented, this field is read-only zero. @@ -95,7 +95,7 @@ mcountinhibit: HPM6: location: 6 description: | - <%- if NUM_HPM_COUNTERS > 3 -%> + <%- if COUNTINHIBIT_EN[6] -%> When set, `hpmcounter6.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter6 is not implemented, this field is read-only zero. @@ -107,7 +107,7 @@ mcountinhibit: HPM7: location: 7 description: | - <%- if NUM_HPM_COUNTERS > 4 -%> + <%- if COUNTINHIBIT_EN[7] -%> When set, `hpmcounter7.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter7 is not implemented, this field is read-only zero. @@ -119,7 +119,7 @@ mcountinhibit: HPM8: location: 8 description: | - <%- if NUM_HPM_COUNTERS > 5 -%> + <%- if COUNTINHIBIT_EN[8] -%> When set, `hpmcounter8.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter8 is not implemented, this field is read-only zero. @@ -131,7 +131,7 @@ mcountinhibit: HPM9: location: 9 description: | - <%- if NUM_HPM_COUNTERS > 6 -%> + <%- if COUNTINHIBIT_EN[9] -%> When set, `hpmcounter9.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter9 is not implemented, this field is read-only zero. @@ -143,7 +143,7 @@ mcountinhibit: HPM10: location: 10 description: | - <%- if NUM_HPM_COUNTERS > 7 -%> + <%- if COUNTINHIBIT_EN[10] -%> When set, `hpmcounter10.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter10 is not implemented, this field is read-only zero. @@ -155,7 +155,7 @@ mcountinhibit: HPM11: location: 11 description: | - <%- if NUM_HPM_COUNTERS > 8 -%> + <%- if COUNTINHIBIT_EN[11] -%> When set, `hpmcounter11.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter11 is not implemented, this field is read-only zero. @@ -167,7 +167,7 @@ mcountinhibit: HPM12: location: 12 description: | - <%- if NUM_HPM_COUNTERS > 9 -%> + <%- if COUNTINHIBIT_EN[12] -%> When set, `hpmcounter12.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter12 is not implemented, this field is read-only zero. @@ -179,7 +179,7 @@ mcountinhibit: HPM13: location: 13 description: | - <%- if NUM_HPM_COUNTERS > 10 -%> + <%- if COUNTINHIBIT_EN[13] -%> When set, `hpmcounter13.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter13 is not implemented, this field is read-only zero. @@ -191,7 +191,7 @@ mcountinhibit: HPM14: location: 14 description: | - <%- if NUM_HPM_COUNTERS > 11 -%> + <%- if COUNTINHIBIT_EN[14] -%> When set, `hpmcounter14.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter14 is not implemented, this field is read-only zero. @@ -203,7 +203,7 @@ mcountinhibit: HPM15: location: 15 description: | - <%- if NUM_HPM_COUNTERS > 12 -%> + <%- if COUNTINHIBIT_EN[15] -%> When set, `hpmcounter15.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter15 is not implemented, this field is read-only zero. @@ -215,7 +215,7 @@ mcountinhibit: HPM16: location: 16 description: | - <%- if NUM_HPM_COUNTERS > 13 -%> + <%- if COUNTINHIBIT_EN[16] -%> When set, `hpmcounter16.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter16 is not implemented, this field is read-only zero. @@ -227,7 +227,7 @@ mcountinhibit: HPM17: location: 17 description: | - <%- if NUM_HPM_COUNTERS > 14 -%> + <%- if COUNTINHIBIT_EN[17] -%> When set, `hpmcounter17.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter17 is not implemented, this field is read-only zero. @@ -239,7 +239,7 @@ mcountinhibit: HPM18: location: 18 description: | - <%- if NUM_HPM_COUNTERS > 15 -%> + <%- if COUNTINHIBIT_EN[18] -%> When set, `hpmcounter18.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter18 is not implemented, this field is read-only zero. @@ -251,7 +251,7 @@ mcountinhibit: HPM19: location: 19 description: | - <%- if NUM_HPM_COUNTERS > 16 -%> + <%- if COUNTINHIBIT_EN[19] -%> When set, `hpmcounter19.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter19 is not implemented, this field is read-only zero. @@ -263,7 +263,7 @@ mcountinhibit: HPM20: location: 20 description: | - <%- if NUM_HPM_COUNTERS > 17 -%> + <%- if COUNTINHIBIT_EN[20] -%> When set, `hpmcounter20.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter20 is not implemented, this field is read-only zero. @@ -275,7 +275,7 @@ mcountinhibit: HPM21: location: 21 description: | - <%- if NUM_HPM_COUNTERS > 18 -%> + <%- if COUNTINHIBIT_EN[21] -%> When set, `hpmcounter21.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter21 is not implemented, this field is read-only zero. @@ -287,7 +287,7 @@ mcountinhibit: HPM22: location: 22 description: | - <%- if NUM_HPM_COUNTERS > 19 -%> + <%- if COUNTINHIBIT_EN[22] -%> When set, `hpmcounter22.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter22 is not implemented, this field is read-only zero. @@ -299,7 +299,7 @@ mcountinhibit: HPM23: location: 23 description: | - <%- if NUM_HPM_COUNTERS > 20 -%> + <%- if COUNTINHIBIT_EN[23] -%> When set, `hpmcounter23.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter23 is not implemented, this field is read-only zero. @@ -311,7 +311,7 @@ mcountinhibit: HPM24: location: 24 description: | - <%- if NUM_HPM_COUNTERS > 21 -%> + <%- if COUNTINHIBIT_EN[24] -%> When set, `hpmcounter24.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter24 is not implemented, this field is read-only zero. @@ -323,7 +323,7 @@ mcountinhibit: HPM25: location: 25 description: | - <%- if NUM_HPM_COUNTERS > 22 -%> + <%- if COUNTINHIBIT_EN[25] -%> When set, `hpmcounter25.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter25 is not implemented, this field is read-only zero. @@ -335,7 +335,7 @@ mcountinhibit: HPM26: location: 26 description: | - <%- if NUM_HPM_COUNTERS > 23 -%> + <%- if COUNTINHIBIT_EN[26] -%> When set, `hpmcounter26.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter26 is not implemented, this field is read-only zero. @@ -347,7 +347,7 @@ mcountinhibit: HPM27: location: 27 description: | - <%- if NUM_HPM_COUNTERS > 24 -%> + <%- if COUNTINHIBIT_EN[27] -%> When set, `hpmcounter27.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter27 is not implemented, this field is read-only zero. @@ -359,7 +359,7 @@ mcountinhibit: HPM28: location: 28 description: | - <%- if NUM_HPM_COUNTERS > 25 -%> + <%- if COUNTINHIBIT_EN[28] -%> When set, `hpmcounter28.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter28 is not implemented, this field is read-only zero. @@ -371,7 +371,7 @@ mcountinhibit: HPM29: location: 29 description: | - <%- if NUM_HPM_COUNTERS > 26 -%> + <%- if COUNTINHIBIT_EN[29] -%> When set, `hpmcounter29.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter29 is not implemented, this field is read-only zero. @@ -383,7 +383,7 @@ mcountinhibit: HPM30: location: 30 description: | - <%- if NUM_HPM_COUNTERS > 27 -%> + <%- if COUNTINHIBIT_EN[30] -%> When set, `hpmcounter30.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter30 is not implemented, this field is read-only zero. @@ -395,7 +395,7 @@ mcountinhibit: HPM31: location: 31 description: | - <%- if NUM_HPM_COUNTERS > 28 -%> + <%- if COUNTINHIBIT_EN[31] -%> When set, `hpmcounter31.COUNT` stops counting in all privilege modes. <%- else -%> Since hpmcounter31 is not implemented, this field is read-only zero. diff --git a/arch/csr/hstatus.yaml b/arch/csr/hstatus.yaml index 3edd63c22..94c2b339a 100644 --- a/arch/csr/hstatus.yaml +++ b/arch/csr/hstatus.yaml @@ -22,6 +22,7 @@ hstatus: Determines the effective XLEN in VS-mode. Valid values are: + [separator="!"] !=== ! Value ! VSXLEN @@ -87,7 +88,7 @@ hstatus: The `wfi` instruction is also affected by `mstatus.TW`, as shown below: - [%autowidth,%footer] + [separator="!",%autowidth,%footer] !=== .2+! [.rotate]#`mstatus.TW`# .2+! [.rotate]#`hstatus.VTW`# 4+^.>! `wfi` behavior h! HS-mode h! U-mode h! VS-mode h! VU-mode diff --git a/arch/csr/mcause.yaml b/arch/csr/mcause.yaml index 942974902..7cd9e71bf 100644 --- a/arch/csr/mcause.yaml +++ b/arch/csr/mcause.yaml @@ -1,6 +1,5 @@ # yaml-language-server: $schema=../../schemas/csr_schema.json -# <%- max_code = [interrupt_codes.keys.max, exception_codes.keys.max].max -%> mcause: long_name: Machine Cause @@ -55,16 +54,18 @@ mcause: <%- end -%> Valid interrupt codes are: + [separator="!"] !=== - <%- Hash[interrupt_codes.sort_by{ |num, _name| num }].each do |num, name| -%> - ! <%= num %> ! <%= name %> + <%- interrupt_codes.sort_by{ |code| code.num }.each do |code| -%> + ! <%= code.num %> ! <%= code.name %> <%- end -%> !=== Valid exception codes are: + [separator="!"] !=== - <%- Hash[exception_codes.sort_by{ |num, _name| num }].each do |num, name| -%> - ! <%= num %> ! <%= name %> + <%- exception_codes.sort_by{ |code| code.num }.each do |code| -%> + ! <%= code.num %> ! <%= code.name %> <%- end -%> !=== type: RW-RH diff --git a/arch/csr/medeleg.yaml b/arch/csr/medeleg.yaml index f29901c31..d6c92e0f0 100644 --- a/arch/csr/medeleg.yaml +++ b/arch/csr/medeleg.yaml @@ -48,7 +48,7 @@ medeleg: The handling mode is determined as follows: <%- if ext?(:H) -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.IAM`# .2+! [.rotate]#`hedeleg.IAM`# 4+^.>! Current Mode .>h! `M-mode` .>h! `HS-mode` .>h! `VS-mode` .>h! `VU-mode` @@ -59,7 +59,7 @@ medeleg: ! 1 ! 1 ! M ! HS ! VS ! VS !=== <%- else -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.IAM`# 2+^.>! Current Mode .>h! `M-mode` .>h! `S-mode` @@ -85,7 +85,7 @@ medeleg: The handling mode is determined as follows: <%- if ext?(:H) -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.IAF`# .2+! [.rotate]#`hedeleg.IAF`# 4+^.>! Current Mode .>h! `M-mode` .>h! `HS-mode` .>h! `VS-mode` .>h! `VU-mode` @@ -96,7 +96,7 @@ medeleg: ! 1 ! 1 ! M ! HS ! VS ! VS !=== <%- else -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.IAF`# 2+^.>! Current Mode .>h! `M-mode` .>h! `S-mode` @@ -123,7 +123,7 @@ medeleg: The handling mode is determined as follows: <%- if ext?(:H) -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.II`# .2+! [.rotate]#`hedeleg.II`# 4+^.>! Current Mode .>h! `M-mode` .>h! `HS-mode` .>h! `VS-mode` .>h! `VU-mode` @@ -134,7 +134,7 @@ medeleg: ! 1 ! 1 ! M ! HS ! VS ! VS !=== <%- else -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.II`# 2+^.>! Current Mode .>h! `M-mode` .>h! `S-mode` @@ -160,7 +160,7 @@ medeleg: The handling mode is determined as follows: <%- if ext?(:H) -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.B`# .2+! [.rotate]#`hedeleg.B`# 4+^.>! Current Mode .>h! `M-mode` .>h! `HS-mode` .>h! `VS-mode` .>h! `VU-mode` @@ -171,7 +171,7 @@ medeleg: ! 1 ! 1 ! M ! HS ! VS ! VS !=== <%- else -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.B`# 2+^.>! Current Mode .>h! `M-mode` .>h! `S-mode` @@ -202,7 +202,7 @@ medeleg: The handling mode is determined as follows: <%- if ext?(:H) -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.LAM`# .2+! [.rotate]#`hedeleg.LAM`# 4+^.>! Current Mode .>h! `M-mode` .>h! `HS-mode` .>h! `VS-mode` .>h! `VU-mode` @@ -213,7 +213,7 @@ medeleg: ! 1 ! 1 ! M ! HS ! VS ! VS !=== <%- else -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.LAM`# 2+^.>! Current Mode .>h! `M-mode` .>h! `S-mode` @@ -240,7 +240,7 @@ medeleg: The handling mode is determined as follows: <%- if ext?(:H) -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.LAF`# .2+! [.rotate]#`hedeleg.LAF`# 4+^.>! Current Mode .>h! `M-mode` .>h! `HS-mode` .>h! `VS-mode` .>h! `VU-mode` @@ -251,7 +251,7 @@ medeleg: ! 1 ! 1 ! M ! HS ! VS ! VS !=== <%- else -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.LAF`# 2+^.>! Current Mode .>h! `M-mode` .>h! `S-mode` @@ -283,7 +283,7 @@ medeleg: The handling mode is determined as follows: <%- if ext?(:H) -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.SAM`# .2+! [.rotate]#`hedeleg.SAM`# 4+^.>! Current Mode .>h! `M-mode` .>h! `HS-mode` .>h! `VS-mode` .>h! `VU-mode` @@ -294,7 +294,7 @@ medeleg: ! 1 ! 1 ! M ! HS ! VS ! VS !=== <%- else -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.SAM`# 2+^.>! Current Mode .>h! `M-mode` .>h! `S-mode` @@ -321,7 +321,7 @@ medeleg: The handling mode is determined as follows: <%- if ext?(:H) -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.SAF`# .2+! [.rotate]#`hedeleg.SAF`# 4+^.>! Current Mode .>h! `M-mode` .>h! `HS-mode` .>h! `VS-mode` .>h! `VU-mode` @@ -332,7 +332,7 @@ medeleg: ! 1 ! 1 ! M ! HS ! VS ! VS !=== <%- else -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.SAF`# 2+^.>! Current Mode .>h! `M-mode` .>h! `S-mode` @@ -358,7 +358,7 @@ medeleg: The handling mode is determined as follows: <%- if ext?(:H) -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.EU`# .2+! [.rotate]#`hedeleg.EU`# 4+^.>! Current Mode .>h! `M-mode` .>h! `HS-mode` .>h! `VS-mode` .>h! `VU-mode` @@ -369,7 +369,7 @@ medeleg: ! 1 ! 1 ! M ! HS ! VS ! VS !=== <%- else -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.EU`# 2+^.>! Current Mode .>h! `M-mode` .>h! `S-mode` @@ -395,7 +395,7 @@ medeleg: The handling mode is determined as follows: - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.ES`# 2+^.>! Current Mode .>h! `M-mode` .>h! `(H)S-mode` @@ -419,7 +419,7 @@ medeleg: The handling mode is determined as follows: - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.EVS`# 2+^.>! Current Mode .>h! `M-mode` .>h! `(H)S-mode` @@ -455,7 +455,7 @@ medeleg: The handling mode is determined as follows: <%- if ext?(:H) -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.IPF`# .2+! [.rotate]#`hedeleg.IPF`# 4+^.>! Current Mode .>h! `M-mode` .>h! `HS-mode` .>h! `VS-mode` .>h! `VU-mode` @@ -466,7 +466,7 @@ medeleg: ! 1 ! 1 ! M ! HS ! VS ! VS !=== <%- else -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.IPF`# 2+^.>! Current Mode .>h! `M-mode` .>h! `S-mode` @@ -492,7 +492,7 @@ medeleg: The handling mode is determined as follows: <%- if ext?(:H) -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.LPF`# .2+! [.rotate]#`hedeleg.LPF`# 4+^.>! Current Mode .>h! `M-mode` .>h! `HS-mode` .>h! `VS-mode` .>h! `VU-mode` @@ -503,7 +503,7 @@ medeleg: ! 1 ! 1 ! M ! HS ! VS ! VS !=== <%- else -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.LPF`# 2+^.>! Current Mode .>h! `M-mode` .>h! `S-mode` @@ -530,7 +530,7 @@ medeleg: The handling mode is determined as follows: <%- if ext?(:H) -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.SPF`# .2+! [.rotate]#`hedeleg.SPF`# 4+^.>! Current Mode .>h! `M-mode` .>h! `HS-mode` .>h! `VS-mode` .>h! `VU-mode` @@ -541,7 +541,7 @@ medeleg: ! 1 ! 1 ! M ! HS ! VS ! VS !=== <%- else -%> - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.LPF`# 2+^.>! Current Mode .>h! `M-mode` .>h! `S-mode` @@ -566,7 +566,7 @@ medeleg: The handling mode is determined as follows: - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.IGPF`# 2+^.>! Current Mode .>h! `M-mode` .>h! `(H)S-mode` @@ -591,7 +591,7 @@ medeleg: The handling mode is determined as follows: - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.LGPF`# 2+^.>! Current Mode .>h! `M-mode` .>h! `(H)S-mode` @@ -617,7 +617,7 @@ medeleg: The handling mode is determined as follows: - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.VI`# 2+^.>! Current Mode .>h! `M-mode` .>h! `(H)S-mode` @@ -643,7 +643,7 @@ medeleg: The handling mode is determined as follows: - [%autowidth, %footer] + [separator="!",%autowidth, %footer] !=== .2+! [.rotate]#`medeleg.SGPF`# 2+^.>! Current Mode .>h! `M-mode` .>h! `(H)S-mode` diff --git a/arch/csr/menvcfg.yaml b/arch/csr/menvcfg.yaml index 1c8b54f25..06b8116fa 100644 --- a/arch/csr/menvcfg.yaml +++ b/arch/csr/menvcfg.yaml @@ -27,7 +27,7 @@ menvcfg: [[menvcfg-FIOM]] .Modified interpretation of FENCE predecessor and successor sets for modes less privileged than M when FIOM=1. - [%autowidth,float="center",align="center",cols="^,<",options="header"] + [separator="!",%autowidth,float="center",align="center",cols="^,<",options="header"] !=== !Instruction bit |Meaning when set !PI + @@ -253,7 +253,7 @@ menvcfg: FENCE instructions ordering I/O regions also implicitly order memory regions when executed in any mode less privileged than M-mode. - [%autowidth,float="center",align="center",cols="^,<",options="header"] + [separator="!",%autowidth,float="center",align="center",cols="^,<",options="header"] !=== !Instruction bit !Meaning when set !PI + diff --git a/arch/csr/mtval.yaml b/arch/csr/mtval.yaml index d2222d5c5..089746a07 100644 --- a/arch/csr/mtval.yaml +++ b/arch/csr/mtval.yaml @@ -15,6 +15,7 @@ mtval: The values are: + [separator="!"] !=== ! Exception type ! Value diff --git a/arch/csr/satp.yaml b/arch/csr/satp.yaml index 439a270bc..3dae855db 100644 --- a/arch/csr/satp.yaml +++ b/arch/csr/satp.yaml @@ -17,7 +17,7 @@ satp: Controls the current translation mode according to the table below. - [%autowidth] + [separator="!",%autowidth] !=== ! Value ! Name ! Description diff --git a/arch/csr/scause.yaml b/arch/csr/scause.yaml index 50c405490..5d693596d 100644 --- a/arch/csr/scause.yaml +++ b/arch/csr/scause.yaml @@ -1,6 +1,5 @@ # yaml-language-server: $schema=../../schemas/csr_schema.json -# <%-max_code = [interrupt_codes.keys.max, exception_codes.keys.max].max -%> scause: long_name: Supervisor Cause @@ -56,16 +55,18 @@ scause: <%- end -%> Valid interrupt codes are: + [separator="!"] !=== - <%- Hash[interrupt_codes.sort_by { |num, _name| num }].each do |num, name| -%> - ! <%= num %> ! <%= name %> + <%- interrupt_codes.sort_by { |code| code.num }.each do |code| -%> + ! <%= code.num %> ! <%= code.name %> <%- end -%> !=== Valid exception codes are: + [separator="!"] !=== - <%- Hash[exception_codes.sort_by { |num, _name| num }].each do |num, name| -%> - ! <%= num %> ! <%= name %> + <%- exception_codes.sort_by { |code| code.num }.each do |code| -%> + ! <%= code.num %> ! <%= code.name %> <%- end -%> !=== type: RW-RH diff --git a/arch/csr/senvcfg.yaml b/arch/csr/senvcfg.yaml index 3f08d6776..a06a95d35 100644 --- a/arch/csr/senvcfg.yaml +++ b/arch/csr/senvcfg.yaml @@ -22,7 +22,7 @@ senvcfg: * `1`: The instruction is executed To summarize access: - [%autowidth] + [separator="!",%autowidth] !=== ! `menvcfg.CBZE` ! `senvcfg.CBZE` behavior @@ -53,7 +53,7 @@ senvcfg: * `1`: The instruction is executed To summarize access: - [%autowidth] + [separator="!",%autowidth] !=== ! `menvcfg.CBCFE` ! `senvcfg.CBCFE` behavior @@ -75,7 +75,7 @@ senvcfg: This field has restricted values based on the value of `menvcfg.CBIE`. When an invalid value is written, it is ignored and the field remains unchanged. - [%autowidth,cols=",.>"] + [separator="!",%autowidth,cols=",.>"] !=== ! [.rotate]#`menvcfg.CBIE`# ! Valid values of `senvcfg.CBIE` @@ -115,7 +115,7 @@ senvcfg: FENCE instructions ordering I/O regions also implicitly order memory regions when executed in U-mode as follows: - [%autowidth,float="center",align="center",cols="^,<",options="header"] + [separator="!",%autowidth,float="center",align="center",cols="^,<",options="header"] !=== !Instruction bit !Meaning when set !PI + diff --git a/arch/csr/sip.yaml b/arch/csr/sip.yaml index b45da8b75..73512e9af 100644 --- a/arch/csr/sip.yaml +++ b/arch/csr/sip.yaml @@ -44,7 +44,7 @@ sip: <%- end -%> To summarize: - [%autowidth] + [separator="!",%autowidth] !=== ! `mideleg.SSI` ! `sip.SSIP` behavior @@ -77,7 +77,7 @@ sip: <%- end -%> To summarize: - [%autowidth] + [separator="!",%autowidth] !=== ! `mideleg.STI` ! `sip.STIP` behavior @@ -102,7 +102,7 @@ sip: Otherwise, `sip.SEIP` is a read-only view of `mip.SEIP`. To summarize: - [%autowidth] + [separator="!",%autowidth] !=== ! `mideleg.SEI` ! `sip.SEIP` behavior @@ -131,7 +131,7 @@ sip: Software writes 0 to `sip.LCOFIP` to clear the pending interrupt. To summarize: - [%autowidth] + [separator="!",%autowidth] !=== ! `mideleg.LCOFI` ! `sip.LCOFIP` behavior diff --git a/arch/csr/stval.yaml b/arch/csr/stval.yaml index 52be3f540..879579cf6 100644 --- a/arch/csr/stval.yaml +++ b/arch/csr/stval.yaml @@ -15,6 +15,7 @@ stval: The values are: + [separator="!"] !=== ! Exception type ! Value diff --git a/arch/csr/stvec.yaml b/arch/csr/stvec.yaml index bd5697870..b3c80bc2e 100644 --- a/arch/csr/stvec.yaml +++ b/arch/csr/stvec.yaml @@ -1,7 +1,5 @@ # yaml-language-server: $schema=../../schemas/csr_schema.json -# <%- va_size = ext?(:Sv57) ? 57 : (ext?(:Sv48) ? 49 :39) -%> - stvec: long_name: Supervisor Trap Vector address: 0x105 @@ -13,6 +11,7 @@ stvec: BASE: location: 63-2 description: | + <%- va_size = ext?(:Sv57) ? 57 : (ext?(:Sv48) ? 49 :39) -%> Bit 63:0 of the virtual address of the exception vector for any trap taken into S-mode. If the base address is written with a non-cannonical address (_i.e._, bits 63:<%= va_size %> do not match bit <%= va_size-1 %>), diff --git a/arch/csr/time.yaml b/arch/csr/time.yaml index 29f2dd9a9..f6c312059 100644 --- a/arch/csr/time.yaml +++ b/arch/csr/time.yaml @@ -27,8 +27,43 @@ time: COUNT: location: 63-0 description: | - Alias of the memory-mapped M-mode CSR `mtime`. - Reports the current wall-clock time from the timer device. type: RO-H reset_value: UNDEFINED_LEGAL + sw_read(): | + # access is determined by *counteren CSRs + if (mode() == PrivilegeMode::S) { + # S-mode is present -> + # mcounteren determines access in S-mode + if (CSR[mcounteren].TM == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::U) { + if (CSR[misa].S == 1'b1) { + # S-mode is present -> + # mcounteren and scounteren together determine access in U-mode + if ((CSR[mcounteren].TM & CSR[scounteren].TM) == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].TM == 1'b0) { + # S-mode is not present -> + # mcounteren determines access in U-mode + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VS) { + # access in VS mode + if (CSR[hcounteren].TM == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].TM == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].TM & CSR[scounteren].TM) == 1'b0) && (CSR[mcounteren].IR == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].TM == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_mtime(); diff --git a/arch/csr/vscause.yaml b/arch/csr/vscause.yaml index d0193b878..da8c5c577 100644 --- a/arch/csr/vscause.yaml +++ b/arch/csr/vscause.yaml @@ -1,7 +1,5 @@ # yaml-language-server: $schema=../../schemas/csr_schema.json -# <%- max_code = [interrupt_codes.keys.max, exception_codes.keys.max].max -%> - vscause: long_name: Virtual Supervisor Cause address: 0x242 @@ -56,16 +54,18 @@ vscause: <%- end -%> Valid interrupt codes are: + [separator="!"] !=== - <%- Hash[interrupt_codes.sort_by { |num, _name| num }].each do |num, name| -%> - ! <%= num %> ! <%= name %> + <%- interrupt_codes.sort_by { |code| code.num }.each do |code| -%> + ! <%= code.num %> ! <%= code.name %> <%- end -%> !=== Valid exception codes are: + [separator="!"] !=== - <%- Hash[exception_codes.sort_by { |num, _name| num }].each do |num, name| -%> - ! <%= num %> ! <%= name %> + <%- exception_codes.sort_by { |code| code.num }.each do |code| -%> + ! <%= code.num %> ! <%= code.name %> <%- end -%> !=== type: RW-RH diff --git a/arch/csr/vstval.yaml b/arch/csr/vstval.yaml index a02d7ea61..c42ca1721 100644 --- a/arch/csr/vstval.yaml +++ b/arch/csr/vstval.yaml @@ -17,6 +17,7 @@ vstval: The values are: + [separator="!"] !=== ! Exception type ! Value diff --git a/arch/csr/vstvec.yaml b/arch/csr/vstvec.yaml index a3b905529..88f491128 100644 --- a/arch/csr/vstvec.yaml +++ b/arch/csr/vstvec.yaml @@ -1,7 +1,5 @@ # yaml-language-server: $schema=../../schemas/csr_schema.json -# <%- va_size = ext?(:Sv57) ? 57 : (ext?(:Sv48) ? 49 :39) -%> - vstvec: long_name: Supervisor Trap Vector address: 0x205 @@ -14,6 +12,7 @@ vstvec: BASE: location: 63-2 description: | + <%- va_size = ext?(:Sv57) ? 57 : (ext?(:Sv48) ? 49 :39) -%> Bit 63:0 of the virtual address of the exception vector for any trap taken into VS-mode. If the base address is written with a non-cannonical address (_i.e._, bits 63:<%= va_size %> do not match bit <%= va_size-1 %>), diff --git a/arch/ext/H.yaml b/arch/ext/H.yaml index cfd3e2f60..a82f83398 100644 --- a/arch/ext/H.yaml +++ b/arch/ext/H.yaml @@ -307,3 +307,19 @@ H: When false `vstval` is written with 0 when an `IllegalInstruction` exception occurs. schema: type: boolean + HCOUNTENABLE_EN: + description: | + Indicates which counters can delegated via `hcounteren` + + An unimplemented counter cannot be specified, i.e., if + HPM_COUNTER_EN[3] is false, it would be illegal to set + HCOUNTENABLE_EN[3] to true. + + HCOUNTENABLE_EN[0:2] must all be false if `Zicntr` is not implemented. + HCOUNTENABLE_EN[3:31] must all be false if `Zihpm` is not implemented. + schema: + type: array + items: + type: boolean + maxItems: 32 + minItems: 32 \ No newline at end of file diff --git a/arch/ext/I.yaml b/arch/ext/I.yaml index e4441efea..1ca3d962c 100644 --- a/arch/ext/I.yaml +++ b/arch/ext/I.yaml @@ -146,25 +146,19 @@ I: type: boolean maxItems: 32 minItems: 32 - COUNTENABLE_EN: + MCOUNTENABLE_EN: description: | Indicates which counters can delegated via `mcounteren` An unimplemented counter cannot be specified, i.e., if HPM_COUNTER_EN[3] is false, it would be illegal to set - COUNTENABLE_EN[3] to true. + MCOUNTENABLE_EN[3] to true. - COUNTENABLE_EN[1] can never be true, since it corresponds to `mcounteren.TM`, - which is always read-only-0. - - COUNTENABLE_EN[3:31] must all be false if `Zihpm` is not implemented. + MCOUNTENABLE_EN[0:2] must all be false if `Zicntr` is not implemented. + MCOUNTENABLE_EN[3:31] must all be false if `Zihpm` is not implemented. schema: type: array items: - - type: boolean - - const: false - - type: boolean - additionalItems: type: boolean maxItems: 32 minItems: 32 @@ -307,6 +301,7 @@ I: Therefore, pmp registers will behave as follows according to NUN_PMP_ENTRIES: + [separator="!"] !=== ! NUM_PMP_ENTRIES ! pmpaddr<0-15> / pmpcfg<0-3> ! pmpaddr<16-63> / pmpcfg<4-15> ! 0 ! N ! N @@ -364,10 +359,13 @@ I: description: | Endianess of data in M-mode. Can be one of: - * little: M-mode data is always little endian - * big: M-mode data is always big endian - * dynamic: M-mode data can be either little or big endian, - depending on the CSR field `mstatus.MBE` + [separator="!"] + !=== + h! little ! M-mode data is always little endian + h! big ! M-mode data is always big endian + h! dynamic ! M-mode data can be either little or big endian, + depending on the CSR field `mstatus.MBE` + !=== schema: type: string enum: [little, big, dynamic] \ No newline at end of file diff --git a/arch/ext/S.yaml b/arch/ext/S.yaml index 0e63da4f4..6817d8b47 100644 --- a/arch/ext/S.yaml +++ b/arch/ext/S.yaml @@ -170,4 +170,20 @@ S: Must be greater than or equal to _max_(`PHYS_ADDR_WIDTH`, `VA_SIZE`) schema: type: integer - maximum: 0xffffffffffffffff \ No newline at end of file + maximum: 0xffffffffffffffff + SCOUNTENABLE_EN: + description: | + Indicates which counters can delegated via `scounteren` + + An unimplemented counter cannot be specified, i.e., if + HPM_COUNTER_EN[3] is false, it would be illegal to set + SCOUNTENABLE_EN[3] to true. + + SCOUNTENABLE_EN[0:2] must all be false if `Zicntr` is not implemented. + SCOUNTENABLE_EN[3:31] must all be false if `Zihpm` is not implemented. + schema: + type: array + items: + type: boolean + maxItems: 32 + minItems: 32 \ No newline at end of file diff --git a/arch/isa/builtin_functions.idl b/arch/isa/builtin_functions.idl index 7e76efda0..47226e533 100644 --- a/arch/isa/builtin_functions.idl +++ b/arch/isa/builtin_functions.idl @@ -39,6 +39,13 @@ builtin function read_mcycle { } } +builtin function read_mtime { + returns Bits<64> + description { + Return the current value of the real time device. + } +} + builtin function sw_write_mcycle { returns Bits<64> arguments Bits<64> value diff --git a/backends/cfg_html_doc/adoc_gen.rake b/backends/cfg_html_doc/adoc_gen.rake index 81d9165b8..36cbd5d00 100644 --- a/backends/cfg_html_doc/adoc_gen.rake +++ b/backends/cfg_html_doc/adoc_gen.rake @@ -50,7 +50,6 @@ require "ruby-prof" File.write(path, arch_def.find_replace_links(erb.result(binding))) end when "func" - isa_def = arch_def.global_ast global_symtab = arch_def.sym_table path = dir_path / "funcs.adoc" puts " Generating #{path}" @@ -101,7 +100,7 @@ require "ruby-prof" lines << " * `#{inst.name}` #{inst.long_name}" end when "func" - puts "Generting functino list" + puts "Generting function list" arch_def.implemented_functions.each do |func| lines << " * `#{func.name}`" end diff --git a/backends/cfg_html_doc/html_gen.rake b/backends/cfg_html_doc/html_gen.rake index e7086239c..24b1f3b69 100644 --- a/backends/cfg_html_doc/html_gen.rake +++ b/backends/cfg_html_doc/html_gen.rake @@ -214,6 +214,13 @@ rule %r{#{$root}/gen/cfg_html_doc/.*/antora/playbook.yaml} => proc { |tname| color: white; font-weight: bold; } + + .csr-field-info { + margin-left: 1em; + padding: 1em; + border-radius: 25px; + border: 2px solid; + } PLAYBOOK end diff --git a/backends/cfg_html_doc/templates/config.adoc.erb b/backends/cfg_html_doc/templates/config.adoc.erb index a61122ddd..021aa3375 100644 --- a/backends/cfg_html_doc/templates/config.adoc.erb +++ b/backends/cfg_html_doc/templates/config.adoc.erb @@ -11,7 +11,7 @@ == Parameters -<%- arch_def.params.each do |param| -%> +<%- arch_def.params.sort_by { |param| param.name }.each do |param| -%> === *<%= param.name %>* [cols="1,4,1"] diff --git a/backends/cfg_html_doc/templates/csr.adoc.erb b/backends/cfg_html_doc/templates/csr.adoc.erb index 325643ae1..d1a8a69d3 100644 --- a/backends/cfg_html_doc/templates/csr.adoc.erb +++ b/backends/cfg_html_doc/templates/csr.adoc.erb @@ -14,10 +14,11 @@ h| CSR Address | <%= "0x#{csr.address.to_s(16)}" %> <%- if csr.priv_mode == 'VS' -%> h| Virtual CSR Address | <%= "0x#{csr.virtual_address.to_s(16)}" %> <%- end -%> +h| Defining extension | <%= csr.defined_by.map(&:to_s).join(", ") %> <%- if csr.dynamic_length?(arch_def) -%> h| Length | <%= csr.length_pretty(arch_def) %> <%- else -%> -h| Length | <%= csr.length_pretty(arch_def) %>-bit +h| Length | <%= csr.length_pretty(arch_def) %> <%- end -%> h| Privilege Mode | <%= csr.priv_mode %> |=== @@ -57,7 +58,7 @@ This CSR format changes dynamically. |Name | Location | Type | Reset Value <%- csr.implemented_fields(arch_def).each do |field| -%> -| xref:<%=csr.name%>-<%=field.name%>-def[`<%= field.name %>`] +| `xref:<%=csr.name%>-<%=field.name%>-def[<%= field.name %>]` | <%= field.location_pretty(arch_def) %> | <%= field.type(arch_def) %> | <%= field.reset_value(arch_def) %> @@ -75,13 +76,13 @@ This CSR has no fields. However, it must still exist (not cause an `Illegal Inst [[<%=csr.name%>-<%=field.name%>-def]] === `<%= field.name %>` -[example] -**** +[.csr-field-info] +-- Location:: -<%= field.location_pretty(arch_def) %> +`<%=field.csr.name%>[<%= field.location_pretty(arch_def) %>]` Description:: -<%= field.description %> +<%= arch_def.render_erb(field.description).gsub("\n\n", "\n+\n") %> Type:: [%autowidth] @@ -93,29 +94,40 @@ Type:: Reset value:: <%= field.reset_value(arch_def) %> -**** +<%- if field.has_custom_sw_write? -%> +Softare write:: +This field has special behavior when written by software (_e.g._, through `csrrw`). ++ +When software tries to write `csr_value`, the field will be written with the return value of the function below. ++ +<%- if arch_def.multi_xlen? && csr.defined_in_all_bases? && field.defined_in_all_bases? -%> +[tabs] +==== +RV32:: ++ +[source,idl,subs="specialchars,macros"] +---- +<%= field.pruned_sw_write_ast(arch_def, 32).gen_adoc %> +---- +RV64:: ++ +[source,idl,subs="specialchars,macros"] +---- +<%= field.pruned_sw_write_ast(arch_def, 64).gen_adoc %> +---- +<%- else -%> +<%- xlen = !arch_def.multi_xlen? ? arch_def.mxlen : (!csr.defined_in_all_bases? ? csr.base : field.base) -%> +[source,idl,subs="specialchars,macros"] +---- +<%= field.pruned_sw_write_ast(arch_def, xlen).gen_adoc %> +---- <%- end -%> <%- end -%> -<%- if csr.fields.map(&:has_custom_sw_write?).any? -%> -== Software write - -This CSR may store a value that is different from what software attempts to write. +-- -When a software write occurs (_e.g._, through `csrrw`), the following determines the -written value: - -[idl] ----- -<%- csr.fields.each do |field| -%> -<%- if field.has_custom_sw_write? -%> -<%= field.name %> = <%= field["sw_write(csr_value)"] %> -<%- else -%> -<%= field.name %> = csr_value.<%= field.name %> -<%- end -%> <%- end -%> ----- <%- end -%> <%- if csr.has_custom_sw_read? -%> diff --git a/backends/cfg_html_doc/templates/ext.adoc.erb b/backends/cfg_html_doc/templates/ext.adoc.erb index 40984e6f8..79fc64dc1 100644 --- a/backends/cfg_html_doc/templates/ext.adoc.erb +++ b/backends/cfg_html_doc/templates/ext.adoc.erb @@ -4,12 +4,6 @@ Implemented Version:: <%= ext_version.version %> -<%- if !ext.implies.empty? -%> -This extension implies the following extension(s): - -`<%= ext.name %>` => <%= ext.implies.map { |e| "`#{e.name}`, version #{e.version}" }.join(", ") %> -<%- end -%> - == Versions <%- ext.versions.each do |v| -%> @@ -51,3 +45,18 @@ The following instructions are added by this extension in the <%= ext.arch_def.n <%- end -%> |=== <%- end -%> + +<%- unless ext.params.empty? -%> +== Parameters + +This extension has the following implementation options: + +<%- ext.params.sort_by { |p| p.name }.each do |param| -%> +<%= param.name %>:: ++ +-- +<%= param.desc %> +-- +<%- end -%> + +<%- end -%> \ No newline at end of file diff --git a/backends/cfg_html_doc/templates/func.adoc.erb b/backends/cfg_html_doc/templates/func.adoc.erb index 86fb04b8d..83eb37aaf 100644 --- a/backends/cfg_html_doc/templates/func.adoc.erb +++ b/backends/cfg_html_doc/templates/func.adoc.erb @@ -23,14 +23,14 @@ Original:: + [subs="specialchars,macros"] ---- -<%= body_ast.gen_adoc.gsub('(', 'pass:[(]') %> +<%= body_ast.gen_adoc %> ---- Pruned:: + [subs="specialchars,macros"] ---- -<%= body_ast.prune(global_symtab.deep_clone).gen_adoc.gsub('(', 'pass:[(]') %> +<%= body_ast.prune(global_symtab.deep_clone).gen_adoc %> ---- ==== <%- end -%> diff --git a/backends/ext_pdf_doc/idl_lexer.rb b/backends/ext_pdf_doc/idl_lexer.rb index 3dab3f2d4..c9998e930 100644 --- a/backends/ext_pdf_doc/idl_lexer.rb +++ b/backends/ext_pdf_doc/idl_lexer.rb @@ -13,7 +13,9 @@ class Idl < RegexLexer id = /[a-zA-Z_][a-zA-Z0-9_]*/ def self.keywords - @keywords ||= Set.new %w[ + return @keywords unless @keywords.nil? + + @keywords = Set.new %w[ if else for return returns arguments description body function builtin enum bitfield ] end @@ -39,7 +41,7 @@ def self.keywords_type rule %r/0x[0-9a-f]+[lu]*/i, Num::Hex rule %r/0[0-7]+[lu]*/i, Num::Oct rule %r{\d+}, Num::Integer - rule %r{(?:true|false|\$encoding|\$pc)}, Name::Builtin + rule %r{(?:true|false|\$encoding|\$pc|\$signed|\$bits)}, Name::Builtin rule %r{[.,;:\[\]\(\)\}\{]}, Punctuation rule %r([~!%^&*+=\|?:<>/-]), Operator rule id do |m| diff --git a/backends/ext_pdf_doc/templates/ext_pdf.adoc.erb b/backends/ext_pdf_doc/templates/ext_pdf.adoc.erb index 5db3bb6ac..5acaf8455 100644 --- a/backends/ext_pdf_doc/templates/ext_pdf.adoc.erb +++ b/backends/ext_pdf_doc/templates/ext_pdf.adoc.erb @@ -146,7 +146,7 @@ The following versions have been defined: -- Version:: <%= version["version"] %> State:: <%= version["state"] %> -<%- if version.key?("ratification_date") -%> +<%- if version.key?("ratification_date") && !version["ratification_date"].nil? -%> Ratification Date:: <%= version["ratification_date"] %> <%- end -%> <%- if version.key?("url") -%> @@ -169,21 +169,177 @@ Changes:: <%- end -%> <%- end -%> +<%- unless ext.csrs.empty? -%> +<<< +== CSR summary + +The following <%= ext.csrs.size %> are added by this extension. + +[%autowidth] +|=== +| RV32 | RV64 | CSR | Name | <%= ext.versions.map { |v| "v#{v["version"]}" }.join(" | ") %> + +<%- ext.csrs.each do |csr| -%> +| <%= csr.defined_in_base32? ? "✓" : "" %> +| <%= csr.defined_in_base64? ? "✓" : "" %> +| xref:csrs-<%= csr.name.gsub('.', '_') %>[<%= csr.name %>] +| <%= csr.long_name %> +| <%= ext.versions.map { |v| csr.defined_by?(ext.name, v["version"]) ? "✓" : "" }.join(" | ") %> +<%- end -%> + +|=== + +<<< +[#csrs,reftext="CSRs (in alphabetical order)"] +== Csrs (in alphabetical order) + +<%- ext.csrs.each do |csr| -%> +<<< +[#csrs-<%= csr.name.gsub('.', '_') %>,reftext=<%= csr.name %>] +=== <%= csr.name %> + +*<%= csr.long_name %>* + +<%= arch_def.render_erb(csr.description) %> + +==== Attributes +[%autowidth] +|=== +h| CSR Address | <%= "0x#{csr.address.to_s(16)}" %> +<%- if csr.priv_mode == 'VS' -%> +h| Virtual CSR Address | <%= "0x#{csr.virtual_address.to_s(16)}" %> +<%- end -%> +<%- if csr.dynamic_length?(arch_def) -%> +h| Length | <%= csr.length_pretty(arch_def) %> +<%- else -%> +h| Length | <%= csr.length_pretty(arch_def) %>-bit +<%- end -%> +h| Privilege Mode | <%= csr.priv_mode %> +|=== + +==== Format +<%- unless csr.dynamic_length?(arch_def) || csr.fields.any? { |f| f.dynamic_location?(arch_def) } -%> +<%# CSR has a known static length, so there is only one format to display -%> +.<%= csr.name %> format +[wavedrom, ,svg,subs='attributes',width="100%"] +.... +<%= JSON.dump csr.wavedrom_desc(arch_def, 64) %> +.... +<%- else -%> +<%# CSR has a dynamic length, or a field has a dynamic location, + so there is more than one format to display -%> +This CSR format changes dynamically. + +.<%= csr.name %> Format when <%= csr.length_cond32 %> +[wavedrom, ,svg,subs='attributes',width="100%"] +.... +<%= JSON.dump csr.wavedrom_desc(arch_def, 32) %> +.... + +.<%= csr.name %> Format when <%= csr.length_cond64 %> +[wavedrom, ,svg,subs='attributes',width="100%"] +.... +<%= JSON.dump csr.wavedrom_desc(arch_def, 64) %> +.... +<%- end -%> + +==== Field Summary + +[%autowidth,float="center",align="center",cols="^,<,<,<",options="header",role="stretch"] +|=== +|Name | Location | Type | Reset Value + +<%- csr.fields.each do |field| -%> +| xref:<%=csr.name%>-<%=field.name%>-def[`<%= field.name %>`] +| <%= field.location_pretty(arch_def) %> +| <%= field.type_pretty(arch_def) %> +| <%= field.reset_value_pretty(arch_def) %> + +<%- end -%> +|=== + + +==== Fields + +<%- if csr.fields.empty? -%> +This CSR has no fields. However, it must still exist (not cause an `Illegal Instruction` trap) and always return zero on a read. +<%- else -%> + +<%- csr.fields.each do |field| -%> +[[<%=csr.name%>-<%=field.name%>-def]] +===== `<%= field.name %>` + +[example] +**** +Location:: +<%= field.location_pretty(arch_def) %> + +Description:: +<%= field.description %> + +Type:: +<%= field.type_pretty(arch_def) %> + +Reset value:: +<%= field.reset_value_pretty(arch_def) %> + +**** + +<%- end -%> +<%- end -%> + +<%- if csr.fields.map(&:has_custom_sw_write?).any? -%> +== Software write + +This CSR may store a value that is different from what software attempts to write. + +When a software write occurs (_e.g._, through `csrrw`), the following determines the +written value: + +[idl] +---- +<%- csr.fields.each do |field| -%> +<%- if field.has_custom_sw_write? -%> +<%= field.name %> = <%= field["sw_write(csr_value)"] %> +<%- else -%> +<%= field.name %> = csr_value.<%= field.name %> +<%- end -%> +<%- end -%> +---- +<%- end -%> + +<%- if csr.has_custom_sw_read? -%> +== Software read + +This CSR may return a value that is different from what is stored in hardware. + +[source,idl,subs="specialchars,macros"] +---- +<%= csr.sw_read_ast(arch_def.idl_compiler).gen_adoc %> +---- +<%- end -%> + + +<%- end -%> + +<%- end -%> + +<%- unless ext.instructions.empty? -%> <<< == Instruction summary -The following instructions are added by this extension: +The following <%= ext.instructions.size %> instructions are added by this extension: [%autowidth] |=== | RV32 | RV64 | Mnemonic | Instruction | <%= ext.versions.map { |v| "v#{v["version"]}" }.join(" | ") %> <%- ext.instructions.each do |i| -%> -| <%= i.rv32? ? "X" : "" %> -| <%= i.rv64? ? "X" : "" %> +| <%= i.rv32? ? "✓" : "" %> +| <%= i.rv64? ? "✓" : "" %> | `<%= i.name %> <%= i.assembly.gsub("x", "r") %>` | xref:insns-<%= i.name.gsub('.', '_') %>[<%= i.long_name %>] -| <%= ext.versions.map { |v| i.defined_by?(ext.name, v["version"]) ? "X" : "" }.join(" | ") %> +| <%= ext.versions.map { |v| i.defined_by?(ext.name, v["version"]) ? "✓" : "" }.join(" | ") %> <%- end -%> |=== @@ -250,7 +406,7 @@ RV64:: <%- end -%> ---- <%- else -%> -[source,idl] +[source,idl,subs="specialchars,macros"] ---- <%- i.decode_variables(i.base.nil? ? 64 : i.base).each do |d| -%> <%= d.sext? ? 'signed ' : '' %>Bits<<%= d.size %>> <%= d.name %> = <%= d.extract %>; @@ -259,7 +415,7 @@ RV64:: <%- end -%> Operation:: -[source,idl] +[source,idl,subs="specialchars,macros"] ---- <%= i.operation_ast(arch_def.idl_compiler).gen_adoc %> ---- @@ -276,4 +432,29 @@ Included in:: <%- end -%> |=== <<< +<%- end -%> +<%- end -%> + +<<< +== IDL Functions + +<%- ext.reachable_functions_unevaluated.sort { |a,b| a.name <=> b.name }.each do |f| -%> +[#<%= f.name %>-func-def] +=== <%= f.name %><%- if f.builtin? -%> (builtin)<%- end -%> + +<%= f.description %> + +|=== +h| Return Type l| <%= f.return_type_list_str.join(', ') %> +h| Arguments l| <%= f.arguments_list_str.join (', ') %> +|=== + +<%- unless f.builtin? -%> +<%- body_ast = f.body -%> +[source,idl,subs="specialchars,macros"] +---- +<%= body_ast.gen_adoc %> +---- +<%- end -%> + <%- end -%> \ No newline at end of file diff --git a/cfgs/generic_rv64/params.yaml b/cfgs/generic_rv64/params.yaml index 67b583cfb..c7fbb6ec1 100644 --- a/cfgs/generic_rv64/params.yaml +++ b/cfgs/generic_rv64/params.yaml @@ -106,15 +106,95 @@ params: - false # HPM30 - false # HPM31 - # Indicates which counters can delegated via mcounteren + # Indicates which counters can delegated via mcounteren # # An unimplemented counter cannot be specified, i.e., if # NUM_HPM_COUNTERS == 8, it would be illegal to add index # 11 in COUNTEN_EN since the highest implemented counter # would be at bit 10 - COUNTENABLE_EN: + MCOUNTENABLE_EN: - true # CY - - false # empty + - false # TM + - true # IR + - true # HPM3 + - true # HPM4 + - true # HPM5 + - true # HPM6 + - true # HPM7 + - true # HPM8 + - true # HPM9 + - true # HPM10 + - false # HPM11 + - false # HPM12 + - false # HPM13 + - false # HPM14 + - false # HPM15 + - false # HPM16 + - false # HPM17 + - false # HPM18 + - false # HPM19 + - false # HPM20 + - false # HPM21 + - false # HPM22 + - false # HPM23 + - false # HPM24 + - false # HPM25 + - false # HPM26 + - false # HPM27 + - false # HPM28 + - false # HPM29 + - false # HPM30 + - false # HPM31 + + # Indicates which counters can delegated via scounteren + # + # An unimplemented counter cannot be specified, i.e., if + # NUM_HPM_COUNTERS == 8, it would be illegal to add index + # 11 in COUNTEN_EN since the highest implemented counter + # would be at bit 10 + SCOUNTENABLE_EN: + - true # CY + - false # TM + - true # IR + - true # HPM3 + - true # HPM4 + - true # HPM5 + - true # HPM6 + - true # HPM7 + - true # HPM8 + - true # HPM9 + - true # HPM10 + - false # HPM11 + - false # HPM12 + - false # HPM13 + - false # HPM14 + - false # HPM15 + - false # HPM16 + - false # HPM17 + - false # HPM18 + - false # HPM19 + - false # HPM20 + - false # HPM21 + - false # HPM22 + - false # HPM23 + - false # HPM24 + - false # HPM25 + - false # HPM26 + - false # HPM27 + - false # HPM28 + - false # HPM29 + - false # HPM30 + - false # HPM31 + + # Indicates which counters can delegated via hcounteren + # + # An unimplemented counter cannot be specified, i.e., if + # NUM_HPM_COUNTERS == 8, it would be illegal to add index + # 11 in COUNTEN_EN since the highest implemented counter + # would be at bit 10 + HCOUNTENABLE_EN: + - true # CY + - false # TM - true # IR - true # HPM3 - true # HPM4 diff --git a/lib/arch_def.rb b/lib/arch_def.rb index b549886e3..72fd18bcd 100644 --- a/lib/arch_def.rb +++ b/lib/arch_def.rb @@ -9,6 +9,7 @@ require_relative "idl/passes/gen_adoc" require_relative "idl/passes/prune" require_relative "idl/passes/reachable_functions" +require_relative "idl/passes/reachable_functions_unevaluated" require_relative "idl/passes/reachable_exceptions" # base for any object representation of the Architecture Definition @@ -331,7 +332,7 @@ def type(arch_def) type = if @data.key?("type") @data["type"] - else + elsif arch_def.is_a?(ImplArchDef) # the type is config-specific... idl = @data["type()"] raise "type() is nil for #{csr.name}.#{name} #{@data}?" if idl.nil? @@ -363,10 +364,25 @@ def type(arch_def) ensure sym_table.pop end + else + raise "arch def is generic, can't know type exactly" end @type_cache[arch_def] = type end + # @return [String] A pretty-printed type string + def type_pretty(arch_def) + if arch_def.is_a?(ImplArchDef) + type(arch_def) + else + if @data.key?("type") + @data["type"] + else + @data["type()"] + end + end + end + # @return [Alias,nil] The aliased field, or nil if there is no alias def alias return @alias unless @alias.nil? @@ -394,10 +410,11 @@ def alias @alias end - # @return [Array] List of functions called thorugh this field # @param archdef [ImplArchDef] a configuration # @Param effective_xlen [Integer] 32 or 64; needed because fields can change in different XLENs def reachable_functions(archdef, effective_xlen) + return @reachable_functions unless @reachable_functions.nil? fns = [] if has_custom_sw_write? @@ -422,7 +439,36 @@ def reachable_functions(archdef, effective_xlen) fns.concat ast.reachable_functions(archdef.sym_table.deep_clone.push) end end - fns + + @reachable_functions = fns.uniq + end + + # @return [Array] List of functions called thorugh this field, irrespective of context + # @param archdef [ArchDef] Architecture definition + def reachable_functions_unevaluated(archdef) + return @reachable_functions_unevaluated unless @reachable_functions_unevaluated.nil? + + fns = [] + if has_custom_sw_write? + ast = sw_write_ast(archdef.idl_compiler) + unless ast.nil? + fns.concat ast.reachable_functions_unevaluated(archdef) + end + end + if @data.key?("type()") + ast = type_ast(archdef.idl_compiler) + unless ast.nil? + fns.concat ast.reachable_functions_unevaluated(archdef) + end + end + if @data.key?("reset_value()") + ast = reset_value_ast(archdef.idl_compiler) + unless ast.nil? + fns.concat ast.reachable_functions_unevalutated(archdef) + end + end + + @reachable_functions_unevaluated = fns.uniq end # @return [Csr] Parent CSR for this field @@ -432,12 +478,16 @@ def reachable_functions(archdef, effective_xlen) # @return [Boolean] Whether or not the location of the field changes dynamically # (e.g., based on mstatus.SXL) in the configuration def dynamic_location?(arch_def) - if @data.key?("location_rv32") - csr.modes_with_access.each do |mode| - return true if arch_def.multi_xlen_in_mode?(mode) + if arch_def.is_a?(ImplArchDef) + unless @data["location_rv32"].nil? + csr.modes_with_access.each do |mode| + return true if arch_def.multi_xlen_in_mode?(mode) + end end + false + else + !@data["location_rv32"].nil? end - false end # @param arch_def [IdL::Compiler] A compiler @@ -526,10 +576,24 @@ def reset_value(arch_def) else symtab = arch_def.sym_table.deep_clone symtab.push - pruned_reset_value_ast(arch_def).return_value(symtab) + val = pruned_reset_value_ast(arch_def).return_value(symtab) + val = "UNDEFINED_LEGAL" if val == 0x1_0000_0000_0000_0000 + val end end + def reset_value_pretty(arch_def) + if arch_def.is_a?(ImplArchDef) + reset_value(arch_def) + else + if @data.key?("reset_value") + @data["reset_value"] + else + @data["reset_value()"] + end + end + end + # @return [Boolean] true if the CSR field has a custom sw_write function def has_custom_sw_write? @data.key?("sw_write(csr_value)") && !@data["sw_write(csr_value)"].empty? @@ -667,6 +731,9 @@ def base64_only? = @data.key?("base") && @data["base"] == 64 # @return [Boolean] Whether or not this field only exists when XLEN == 32 def base32_only? = @data.key?("base") && @data["base"] == 32 + def defined_in_base32? = @data["base"].nil? || @data["base"] == 32 + def defined_in_base64? = @data["base"].nil? || @data["base"] == 64 + # @return [Boolean] Whether or not this field exists for any XLEN def defined_in_all_bases? = @data["base"].nil? @@ -700,7 +767,11 @@ def location_pretty(arch_def) #{derangeify.call(location(arch_def, 64))} when #{condition.sub('%%', '1')} LOC else - derangeify.call(location(arch_def, arch_def.param_values["XLEN"])) + if arch_def.is_a?(ImplArchDef) + derangeify.call(location(arch_def, arch_def.param_values["XLEN"])) + else + derangeify.call(location(arch_def, nil)) + end end end @@ -773,12 +844,29 @@ def priv_mode @data["priv_mode"] end + def long_name + @data["long_name"] + end + # @return [Integer] CSR address in VS/VU mode, if different from other modes # @return [nil] If the CSR is not accessible in VS/VU mode, or if it's address does not change in those modes def virtual_address @data["virtual_address"] 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"] + + # @return [Boolean] true if this CSR is defined when XLEN is 32 + def defined_in_base32? = @data["base"].nil? || @data["base"] == 32 + + # @return [Boolean] true if this CSR is defined when XLEN is 64 + def defined_in_base64? = @data["base"].nil? || @data["base"] == 64 + + # @return [Boolean] true if this CSR is defined regardless of the effective XLEN + def defined_in_all_bases? = @data["base"].nil? + # @param arch_def [ArchDef] A configuration # @return [Boolean] Whether or not the format of this CSR changes when the effective XLEN changes in some mode def format_changes_with_xlen?(arch_def) @@ -791,6 +879,8 @@ def format_changes_with_xlen?(arch_def) # @param arch_def [ImplArchDef] A configuration # @return [Array] List of functions reachable from this CSR's sw_read or a field's sw_wirte function def reachable_functions(arch_def) + return @reachable_functions unless @reachable_functions.nil? + fns = [] if has_custom_sw_read? @@ -813,7 +903,26 @@ def reachable_functions(arch_def) end end - fns.uniq + @reachable_functions = fns.uniq + end + + # @param arch_def [ArchDef] Architecture definition + # @return [Array] List of functions reachable from this CSR's sw_read or a field's sw_wirte function, irrespective of context + def reachable_functions_unevaluated(arch_def) + return @reachable_functions_unevaluated unless @reachable_functions_unevaluated.nil? + + fns = [] + + if has_custom_sw_read? + ast = sw_read_ast(arch_def.idl_compiler) + fns.concat(ast.reachable_functions_unevaluated(arch_def)) + end + + fields.each do |field| + fns.concat(field.reachable_functions_unevaluated(arch_def)) + end + + @reachable_functions_unevaluated = fns.uniq end # @param arch_def [ArchDef] A configuration @@ -824,15 +933,45 @@ def dynamic_length?(arch_def) case @data["length"] when "MXLEN" - false # mxlen can never change + if arch_def.is_a?(ImplArchDef) + false # mxlen can never change + else + if @data["base"].nil? + # don't know MXLEN + true + else + # mxlen is always "base" + false + end + end when "SXLEN" - arch_def.param_values["SXLEN"] == 3264 + if arch_def.is_a?(ImplArchDef) + arch_def.param_values["SXLEN"] == 3264 + else + if @data["base"].nil? + # don't know SXLEN + true + else + # sxlen is always "base" + false + end + end when "VSXLEN" - arch_def.param_values["VSXLEN"] == 3264 + if arch_def.is_a?(ImplArchDef) + arch_def.param_values["VSXLEN"] == 3264 + else + if @data["base"].nil? + # don't know VSXLEN + true + else + # vsxlen is always "base" + false + end + end else raise "Unexpected length" end - !@data["length"].is_a?(Integer) && (@data["length"] != "MXLEN") + # !@data["length"].is_a?(Integer) && (@data["length"] != "MXLEN") end # @param arch_def [ArchDef] A configuration (can be nil if the lenth is not dependent on a config parameter) @@ -841,27 +980,60 @@ def dynamic_length?(arch_def) def length(arch_def, effective_xlen = nil) case @data["length"] when "MXLEN" - arch_def.param_values["XLEN"] + if arch_def.is_a?(ImplArchDef) + arch_def.param_values["XLEN"] + else + if @data["base"].nil? + @data["base"] + else + # don't know MXLEN + raise ArgumentError, "effective_xlen is required when length is MXLEN and arch_def is generic" if effective_xlen.nil? + + effective_xlen + end + end when "SXLEN" - if arch_def.param_values["SXLEN"] == 3264 - raise ArgumentError, "effective_xlen is required when length is dynamic (#{name})" if effective_xlen.nil? + if arch_def.is_a?(ImplArchDef) + if arch_def.param_values["SXLEN"] == 3264 + raise ArgumentError, "effective_xlen is required when length is dynamic (#{name})" if effective_xlen.nil? + + effective_xlen + else + raise "CSR #{name} is not implemented" if arch_def.implemented_csrs.none? { |c| c.name == name } + raise "CSR #{name} is not implemented" if arch_def.param_values["SXLEN"].nil? - effective_xlen + arch_def.param_values["SXLEN"] + end else - raise "CSR #{name} is not implemented" if arch_def.implemented_csrs.none? { |c| c.name == name } - raise "CSR #{name} is not implemented" if arch_def.param_values["SXLEN"].nil? + if @data["base"].nil? + @data["base"] + else + # don't know SXLEN + raise ArgumentError, "effective_xlen is required when length is SXLEN and arch_def is generic" if effective_xlen.nil? - arch_def.param_values["SXLEN"] + effective_xlen + end end when "VSXLEN" - if arch_def.param_values["VSXLEN"] == 3264 - raise ArgumentError, "effective_xlen is required when length is dynamic (#{name})" if effective_xlen.nil? + if arch_def.is_a?(ImplArchDef) + if arch_def.param_values["VSXLEN"] == 3264 + raise ArgumentError, "effective_xlen is required when length is dynamic (#{name})" if effective_xlen.nil? + + effective_xlen + else + raise "CSR #{name} is not implemented" if arch_def.param_values["VSXLEN"].nil? - effective_xlen + arch_def.param_values["VSXLEN"] + end else - raise "CSR #{name} is not implemented" if arch_def.param_values["VSXLEN"].nil? + if @data["base"].nil? + @data["base"] + else + # don't know VSXLEN + raise ArgumentError, "effective_xlen is required when length is VSXLEN and arch_def is generic" if effective_xlen.nil? - arch_def.param_values["VSXLEN"] + effective_xlen + end end when Integer @data["length"] @@ -1153,7 +1325,12 @@ def wavedrom_desc(arch_def, effective_xlen) "reg" => [] } last_idx = -1 - field_list = implemented_fields_for(arch_def, effective_xlen) + field_list = + if arch_def.is_a?(ImplArchDef) + implemented_fields_for(arch_def, effective_xlen) + else + fields + end field_list.each do |field| if field.location(arch_def, effective_xlen).min != last_idx + 1 @@ -1202,6 +1379,12 @@ def base @data["base"] end + # @param xlen [Integer] 32 or 64, the target xlen + # @return [Boolean] whethen or not instruction is defined in base +xlen+ + def defined_in_base?(xlen) + base == xlen + end + # @return [String] Assembly format def assembly @data["assembly"] @@ -1210,7 +1393,7 @@ def assembly # @return [Array] List of extensions requirements (in addition to one returned by {#defined_by}) that must be met for the instruction to exist def extension_requirements return [] unless @data.key?("requires") - + @extension_requirements = [] if @data["requires"].is_a?(Array) # could be either a single extension with requirement, or a list of requirements @@ -1220,7 +1403,7 @@ def extension_requirements # this is a list @data["requires"].each do |r| @extension_requirements << to_extension_requirement(r) - end + end end else @extension_requirements << to_extension_requirement(@data["requires"]) @@ -1922,6 +2105,29 @@ def versions @data["versions"] end + # @return [Array] Ratified versions hash from config + def ratified_versions + @data["versions"].select { |v| v["state"] == "ratified" } + end + + # @return [String] Mimumum defined version of this extension + def min_version + versions.map { |v| Gem::Version.new(v["version"]) }.min + end + + # @return [String] Maximum defined version of this extension + def max_version + versions.map { |v| Gem::Version.new(v["version"]) }.max + end + + # @return [String] Mimumum defined ratified version of this extension + # @return [nil] if there is no ratified version + def min_ratified_version + return nil if ratified_versions.empty? + + ratified_versions.map { |v| Gem::Version.new(v["version"]) }.min + end + # @return [Array] List of parameters added by this extension def params return @params unless @params.nil? @@ -1969,9 +2175,59 @@ def implies(version_requirement = ">= 0") implications end - # returns the list of instructions implemented by this extension + # @return [Array] the list of instructions implemented by this extension (may be empty) def instructions - arch_def.instructions.select { |i| i.definedBy == name || (i.definedBy.is_a?(Array) && i.definedBy.include?(name)) } + return @instructions unless @instructions.nil? + + @instructions = arch_def.instructions.select { |i| i.definedBy == name || (i.definedBy.is_a?(Array) && i.definedBy.include?(name)) } + end + + # @return [Array] the list of CSRs implemented by this extension (may be empty) + def csrs + return @csrs unless @csrs.nil? + + @csrs = arch_def.csrs.select { |csr| csr.defined_by?(ExtensionVersion.new(name, max_version)) } + end + + # return the set of reachable functions from any of this extensions's CSRs or instructions in the given evaluation context + # + # @param symtab [Idl::SymbolTable] The evaluation context + # @return [Array] Array of IDL functions reachable from any instruction or CSR in the extension + def reachable_functions(symtab) + @reachable_functions ||= {} + + return @reachable_functions[symtab] unless @reachable_functions[symtab].nil? + + funcs = [] + + puts "Finding all reachable functions from extension #{name}" + + instructions.each do |inst| + funcs += inst.reachable_functions(symtab, 32) if inst.defined_in_base?(32) + funcs += inst.reachable_functions(symtab, 64) if inst.defined_in_base?(64) + end + + csrs.each do |csr| + funcs += csr.reachable_functions(arch_def) + end + + @reachable_functions[symtab] = funcs.uniq + end + + # @return [Array] Array of IDL functions reachable from any instruction or CSR in the extension, irrespective of a specific evaluation context + def reachable_functions_unevaluated + return @reachable_functions_unevaluated unless @reachable_functions_unevaluated.nil? + + funcs = [] + instructions.each do |inst| + funcs += inst.operation_ast(arch_def.idl_compiler).reachable_functions_unevaluated(arch_def) + end + + csrs.each do |csr| + funcs += csr.reachable_functions_unevaluated(arch_def) + end + + @reachable_functions_unevaluated = funcs.uniq(&:name) end end @@ -2044,6 +2300,10 @@ def version_requirement @requirement end + def to_s + "#{name} #{@requirement}" + end + # @param name [#to_s] Extension name # @param requirements (see Gem::Requirement#new) def initialize(name, *requirements) @@ -2200,6 +2460,32 @@ def inst(inst_name) instruction_hash[inst_name.to_s] end + # @return [Array] List of all functions defined by the architecture + def functions + return @functions unless @functions.nil? + + @functions = @global_ast.functions + end + + # @return [Hash] Function hash of name => FunctionBodyAst + def function_hash + return @function_hash unless @function_hash.nil? + + @function_hash = {} + functions.each do |func| + @function_hash[func.name] = func + end + + @function_hash + end + + # @param name [String] A function name + # @return [Idl::FunctionBodyAst] A function named +name+ + # @return [nil] if no function named +name+ is found + def function(name) + function_hash[name] + end + # given an adoc string, find names of CSR/Instruction/Extension enclosed in `monospace` # and replace them with links to the relevant object page # @@ -2214,7 +2500,7 @@ def find_replace_links(adoc) "%%LINK%csr_field;#{csr_name}.#{field_name};#{csr_name}.#{field_name}%%" elsif !csr.nil? "%%LINK%csr;#{csr_name};#{csr_name}%%" - elsif inst(name.downcase) + elsif inst(name) "%%LINK%inst;#{name};#{name}%%" elsif extension(name) "%%LINK%ext;#{name};#{name}%%" @@ -2248,7 +2534,7 @@ def initialize(name, var, number, ext) end end -# all the same informatin as ExceptinCOde, but for interrupts +# all the same informatin as ExceptinCode, but for interrupts InterruptCode = Class.new(ExceptionCode) # Object model for a configured architecture definition @@ -2379,8 +2665,10 @@ def initialize(config_name) @sym_table = Idl::SymbolTable.new(self) # load the globals into the symbol table + custom_globals_path = $root / "cfgs" / @name / "arch_overlay" / "isa" / "globals.isa" + idl_path = File.exist?(custom_globals_path) ? custom_globals_path : $root / "arch" / "isa" / "globals.isa" @global_ast = @idl_compiler.compile_file( - $root / "arch" / "isa" / "globals.isa", + idl_path, symtab: @sym_table ) diff --git a/lib/idl/ast.rb b/lib/idl/ast.rb index 8c816874a..8888328b8 100644 --- a/lib/idl/ast.rb +++ b/lib/idl/ast.rb @@ -5112,32 +5112,53 @@ def execute_unknown(_symtab); end def to_idl = "#{csr.to_idl}.sw_write(#{expression.to_idl})" end - class CsrSoftwareReadSyntaxNode < Treetop::Runtime::SyntaxNode + # @api private + class CsrFunctionCallSyntaxNode < Treetop::Runtime::SyntaxNode def to_ast - CsrSoftwareReadAst.new(input, interval, csr.to_ast) + CsrFunctionCallAst.new(input, interval, function_name.text_value, csr.to_ast) end end - class CsrSoftwareReadAst < AstNode + # represents a function call for a CSR register + # for example: + # + # CSR[mstatus].address() + # CSR[mtval].sw_read() + class CsrFunctionCallAst < AstNode include Rvalue + # @return [String] The function being called + attr_reader :function_name + def csr = @children[0] - def initialize(input, interval, csr) + def initialize(input, interval, function_name, csr) super(input, interval, [csr]) + @function_name = function_name end def type_check(symtab) + unless ["sw_read", "address"].include?(function_name) + type_error "'#{function_name}' is not a supported CSR function call" + end + csr.type_check(symtab) end def type(symtab) archdef = symtab.archdef - if csr_known?(symtab) - Type.new(:bits, width: archdef.csr(csr.csr_name(symtab)).length) + case function_name + when "sw_read" + if csr_known?(symtab) + Type.new(:bits, width: archdef.csr(csr.csr_name(symtab)).length) + else + Type.new(:bits, width: archdef.param_values["XLEN"]) + end + when "address" + Type.new(:bits, width: 12) else - Type.new(:bits, width: archdef.param_values["XLEN"]) + internal_error "No function '#{function_name}' for CSR. call type check first!" end end @@ -5155,15 +5176,24 @@ def csr_def(symtab) # @todo check the sw_read function body def value(symtab) - value_error "CSR not knowable" unless csr_known?(symtab) - cd = csr_def(symtab) - cd.fields.each { |f| value_error "#{csr_name}.#{f.name} not RO" unless f.type == "RO" } - - value_error "TODO: CSRs with sw_read function" + case function_name + when "sw_read" + value_error "CSR not knowable" unless csr_known?(symtab) + cd = csr_def(symtab) + 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" + value_error "CSR not knowable" unless csr_known?(symtab) + cd = csr_def(symtab) + cd.address + else + internal_error "TODO: #{function_name}" + end end # @!macro to_idl - def to_idl = "#{csr.to_idl}.sw_read()" + def to_idl = "#{csr.to_idl}.#{function_call}()" end class CsrWriteSyntaxNode < Treetop::Runtime::SyntaxNode diff --git a/lib/idl/idl.treetop b/lib/idl/idl.treetop index 1b4c3e50d..b1da639b6 100644 --- a/lib/idl/idl.treetop +++ b/lib/idl/idl.treetop @@ -377,7 +377,7 @@ grammar Idl rule function_call csr:csr_register_access_expression space* '.' space* 'sw_write' space* '(' space* expression space* ')' / - csr:csr_register_access_expression space* '.' space* 'sw_read' space* '(' space* ')' + csr:csr_register_access_expression space* '.' space* function_name space* '(' space* ')' / function_name t:(space* '<' space* targs:function_call_template_arguments space* '>')? space* '(' space* function_arg_list space* ')' end diff --git a/lib/idl/passes/gen_adoc.rb b/lib/idl/passes/gen_adoc.rb index 10629f8f6..fbd377542 100644 --- a/lib/idl/passes/gen_adoc.rb +++ b/lib/idl/passes/gen_adoc.rb @@ -65,9 +65,9 @@ def gen_adoc(indent, indent_spaces: 2) "#{' '*indent}(#{variables.map { |v| v.gen_adoc(0, indent_spaces: )}.join(', ')} = #{function_call.gen_adoc(0, indent_spaces:)})" end end - class CsrSoftwareReadAst + class CsrFunctionCallAst def gen_adoc(indent, indent_spaces: 2) - "#{' '*indent}#{csr.gen_adoc(indent, indent_spaces:)}.sw_read()" + "#{' '*indent}#{csr.gen_adoc(indent, indent_spaces:)}.#{function_name}()" end end class CsrSoftwareWriteAst @@ -133,7 +133,7 @@ def gen_adoc(indent = 0, indent_spaces: 2) end class SignCastAst def gen_adoc(indent = 0, indent_spaces: 2) - "#{' '*indent}$signed+(+#{expression.gen_adoc(0, indent_spaces:)})" + "#{' '*indent}$signed+++(+++#{expression.gen_adoc(0, indent_spaces:)})" end end class AryRangeAccessAst diff --git a/lib/idl/passes/reachable_functions_unevaluated.rb b/lib/idl/passes/reachable_functions_unevaluated.rb new file mode 100644 index 000000000..059d58b12 --- /dev/null +++ b/lib/idl/passes/reachable_functions_unevaluated.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +# finds all reachable functions from a give sequence of statements + +module Idl + class AstNode + # @param arch_def [ArchDef] Architecture definition + # @return [Array] List of all functions that can be reached (via function calls) from this node, without considering value evaluation + def reachable_functions_unevaluated(arch_def) + children.reduce([]) do |list, e| + list.concat e.reachable_functions_unevaluated(arch_def) + end.uniq(&:name) + end + end + + class FunctionCallExpressionAst + def reachable_functions_unevaluated(arch_def) + fns = [] + if template? + template_arg_nodes.each do |t| + fns.concat(t.reachable_functions_unevaluated(arch_def)) + end + end + + arg_nodes.each do |a| + fns.concat(a.reachable_functions_unevaluated(arch_def)) + end + + func_def_ast = arch_def.function(name) + raise "No function '#{name}' found in Architecture def" if func_def_ast.nil? + + fns += func_def_ast.reachable_functions_unevaluated(arch_def) + fns.uniq(&:name) + end + end + + class FunctionDefAst + def reachable_functions_unevaluated(arch_def) + fns = [self] + + unless builtin? + body.stmts.each do |stmt| + fns += stmt.reachable_functions_unevaluated(arch_def) + end + end + + fns.uniq + end + end +end diff --git a/lib/idl/symbol_table.rb b/lib/idl/symbol_table.rb index 89cc00c4b..96cf337ec 100644 --- a/lib/idl/symbol_table.rb +++ b/lib/idl/symbol_table.rb @@ -21,6 +21,10 @@ def initialize(name, type, value = nil, decode_var: false, template_index: nil, @function_name = function_name end + def hash + [@name, @type, @value, @decode_var, @template_index, @function_name].hash + end + def to_s "VAR: #{type} #{name} #{value.nil? ? 'NO VALUE' : value}" end @@ -76,6 +80,12 @@ class SymbolTable class DuplicateSymError < StandardError end + def hash + return @frozen_hash unless @frozen_hash.nil? + + [@scopes.hash, @archdef.hash].hash + end + def initialize(arch_def) @archdef = arch_def @scopes = [{ @@ -180,6 +190,10 @@ def deep_freeze v.freeze end @scopes.freeze + + # set frozen_hash so that we can quickly compare symtabs + @frozen_hash = [@scopes.hash, @archdef.hash].hash + freeze end @@ -200,7 +214,6 @@ def pop raise "Error: popping the symbol table would remove global scope" if @scopes.size == 1 @scopes.pop - end # @return [Boolean] whether or not any symbol 'name' is defined at any level in the symbol table