From 214d5802db5d73d006907487b46f952085189291 Mon Sep 17 00:00:00 2001 From: dhower-qc <134728312+dhower-qc@users.noreply.github.com> Date: Sat, 20 Jul 2024 20:53:37 -0400 Subject: [PATCH] Refactor for backend, plus (#5) * Refactor to make backends explict. Also: * Make all .yaml files in arch/ valid YAML (ERB is only used in strings) * Make Csr, Instruction, Extension objects independent of an ArchDef * Lots of updates to counter/hpm CSRs to better reflect all the implementation options --- Rakefile | 216 ++++ arch/csr/I/mcounteren.layout | 186 +++ arch/csr/I/mcounteren.yaml | 1055 +++++++++++++++++ arch/csr/I/pmpaddr0.yaml | 75 ++ arch/csr/I/pmpaddr1.yaml | 75 ++ arch/csr/I/pmpaddr10.yaml | 75 ++ arch/csr/I/pmpaddr11.yaml | 75 ++ arch/csr/I/pmpaddr12.yaml | 75 ++ arch/csr/I/pmpaddr13.yaml | 75 ++ arch/csr/I/pmpaddr14.yaml | 75 ++ arch/csr/I/pmpaddr15.yaml | 75 ++ arch/csr/I/pmpaddr16.yaml | 75 ++ arch/csr/I/pmpaddr17.yaml | 75 ++ arch/csr/I/pmpaddr18.yaml | 75 ++ arch/csr/I/pmpaddr19.yaml | 75 ++ arch/csr/I/pmpaddr2.yaml | 75 ++ arch/csr/I/pmpaddr20.yaml | 75 ++ arch/csr/I/pmpaddr21.yaml | 75 ++ arch/csr/I/pmpaddr22.yaml | 75 ++ arch/csr/I/pmpaddr23.yaml | 75 ++ arch/csr/I/pmpaddr24.yaml | 75 ++ arch/csr/I/pmpaddr25.yaml | 75 ++ arch/csr/I/pmpaddr26.yaml | 75 ++ arch/csr/I/pmpaddr27.yaml | 75 ++ arch/csr/I/pmpaddr28.yaml | 75 ++ arch/csr/I/pmpaddr29.yaml | 75 ++ arch/csr/I/pmpaddr3.yaml | 75 ++ arch/csr/I/pmpaddr30.yaml | 75 ++ arch/csr/I/pmpaddr31.yaml | 75 ++ arch/csr/I/pmpaddr32.yaml | 75 ++ arch/csr/I/pmpaddr33.yaml | 75 ++ arch/csr/I/pmpaddr34.yaml | 75 ++ arch/csr/I/pmpaddr35.yaml | 75 ++ arch/csr/I/pmpaddr36.yaml | 75 ++ arch/csr/I/pmpaddr37.yaml | 75 ++ arch/csr/I/pmpaddr38.yaml | 75 ++ arch/csr/I/pmpaddr39.yaml | 75 ++ arch/csr/I/pmpaddr4.yaml | 75 ++ arch/csr/I/pmpaddr40.yaml | 75 ++ arch/csr/I/pmpaddr41.yaml | 75 ++ arch/csr/I/pmpaddr42.yaml | 75 ++ arch/csr/I/pmpaddr43.yaml | 75 ++ arch/csr/I/pmpaddr44.yaml | 75 ++ arch/csr/I/pmpaddr45.yaml | 75 ++ arch/csr/I/pmpaddr46.yaml | 75 ++ arch/csr/I/pmpaddr47.yaml | 75 ++ arch/csr/I/pmpaddr48.yaml | 75 ++ arch/csr/I/pmpaddr49.yaml | 75 ++ arch/csr/I/pmpaddr5.yaml | 75 ++ arch/csr/I/pmpaddr50.yaml | 75 ++ arch/csr/I/pmpaddr51.yaml | 75 ++ arch/csr/I/pmpaddr52.yaml | 75 ++ arch/csr/I/pmpaddr53.yaml | 75 ++ arch/csr/I/pmpaddr54.yaml | 75 ++ arch/csr/I/pmpaddr55.yaml | 75 ++ arch/csr/I/pmpaddr56.yaml | 75 ++ arch/csr/I/pmpaddr57.yaml | 75 ++ arch/csr/I/pmpaddr58.yaml | 75 ++ arch/csr/I/pmpaddr59.yaml | 75 ++ arch/csr/I/pmpaddr6.yaml | 75 ++ arch/csr/I/pmpaddr60.yaml | 75 ++ arch/csr/I/pmpaddr61.yaml | 75 ++ arch/csr/I/pmpaddr62.yaml | 75 ++ arch/csr/I/pmpaddr63.yaml | 75 ++ arch/csr/I/pmpaddr7.yaml | 75 ++ arch/csr/I/pmpaddr8.yaml | 75 ++ arch/csr/I/pmpaddr9.yaml | 75 ++ arch/csr/I/pmpaddrN.layout | 77 ++ arch/csr/I/pmpcfg0.yaml | 490 ++++++++ arch/csr/I/pmpcfg1.yaml | 251 ++++ arch/csr/I/pmpcfg10.yaml | 490 ++++++++ arch/csr/I/pmpcfg11.yaml | 251 ++++ arch/csr/I/pmpcfg12.yaml | 490 ++++++++ arch/csr/I/pmpcfg13.yaml | 251 ++++ arch/csr/I/pmpcfg14.yaml | 490 ++++++++ arch/csr/I/pmpcfg15.yaml | 251 ++++ arch/csr/I/pmpcfg2.yaml | 490 ++++++++ arch/csr/I/pmpcfg3.yaml | 251 ++++ arch/csr/I/pmpcfg4.yaml | 490 ++++++++ arch/csr/I/pmpcfg5.yaml | 251 ++++ arch/csr/I/pmpcfg6.yaml | 490 ++++++++ arch/csr/I/pmpcfg7.yaml | 251 ++++ arch/csr/I/pmpcfg8.yaml | 490 ++++++++ arch/csr/I/pmpcfg9.yaml | 251 ++++ arch/csr/I/pmpcfgN.layout | 79 ++ arch/csr/S/scounteren.layout | 81 ++ arch/csr/S/scounteren.yaml | 642 ++++++++++ .../mcountinhibit.layout} | 17 +- arch/csr/Zicntr/mcountinhibit.yaml | 406 +++++++ arch/csr/Zihpm/hpmcounter10.yaml | 73 ++ arch/csr/Zihpm/hpmcounter10h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter11.yaml | 73 ++ arch/csr/Zihpm/hpmcounter11h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter12.yaml | 73 ++ arch/csr/Zihpm/hpmcounter12h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter13.yaml | 73 ++ arch/csr/Zihpm/hpmcounter13h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter14.yaml | 73 ++ arch/csr/Zihpm/hpmcounter14h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter15.yaml | 73 ++ arch/csr/Zihpm/hpmcounter15h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter16.yaml | 73 ++ arch/csr/Zihpm/hpmcounter16h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter17.yaml | 73 ++ arch/csr/Zihpm/hpmcounter17h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter18.yaml | 73 ++ arch/csr/Zihpm/hpmcounter18h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter19.yaml | 73 ++ arch/csr/Zihpm/hpmcounter19h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter20.yaml | 73 ++ arch/csr/Zihpm/hpmcounter20h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter21.yaml | 73 ++ arch/csr/Zihpm/hpmcounter21h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter22.yaml | 73 ++ arch/csr/Zihpm/hpmcounter22h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter23.yaml | 73 ++ arch/csr/Zihpm/hpmcounter23h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter24.yaml | 73 ++ arch/csr/Zihpm/hpmcounter24h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter25.yaml | 73 ++ arch/csr/Zihpm/hpmcounter25h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter26.yaml | 73 ++ arch/csr/Zihpm/hpmcounter26h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter27.yaml | 73 ++ arch/csr/Zihpm/hpmcounter27h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter28.yaml | 73 ++ arch/csr/Zihpm/hpmcounter28h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter29.yaml | 73 ++ arch/csr/Zihpm/hpmcounter29h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter3.yaml | 73 ++ arch/csr/Zihpm/hpmcounter30.yaml | 73 ++ arch/csr/Zihpm/hpmcounter30h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter31.yaml | 73 ++ arch/csr/Zihpm/hpmcounter31h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter3h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter4.yaml | 73 ++ arch/csr/Zihpm/hpmcounter4h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter5.yaml | 73 ++ arch/csr/Zihpm/hpmcounter5h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter6.yaml | 73 ++ arch/csr/Zihpm/hpmcounter6h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter7.yaml | 73 ++ arch/csr/Zihpm/hpmcounter7h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter8.yaml | 73 ++ arch/csr/Zihpm/hpmcounter8h.yaml | 73 ++ arch/csr/Zihpm/hpmcounter9.yaml | 73 ++ arch/csr/Zihpm/hpmcounter9h.yaml | 73 ++ arch/csr/Zihpm/hpmcounterN.layout | 71 ++ arch/csr/Zihpm/hpmcounterNh.layout | 71 ++ arch/csr/Zihpm/mhpmcounter10.yaml | 48 + arch/csr/Zihpm/mhpmcounter10h.yaml | 29 + arch/csr/Zihpm/mhpmcounter11.yaml | 48 + arch/csr/Zihpm/mhpmcounter11h.yaml | 29 + arch/csr/Zihpm/mhpmcounter12.yaml | 48 + arch/csr/Zihpm/mhpmcounter12h.yaml | 29 + arch/csr/Zihpm/mhpmcounter13.yaml | 48 + arch/csr/Zihpm/mhpmcounter13h.yaml | 29 + arch/csr/Zihpm/mhpmcounter14.yaml | 48 + arch/csr/Zihpm/mhpmcounter14h.yaml | 29 + arch/csr/Zihpm/mhpmcounter15.yaml | 48 + arch/csr/Zihpm/mhpmcounter15h.yaml | 29 + arch/csr/Zihpm/mhpmcounter16.yaml | 48 + arch/csr/Zihpm/mhpmcounter16h.yaml | 29 + arch/csr/Zihpm/mhpmcounter17.yaml | 48 + arch/csr/Zihpm/mhpmcounter17h.yaml | 29 + arch/csr/Zihpm/mhpmcounter18.yaml | 48 + arch/csr/Zihpm/mhpmcounter18h.yaml | 29 + arch/csr/Zihpm/mhpmcounter19.yaml | 48 + arch/csr/Zihpm/mhpmcounter19h.yaml | 29 + arch/csr/Zihpm/mhpmcounter20.yaml | 48 + arch/csr/Zihpm/mhpmcounter20h.yaml | 29 + arch/csr/Zihpm/mhpmcounter21.yaml | 48 + arch/csr/Zihpm/mhpmcounter21h.yaml | 29 + arch/csr/Zihpm/mhpmcounter22.yaml | 48 + arch/csr/Zihpm/mhpmcounter22h.yaml | 29 + arch/csr/Zihpm/mhpmcounter23.yaml | 48 + arch/csr/Zihpm/mhpmcounter23h.yaml | 29 + arch/csr/Zihpm/mhpmcounter24.yaml | 48 + arch/csr/Zihpm/mhpmcounter24h.yaml | 29 + arch/csr/Zihpm/mhpmcounter25.yaml | 48 + arch/csr/Zihpm/mhpmcounter25h.yaml | 29 + arch/csr/Zihpm/mhpmcounter26.yaml | 48 + arch/csr/Zihpm/mhpmcounter26h.yaml | 29 + arch/csr/Zihpm/mhpmcounter27.yaml | 48 + arch/csr/Zihpm/mhpmcounter27h.yaml | 29 + arch/csr/Zihpm/mhpmcounter28.yaml | 48 + arch/csr/Zihpm/mhpmcounter28h.yaml | 29 + arch/csr/Zihpm/mhpmcounter29.yaml | 48 + arch/csr/Zihpm/mhpmcounter29h.yaml | 29 + arch/csr/Zihpm/mhpmcounter3.yaml | 48 + arch/csr/Zihpm/mhpmcounter30.yaml | 48 + arch/csr/Zihpm/mhpmcounter30h.yaml | 29 + arch/csr/Zihpm/mhpmcounter31.yaml | 48 + arch/csr/Zihpm/mhpmcounter31h.yaml | 29 + arch/csr/Zihpm/mhpmcounter3h.yaml | 29 + arch/csr/Zihpm/mhpmcounter4.yaml | 48 + arch/csr/Zihpm/mhpmcounter4h.yaml | 29 + arch/csr/Zihpm/mhpmcounter5.yaml | 48 + arch/csr/Zihpm/mhpmcounter5h.yaml | 29 + arch/csr/Zihpm/mhpmcounter6.yaml | 48 + arch/csr/Zihpm/mhpmcounter6h.yaml | 29 + arch/csr/Zihpm/mhpmcounter7.yaml | 48 + arch/csr/Zihpm/mhpmcounter7h.yaml | 29 + arch/csr/Zihpm/mhpmcounter8.yaml | 48 + arch/csr/Zihpm/mhpmcounter8h.yaml | 29 + arch/csr/Zihpm/mhpmcounter9.yaml | 48 + arch/csr/Zihpm/mhpmcounter9h.yaml | 29 + arch/csr/Zihpm/mhpmcounterN.layout | 46 + arch/csr/Zihpm/mhpmcounterNh.layout | 27 + arch/csr/Zihpm/mhpmevent10.yaml | 144 +++ arch/csr/Zihpm/mhpmevent10h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent11.yaml | 144 +++ arch/csr/Zihpm/mhpmevent11h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent12.yaml | 144 +++ arch/csr/Zihpm/mhpmevent12h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent13.yaml | 144 +++ arch/csr/Zihpm/mhpmevent13h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent14.yaml | 144 +++ arch/csr/Zihpm/mhpmevent14h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent15.yaml | 144 +++ arch/csr/Zihpm/mhpmevent15h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent16.yaml | 144 +++ arch/csr/Zihpm/mhpmevent16h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent17.yaml | 144 +++ arch/csr/Zihpm/mhpmevent17h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent18.yaml | 144 +++ arch/csr/Zihpm/mhpmevent18h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent19.yaml | 144 +++ arch/csr/Zihpm/mhpmevent19h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent20.yaml | 144 +++ arch/csr/Zihpm/mhpmevent20h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent21.yaml | 144 +++ arch/csr/Zihpm/mhpmevent21h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent22.yaml | 144 +++ arch/csr/Zihpm/mhpmevent22h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent23.yaml | 144 +++ arch/csr/Zihpm/mhpmevent23h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent24.yaml | 144 +++ arch/csr/Zihpm/mhpmevent24h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent25.yaml | 144 +++ arch/csr/Zihpm/mhpmevent25h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent26.yaml | 144 +++ arch/csr/Zihpm/mhpmevent26h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent27.yaml | 144 +++ arch/csr/Zihpm/mhpmevent27h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent28.yaml | 144 +++ arch/csr/Zihpm/mhpmevent28h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent29.yaml | 144 +++ arch/csr/Zihpm/mhpmevent29h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent3.yaml | 144 +++ arch/csr/Zihpm/mhpmevent30.yaml | 144 +++ arch/csr/Zihpm/mhpmevent30h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent31.yaml | 144 +++ arch/csr/Zihpm/mhpmevent31h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent3h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent4.yaml | 144 +++ arch/csr/Zihpm/mhpmevent4h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent5.yaml | 144 +++ arch/csr/Zihpm/mhpmevent5h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent6.yaml | 144 +++ arch/csr/Zihpm/mhpmevent6h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent7.yaml | 144 +++ arch/csr/Zihpm/mhpmevent7h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent8.yaml | 144 +++ arch/csr/Zihpm/mhpmevent8h.yaml | 143 +++ arch/csr/Zihpm/mhpmevent9.yaml | 144 +++ arch/csr/Zihpm/mhpmevent9h.yaml | 143 +++ arch/csr/Zihpm/mhpmeventN.layout | 142 +++ arch/csr/Zihpm/mhpmeventNh.layout | 141 +++ arch/csr/cycle.yaml | 55 +- arch/csr/cycleh.yaml | 77 ++ arch/csr/instret.yaml | 53 +- arch/csr/instreth.yaml | 57 +- arch/csr/mcounteren.yaml | 74 -- arch/csr/mcycle.yaml | 16 +- arch/csr/mcycleh.yaml | 31 + arch/csr/mepc.yaml | 4 +- arch/csr/mhpmcounter10.yaml | 6 - arch/csr/mhpmcounter10h.yaml | 6 - arch/csr/mhpmcounter11.yaml | 6 - arch/csr/mhpmcounter11h.yaml | 6 - arch/csr/mhpmcounter12.yaml | 6 - arch/csr/mhpmcounter12h.yaml | 6 - arch/csr/mhpmcounter13.yaml | 6 - arch/csr/mhpmcounter13h.yaml | 6 - arch/csr/mhpmcounter14.yaml | 6 - arch/csr/mhpmcounter14h.yaml | 6 - arch/csr/mhpmcounter15.yaml | 6 - arch/csr/mhpmcounter15h.yaml | 6 - arch/csr/mhpmcounter16.yaml | 6 - arch/csr/mhpmcounter16h.yaml | 6 - arch/csr/mhpmcounter17.yaml | 6 - arch/csr/mhpmcounter17h.yaml | 6 - arch/csr/mhpmcounter18.yaml | 6 - arch/csr/mhpmcounter18h.yaml | 6 - arch/csr/mhpmcounter19.yaml | 6 - arch/csr/mhpmcounter19h.yaml | 6 - arch/csr/mhpmcounter20.yaml | 6 - arch/csr/mhpmcounter20h.yaml | 6 - arch/csr/mhpmcounter21.yaml | 6 - arch/csr/mhpmcounter21h.yaml | 6 - arch/csr/mhpmcounter22.yaml | 6 - arch/csr/mhpmcounter22h.yaml | 6 - arch/csr/mhpmcounter23.yaml | 6 - arch/csr/mhpmcounter23h.yaml | 6 - arch/csr/mhpmcounter24.yaml | 6 - arch/csr/mhpmcounter24h.yaml | 6 - arch/csr/mhpmcounter25.yaml | 6 - arch/csr/mhpmcounter25h.yaml | 6 - arch/csr/mhpmcounter26.yaml | 6 - arch/csr/mhpmcounter26h.yaml | 6 - arch/csr/mhpmcounter27.yaml | 6 - arch/csr/mhpmcounter27h.yaml | 6 - arch/csr/mhpmcounter28.yaml | 6 - arch/csr/mhpmcounter28h.yaml | 6 - arch/csr/mhpmcounter29.yaml | 6 - arch/csr/mhpmcounter29h.yaml | 6 - arch/csr/mhpmcounter3.yaml | 6 - arch/csr/mhpmcounter30.yaml | 6 - arch/csr/mhpmcounter30h.yaml | 6 - arch/csr/mhpmcounter31.yaml | 6 - arch/csr/mhpmcounter31h.yaml | 6 - arch/csr/mhpmcounter3h.yaml | 6 - arch/csr/mhpmcounter4.yaml | 6 - arch/csr/mhpmcounter4h.yaml | 6 - arch/csr/mhpmcounter5.yaml | 6 - arch/csr/mhpmcounter5h.yaml | 6 - arch/csr/mhpmcounter6.yaml | 6 - arch/csr/mhpmcounter6h.yaml | 6 - arch/csr/mhpmcounter7.yaml | 6 - arch/csr/mhpmcounter7h.yaml | 6 - arch/csr/mhpmcounter8.yaml | 6 - arch/csr/mhpmcounter8h.yaml | 6 - arch/csr/mhpmcounter9.yaml | 6 - arch/csr/mhpmcounter9h.yaml | 6 - arch/csr/mhpmcounterN.layout | 46 - arch/csr/mhpmcounterNh.layout | 26 - arch/csr/mhpmevent10.yaml | 6 - arch/csr/mhpmevent10h.yaml | 6 - arch/csr/mhpmevent11.yaml | 6 - arch/csr/mhpmevent11h.yaml | 6 - arch/csr/mhpmevent12.yaml | 6 - arch/csr/mhpmevent12h.yaml | 6 - arch/csr/mhpmevent13.yaml | 6 - arch/csr/mhpmevent13h.yaml | 6 - arch/csr/mhpmevent14.yaml | 6 - arch/csr/mhpmevent14h.yaml | 6 - arch/csr/mhpmevent15.yaml | 6 - arch/csr/mhpmevent15h.yaml | 6 - arch/csr/mhpmevent16.yaml | 6 - arch/csr/mhpmevent16h.yaml | 6 - arch/csr/mhpmevent17.yaml | 6 - arch/csr/mhpmevent17h.yaml | 6 - arch/csr/mhpmevent18.yaml | 6 - arch/csr/mhpmevent18h.yaml | 6 - arch/csr/mhpmevent19.yaml | 6 - arch/csr/mhpmevent19h.yaml | 6 - arch/csr/mhpmevent20.yaml | 6 - arch/csr/mhpmevent20h.yaml | 6 - arch/csr/mhpmevent21.yaml | 6 - arch/csr/mhpmevent21h.yaml | 6 - arch/csr/mhpmevent22.yaml | 6 - arch/csr/mhpmevent22h.yaml | 6 - arch/csr/mhpmevent23.yaml | 6 - arch/csr/mhpmevent23h.yaml | 6 - arch/csr/mhpmevent24.yaml | 6 - arch/csr/mhpmevent24h.yaml | 6 - arch/csr/mhpmevent25.yaml | 6 - arch/csr/mhpmevent25h.yaml | 6 - arch/csr/mhpmevent26.yaml | 6 - arch/csr/mhpmevent26h.yaml | 6 - arch/csr/mhpmevent27.yaml | 6 - arch/csr/mhpmevent27h.yaml | 6 - arch/csr/mhpmevent28.yaml | 6 - arch/csr/mhpmevent28h.yaml | 6 - arch/csr/mhpmevent29.yaml | 6 - arch/csr/mhpmevent29h.yaml | 6 - arch/csr/mhpmevent3.yaml | 6 - arch/csr/mhpmevent30.yaml | 6 - arch/csr/mhpmevent30h.yaml | 6 - arch/csr/mhpmevent31.yaml | 6 - arch/csr/mhpmevent31h.yaml | 6 - arch/csr/mhpmevent3h.yaml | 6 - arch/csr/mhpmevent4.yaml | 6 - arch/csr/mhpmevent4h.yaml | 6 - arch/csr/mhpmevent5.yaml | 6 - arch/csr/mhpmevent5h.yaml | 6 - arch/csr/mhpmevent6.yaml | 6 - arch/csr/mhpmevent6h.yaml | 6 - arch/csr/mhpmevent7.yaml | 6 - arch/csr/mhpmevent7h.yaml | 6 - arch/csr/mhpmevent8.yaml | 6 - arch/csr/mhpmevent8h.yaml | 6 - arch/csr/mhpmevent9.yaml | 6 - arch/csr/mhpmevent9h.yaml | 6 - arch/csr/mhpmeventN.layout | 74 -- arch/csr/mhpmeventNh.layout | 82 -- arch/csr/mideleg.yaml | 9 +- arch/csr/minstret.yaml | 12 +- arch/csr/minstreth.yaml | 6 +- arch/csr/misa.yaml | 23 +- arch/csr/pmpaddr0.yaml | 5 - arch/csr/pmpaddr1.yaml | 5 - arch/csr/pmpaddr10.yaml | 5 - arch/csr/pmpaddr11.yaml | 5 - arch/csr/pmpaddr12.yaml | 5 - arch/csr/pmpaddr13.yaml | 5 - arch/csr/pmpaddr14.yaml | 5 - arch/csr/pmpaddr15.yaml | 5 - arch/csr/pmpaddr2.yaml | 5 - arch/csr/pmpaddr3.yaml | 5 - arch/csr/pmpaddr4.yaml | 5 - arch/csr/pmpaddr5.yaml | 5 - arch/csr/pmpaddr6.yaml | 5 - arch/csr/pmpaddr7.yaml | 5 - arch/csr/pmpaddr8.yaml | 5 - arch/csr/pmpaddr9.yaml | 5 - arch/csr/pmpaddrN.layout | 51 - arch/csr/pmpcfg0.yaml | 5 - arch/csr/pmpcfg1.yaml | 5 - arch/csr/pmpcfg10.yaml | 5 - arch/csr/pmpcfg11.yaml | 5 - arch/csr/pmpcfg12.yaml | 5 - arch/csr/pmpcfg13.yaml | 5 - arch/csr/pmpcfg14.yaml | 5 - arch/csr/pmpcfg15.yaml | 5 - arch/csr/pmpcfg2.yaml | 5 - arch/csr/pmpcfg3.yaml | 5 - arch/csr/pmpcfg4.yaml | 5 - arch/csr/pmpcfg5.yaml | 5 - arch/csr/pmpcfg6.yaml | 5 - arch/csr/pmpcfg7.yaml | 5 - arch/csr/pmpcfg8.yaml | 5 - arch/csr/pmpcfg9.yaml | 5 - arch/csr/pmpcfgN.layout | 82 -- arch/csr/scause.yaml | 8 +- arch/csr/scounteren.yaml | 92 -- arch/csr/sepc.yaml | 4 +- arch/csr/vscause.yaml | 5 +- arch/csr/vsepc.yaml | 4 +- arch/isa/globals.isa | 12 + {lib => backends/arch_gen/lib}/arch_gen.rb | 99 +- backends/arch_gen/tasks.rake | 45 + .../cfg_html_doc}/adoc_gen.rake | 42 +- .../cfg_html_doc}/html_gen.rake | 102 +- backends/cfg_html_doc/tasks.rake | 8 + .../cfg_html_doc/templates}/config.adoc.erb | 0 .../cfg_html_doc/templates}/csr.adoc.erb | 26 +- .../cfg_html_doc/templates}/ext.adoc.erb | 0 .../cfg_html_doc/templates}/func.adoc.erb | 0 .../cfg_html_doc/templates}/inst.adoc.erb | 0 .../cfg_html_doc/templates}/toc.adoc.erb | 0 .../ext_pdf_doc/tasks.rake | 25 +- .../ext_pdf_doc/templates}/ext_pdf.adoc.erb | 0 cfgs/config_validation.rb | 12 + cfgs/generic_rv64/params.yaml | 98 +- do | 9 +- lib/arch_def.rb | 656 ++++------ lib/idl.rb | 4 +- lib/idl/ast.rb | 32 +- lib/idl/symbol_table.rb | 10 + lib/idl/type.rb | 16 +- lib/validate.rb | 9 +- schemas/config_schema.json | 18 + schemas/csr_schema.json | 22 +- tasks/arch_gen.rake | 100 -- tasks/top.rake | 69 -- 467 files changed, 29687 insertions(+), 2249 deletions(-) create mode 100644 Rakefile create mode 100644 arch/csr/I/mcounteren.layout create mode 100644 arch/csr/I/mcounteren.yaml create mode 100644 arch/csr/I/pmpaddr0.yaml create mode 100644 arch/csr/I/pmpaddr1.yaml create mode 100644 arch/csr/I/pmpaddr10.yaml create mode 100644 arch/csr/I/pmpaddr11.yaml create mode 100644 arch/csr/I/pmpaddr12.yaml create mode 100644 arch/csr/I/pmpaddr13.yaml create mode 100644 arch/csr/I/pmpaddr14.yaml create mode 100644 arch/csr/I/pmpaddr15.yaml create mode 100644 arch/csr/I/pmpaddr16.yaml create mode 100644 arch/csr/I/pmpaddr17.yaml create mode 100644 arch/csr/I/pmpaddr18.yaml create mode 100644 arch/csr/I/pmpaddr19.yaml create mode 100644 arch/csr/I/pmpaddr2.yaml create mode 100644 arch/csr/I/pmpaddr20.yaml create mode 100644 arch/csr/I/pmpaddr21.yaml create mode 100644 arch/csr/I/pmpaddr22.yaml create mode 100644 arch/csr/I/pmpaddr23.yaml create mode 100644 arch/csr/I/pmpaddr24.yaml create mode 100644 arch/csr/I/pmpaddr25.yaml create mode 100644 arch/csr/I/pmpaddr26.yaml create mode 100644 arch/csr/I/pmpaddr27.yaml create mode 100644 arch/csr/I/pmpaddr28.yaml create mode 100644 arch/csr/I/pmpaddr29.yaml create mode 100644 arch/csr/I/pmpaddr3.yaml create mode 100644 arch/csr/I/pmpaddr30.yaml create mode 100644 arch/csr/I/pmpaddr31.yaml create mode 100644 arch/csr/I/pmpaddr32.yaml create mode 100644 arch/csr/I/pmpaddr33.yaml create mode 100644 arch/csr/I/pmpaddr34.yaml create mode 100644 arch/csr/I/pmpaddr35.yaml create mode 100644 arch/csr/I/pmpaddr36.yaml create mode 100644 arch/csr/I/pmpaddr37.yaml create mode 100644 arch/csr/I/pmpaddr38.yaml create mode 100644 arch/csr/I/pmpaddr39.yaml create mode 100644 arch/csr/I/pmpaddr4.yaml create mode 100644 arch/csr/I/pmpaddr40.yaml create mode 100644 arch/csr/I/pmpaddr41.yaml create mode 100644 arch/csr/I/pmpaddr42.yaml create mode 100644 arch/csr/I/pmpaddr43.yaml create mode 100644 arch/csr/I/pmpaddr44.yaml create mode 100644 arch/csr/I/pmpaddr45.yaml create mode 100644 arch/csr/I/pmpaddr46.yaml create mode 100644 arch/csr/I/pmpaddr47.yaml create mode 100644 arch/csr/I/pmpaddr48.yaml create mode 100644 arch/csr/I/pmpaddr49.yaml create mode 100644 arch/csr/I/pmpaddr5.yaml create mode 100644 arch/csr/I/pmpaddr50.yaml create mode 100644 arch/csr/I/pmpaddr51.yaml create mode 100644 arch/csr/I/pmpaddr52.yaml create mode 100644 arch/csr/I/pmpaddr53.yaml create mode 100644 arch/csr/I/pmpaddr54.yaml create mode 100644 arch/csr/I/pmpaddr55.yaml create mode 100644 arch/csr/I/pmpaddr56.yaml create mode 100644 arch/csr/I/pmpaddr57.yaml create mode 100644 arch/csr/I/pmpaddr58.yaml create mode 100644 arch/csr/I/pmpaddr59.yaml create mode 100644 arch/csr/I/pmpaddr6.yaml create mode 100644 arch/csr/I/pmpaddr60.yaml create mode 100644 arch/csr/I/pmpaddr61.yaml create mode 100644 arch/csr/I/pmpaddr62.yaml create mode 100644 arch/csr/I/pmpaddr63.yaml create mode 100644 arch/csr/I/pmpaddr7.yaml create mode 100644 arch/csr/I/pmpaddr8.yaml create mode 100644 arch/csr/I/pmpaddr9.yaml create mode 100644 arch/csr/I/pmpaddrN.layout create mode 100644 arch/csr/I/pmpcfg0.yaml create mode 100644 arch/csr/I/pmpcfg1.yaml create mode 100644 arch/csr/I/pmpcfg10.yaml create mode 100644 arch/csr/I/pmpcfg11.yaml create mode 100644 arch/csr/I/pmpcfg12.yaml create mode 100644 arch/csr/I/pmpcfg13.yaml create mode 100644 arch/csr/I/pmpcfg14.yaml create mode 100644 arch/csr/I/pmpcfg15.yaml create mode 100644 arch/csr/I/pmpcfg2.yaml create mode 100644 arch/csr/I/pmpcfg3.yaml create mode 100644 arch/csr/I/pmpcfg4.yaml create mode 100644 arch/csr/I/pmpcfg5.yaml create mode 100644 arch/csr/I/pmpcfg6.yaml create mode 100644 arch/csr/I/pmpcfg7.yaml create mode 100644 arch/csr/I/pmpcfg8.yaml create mode 100644 arch/csr/I/pmpcfg9.yaml create mode 100644 arch/csr/I/pmpcfgN.layout create mode 100644 arch/csr/S/scounteren.layout create mode 100644 arch/csr/S/scounteren.yaml rename arch/csr/{mcountinhibit.yaml => Zicntr/mcountinhibit.layout} (82%) create mode 100644 arch/csr/Zicntr/mcountinhibit.yaml create mode 100644 arch/csr/Zihpm/hpmcounter10.yaml create mode 100644 arch/csr/Zihpm/hpmcounter10h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter11.yaml create mode 100644 arch/csr/Zihpm/hpmcounter11h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter12.yaml create mode 100644 arch/csr/Zihpm/hpmcounter12h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter13.yaml create mode 100644 arch/csr/Zihpm/hpmcounter13h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter14.yaml create mode 100644 arch/csr/Zihpm/hpmcounter14h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter15.yaml create mode 100644 arch/csr/Zihpm/hpmcounter15h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter16.yaml create mode 100644 arch/csr/Zihpm/hpmcounter16h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter17.yaml create mode 100644 arch/csr/Zihpm/hpmcounter17h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter18.yaml create mode 100644 arch/csr/Zihpm/hpmcounter18h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter19.yaml create mode 100644 arch/csr/Zihpm/hpmcounter19h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter20.yaml create mode 100644 arch/csr/Zihpm/hpmcounter20h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter21.yaml create mode 100644 arch/csr/Zihpm/hpmcounter21h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter22.yaml create mode 100644 arch/csr/Zihpm/hpmcounter22h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter23.yaml create mode 100644 arch/csr/Zihpm/hpmcounter23h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter24.yaml create mode 100644 arch/csr/Zihpm/hpmcounter24h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter25.yaml create mode 100644 arch/csr/Zihpm/hpmcounter25h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter26.yaml create mode 100644 arch/csr/Zihpm/hpmcounter26h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter27.yaml create mode 100644 arch/csr/Zihpm/hpmcounter27h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter28.yaml create mode 100644 arch/csr/Zihpm/hpmcounter28h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter29.yaml create mode 100644 arch/csr/Zihpm/hpmcounter29h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter3.yaml create mode 100644 arch/csr/Zihpm/hpmcounter30.yaml create mode 100644 arch/csr/Zihpm/hpmcounter30h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter31.yaml create mode 100644 arch/csr/Zihpm/hpmcounter31h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter3h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter4.yaml create mode 100644 arch/csr/Zihpm/hpmcounter4h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter5.yaml create mode 100644 arch/csr/Zihpm/hpmcounter5h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter6.yaml create mode 100644 arch/csr/Zihpm/hpmcounter6h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter7.yaml create mode 100644 arch/csr/Zihpm/hpmcounter7h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter8.yaml create mode 100644 arch/csr/Zihpm/hpmcounter8h.yaml create mode 100644 arch/csr/Zihpm/hpmcounter9.yaml create mode 100644 arch/csr/Zihpm/hpmcounter9h.yaml create mode 100644 arch/csr/Zihpm/hpmcounterN.layout create mode 100644 arch/csr/Zihpm/hpmcounterNh.layout create mode 100644 arch/csr/Zihpm/mhpmcounter10.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter10h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter11.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter11h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter12.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter12h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter13.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter13h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter14.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter14h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter15.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter15h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter16.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter16h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter17.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter17h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter18.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter18h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter19.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter19h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter20.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter20h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter21.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter21h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter22.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter22h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter23.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter23h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter24.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter24h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter25.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter25h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter26.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter26h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter27.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter27h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter28.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter28h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter29.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter29h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter3.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter30.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter30h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter31.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter31h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter3h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter4.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter4h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter5.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter5h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter6.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter6h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter7.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter7h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter8.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter8h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter9.yaml create mode 100644 arch/csr/Zihpm/mhpmcounter9h.yaml create mode 100644 arch/csr/Zihpm/mhpmcounterN.layout create mode 100644 arch/csr/Zihpm/mhpmcounterNh.layout create mode 100644 arch/csr/Zihpm/mhpmevent10.yaml create mode 100644 arch/csr/Zihpm/mhpmevent10h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent11.yaml create mode 100644 arch/csr/Zihpm/mhpmevent11h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent12.yaml create mode 100644 arch/csr/Zihpm/mhpmevent12h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent13.yaml create mode 100644 arch/csr/Zihpm/mhpmevent13h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent14.yaml create mode 100644 arch/csr/Zihpm/mhpmevent14h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent15.yaml create mode 100644 arch/csr/Zihpm/mhpmevent15h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent16.yaml create mode 100644 arch/csr/Zihpm/mhpmevent16h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent17.yaml create mode 100644 arch/csr/Zihpm/mhpmevent17h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent18.yaml create mode 100644 arch/csr/Zihpm/mhpmevent18h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent19.yaml create mode 100644 arch/csr/Zihpm/mhpmevent19h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent20.yaml create mode 100644 arch/csr/Zihpm/mhpmevent20h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent21.yaml create mode 100644 arch/csr/Zihpm/mhpmevent21h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent22.yaml create mode 100644 arch/csr/Zihpm/mhpmevent22h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent23.yaml create mode 100644 arch/csr/Zihpm/mhpmevent23h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent24.yaml create mode 100644 arch/csr/Zihpm/mhpmevent24h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent25.yaml create mode 100644 arch/csr/Zihpm/mhpmevent25h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent26.yaml create mode 100644 arch/csr/Zihpm/mhpmevent26h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent27.yaml create mode 100644 arch/csr/Zihpm/mhpmevent27h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent28.yaml create mode 100644 arch/csr/Zihpm/mhpmevent28h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent29.yaml create mode 100644 arch/csr/Zihpm/mhpmevent29h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent3.yaml create mode 100644 arch/csr/Zihpm/mhpmevent30.yaml create mode 100644 arch/csr/Zihpm/mhpmevent30h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent31.yaml create mode 100644 arch/csr/Zihpm/mhpmevent31h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent3h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent4.yaml create mode 100644 arch/csr/Zihpm/mhpmevent4h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent5.yaml create mode 100644 arch/csr/Zihpm/mhpmevent5h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent6.yaml create mode 100644 arch/csr/Zihpm/mhpmevent6h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent7.yaml create mode 100644 arch/csr/Zihpm/mhpmevent7h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent8.yaml create mode 100644 arch/csr/Zihpm/mhpmevent8h.yaml create mode 100644 arch/csr/Zihpm/mhpmevent9.yaml create mode 100644 arch/csr/Zihpm/mhpmevent9h.yaml create mode 100644 arch/csr/Zihpm/mhpmeventN.layout create mode 100644 arch/csr/Zihpm/mhpmeventNh.layout create mode 100644 arch/csr/cycleh.yaml delete mode 100644 arch/csr/mcounteren.yaml create mode 100644 arch/csr/mcycleh.yaml delete mode 100644 arch/csr/mhpmcounter10.yaml delete mode 100644 arch/csr/mhpmcounter10h.yaml delete mode 100644 arch/csr/mhpmcounter11.yaml delete mode 100644 arch/csr/mhpmcounter11h.yaml delete mode 100644 arch/csr/mhpmcounter12.yaml delete mode 100644 arch/csr/mhpmcounter12h.yaml delete mode 100644 arch/csr/mhpmcounter13.yaml delete mode 100644 arch/csr/mhpmcounter13h.yaml delete mode 100644 arch/csr/mhpmcounter14.yaml delete mode 100644 arch/csr/mhpmcounter14h.yaml delete mode 100644 arch/csr/mhpmcounter15.yaml delete mode 100644 arch/csr/mhpmcounter15h.yaml delete mode 100644 arch/csr/mhpmcounter16.yaml delete mode 100644 arch/csr/mhpmcounter16h.yaml delete mode 100644 arch/csr/mhpmcounter17.yaml delete mode 100644 arch/csr/mhpmcounter17h.yaml delete mode 100644 arch/csr/mhpmcounter18.yaml delete mode 100644 arch/csr/mhpmcounter18h.yaml delete mode 100644 arch/csr/mhpmcounter19.yaml delete mode 100644 arch/csr/mhpmcounter19h.yaml delete mode 100644 arch/csr/mhpmcounter20.yaml delete mode 100644 arch/csr/mhpmcounter20h.yaml delete mode 100644 arch/csr/mhpmcounter21.yaml delete mode 100644 arch/csr/mhpmcounter21h.yaml delete mode 100644 arch/csr/mhpmcounter22.yaml delete mode 100644 arch/csr/mhpmcounter22h.yaml delete mode 100644 arch/csr/mhpmcounter23.yaml delete mode 100644 arch/csr/mhpmcounter23h.yaml delete mode 100644 arch/csr/mhpmcounter24.yaml delete mode 100644 arch/csr/mhpmcounter24h.yaml delete mode 100644 arch/csr/mhpmcounter25.yaml delete mode 100644 arch/csr/mhpmcounter25h.yaml delete mode 100644 arch/csr/mhpmcounter26.yaml delete mode 100644 arch/csr/mhpmcounter26h.yaml delete mode 100644 arch/csr/mhpmcounter27.yaml delete mode 100644 arch/csr/mhpmcounter27h.yaml delete mode 100644 arch/csr/mhpmcounter28.yaml delete mode 100644 arch/csr/mhpmcounter28h.yaml delete mode 100644 arch/csr/mhpmcounter29.yaml delete mode 100644 arch/csr/mhpmcounter29h.yaml delete mode 100644 arch/csr/mhpmcounter3.yaml delete mode 100644 arch/csr/mhpmcounter30.yaml delete mode 100644 arch/csr/mhpmcounter30h.yaml delete mode 100644 arch/csr/mhpmcounter31.yaml delete mode 100644 arch/csr/mhpmcounter31h.yaml delete mode 100644 arch/csr/mhpmcounter3h.yaml delete mode 100644 arch/csr/mhpmcounter4.yaml delete mode 100644 arch/csr/mhpmcounter4h.yaml delete mode 100644 arch/csr/mhpmcounter5.yaml delete mode 100644 arch/csr/mhpmcounter5h.yaml delete mode 100644 arch/csr/mhpmcounter6.yaml delete mode 100644 arch/csr/mhpmcounter6h.yaml delete mode 100644 arch/csr/mhpmcounter7.yaml delete mode 100644 arch/csr/mhpmcounter7h.yaml delete mode 100644 arch/csr/mhpmcounter8.yaml delete mode 100644 arch/csr/mhpmcounter8h.yaml delete mode 100644 arch/csr/mhpmcounter9.yaml delete mode 100644 arch/csr/mhpmcounter9h.yaml delete mode 100644 arch/csr/mhpmcounterN.layout delete mode 100644 arch/csr/mhpmcounterNh.layout delete mode 100644 arch/csr/mhpmevent10.yaml delete mode 100644 arch/csr/mhpmevent10h.yaml delete mode 100644 arch/csr/mhpmevent11.yaml delete mode 100644 arch/csr/mhpmevent11h.yaml delete mode 100644 arch/csr/mhpmevent12.yaml delete mode 100644 arch/csr/mhpmevent12h.yaml delete mode 100644 arch/csr/mhpmevent13.yaml delete mode 100644 arch/csr/mhpmevent13h.yaml delete mode 100644 arch/csr/mhpmevent14.yaml delete mode 100644 arch/csr/mhpmevent14h.yaml delete mode 100644 arch/csr/mhpmevent15.yaml delete mode 100644 arch/csr/mhpmevent15h.yaml delete mode 100644 arch/csr/mhpmevent16.yaml delete mode 100644 arch/csr/mhpmevent16h.yaml delete mode 100644 arch/csr/mhpmevent17.yaml delete mode 100644 arch/csr/mhpmevent17h.yaml delete mode 100644 arch/csr/mhpmevent18.yaml delete mode 100644 arch/csr/mhpmevent18h.yaml delete mode 100644 arch/csr/mhpmevent19.yaml delete mode 100644 arch/csr/mhpmevent19h.yaml delete mode 100644 arch/csr/mhpmevent20.yaml delete mode 100644 arch/csr/mhpmevent20h.yaml delete mode 100644 arch/csr/mhpmevent21.yaml delete mode 100644 arch/csr/mhpmevent21h.yaml delete mode 100644 arch/csr/mhpmevent22.yaml delete mode 100644 arch/csr/mhpmevent22h.yaml delete mode 100644 arch/csr/mhpmevent23.yaml delete mode 100644 arch/csr/mhpmevent23h.yaml delete mode 100644 arch/csr/mhpmevent24.yaml delete mode 100644 arch/csr/mhpmevent24h.yaml delete mode 100644 arch/csr/mhpmevent25.yaml delete mode 100644 arch/csr/mhpmevent25h.yaml delete mode 100644 arch/csr/mhpmevent26.yaml delete mode 100644 arch/csr/mhpmevent26h.yaml delete mode 100644 arch/csr/mhpmevent27.yaml delete mode 100644 arch/csr/mhpmevent27h.yaml delete mode 100644 arch/csr/mhpmevent28.yaml delete mode 100644 arch/csr/mhpmevent28h.yaml delete mode 100644 arch/csr/mhpmevent29.yaml delete mode 100644 arch/csr/mhpmevent29h.yaml delete mode 100644 arch/csr/mhpmevent3.yaml delete mode 100644 arch/csr/mhpmevent30.yaml delete mode 100644 arch/csr/mhpmevent30h.yaml delete mode 100644 arch/csr/mhpmevent31.yaml delete mode 100644 arch/csr/mhpmevent31h.yaml delete mode 100644 arch/csr/mhpmevent3h.yaml delete mode 100644 arch/csr/mhpmevent4.yaml delete mode 100644 arch/csr/mhpmevent4h.yaml delete mode 100644 arch/csr/mhpmevent5.yaml delete mode 100644 arch/csr/mhpmevent5h.yaml delete mode 100644 arch/csr/mhpmevent6.yaml delete mode 100644 arch/csr/mhpmevent6h.yaml delete mode 100644 arch/csr/mhpmevent7.yaml delete mode 100644 arch/csr/mhpmevent7h.yaml delete mode 100644 arch/csr/mhpmevent8.yaml delete mode 100644 arch/csr/mhpmevent8h.yaml delete mode 100644 arch/csr/mhpmevent9.yaml delete mode 100644 arch/csr/mhpmevent9h.yaml delete mode 100644 arch/csr/mhpmeventN.layout delete mode 100644 arch/csr/mhpmeventNh.layout delete mode 100644 arch/csr/pmpaddr0.yaml delete mode 100644 arch/csr/pmpaddr1.yaml delete mode 100644 arch/csr/pmpaddr10.yaml delete mode 100644 arch/csr/pmpaddr11.yaml delete mode 100644 arch/csr/pmpaddr12.yaml delete mode 100644 arch/csr/pmpaddr13.yaml delete mode 100644 arch/csr/pmpaddr14.yaml delete mode 100644 arch/csr/pmpaddr15.yaml delete mode 100644 arch/csr/pmpaddr2.yaml delete mode 100644 arch/csr/pmpaddr3.yaml delete mode 100644 arch/csr/pmpaddr4.yaml delete mode 100644 arch/csr/pmpaddr5.yaml delete mode 100644 arch/csr/pmpaddr6.yaml delete mode 100644 arch/csr/pmpaddr7.yaml delete mode 100644 arch/csr/pmpaddr8.yaml delete mode 100644 arch/csr/pmpaddr9.yaml delete mode 100644 arch/csr/pmpaddrN.layout delete mode 100644 arch/csr/pmpcfg0.yaml delete mode 100644 arch/csr/pmpcfg1.yaml delete mode 100644 arch/csr/pmpcfg10.yaml delete mode 100644 arch/csr/pmpcfg11.yaml delete mode 100644 arch/csr/pmpcfg12.yaml delete mode 100644 arch/csr/pmpcfg13.yaml delete mode 100644 arch/csr/pmpcfg14.yaml delete mode 100644 arch/csr/pmpcfg15.yaml delete mode 100644 arch/csr/pmpcfg2.yaml delete mode 100644 arch/csr/pmpcfg3.yaml delete mode 100644 arch/csr/pmpcfg4.yaml delete mode 100644 arch/csr/pmpcfg5.yaml delete mode 100644 arch/csr/pmpcfg6.yaml delete mode 100644 arch/csr/pmpcfg7.yaml delete mode 100644 arch/csr/pmpcfg8.yaml delete mode 100644 arch/csr/pmpcfg9.yaml delete mode 100644 arch/csr/pmpcfgN.layout delete mode 100644 arch/csr/scounteren.yaml rename {lib => backends/arch_gen/lib}/arch_gen.rb (89%) create mode 100644 backends/arch_gen/tasks.rake rename {tasks => backends/cfg_html_doc}/adoc_gen.rake (62%) rename {tasks => backends/cfg_html_doc}/html_gen.rake (65%) create mode 100644 backends/cfg_html_doc/tasks.rake rename {views/adoc => backends/cfg_html_doc/templates}/config.adoc.erb (100%) rename {views/adoc => backends/cfg_html_doc/templates}/csr.adoc.erb (74%) rename {views/adoc => backends/cfg_html_doc/templates}/ext.adoc.erb (100%) rename {views/adoc => backends/cfg_html_doc/templates}/func.adoc.erb (100%) rename {views/adoc => backends/cfg_html_doc/templates}/inst.adoc.erb (100%) rename {views/adoc => backends/cfg_html_doc/templates}/toc.adoc.erb (100%) rename tasks/ext_pdf_gen.rake => backends/ext_pdf_doc/tasks.rake (77%) rename {views/adoc => backends/ext_pdf_doc/templates}/ext_pdf.adoc.erb (100%) delete mode 100644 tasks/arch_gen.rake delete mode 100644 tasks/top.rake diff --git a/Rakefile b/Rakefile new file mode 100644 index 000000000..bd91226b3 --- /dev/null +++ b/Rakefile @@ -0,0 +1,216 @@ +# frozen_string_literal: true + +$root = Pathname.new(__FILE__).dirname.realpath +$lib = $root / "lib" + +require "yard" +require "minitest/test_task" + +require_relative $root / "lib" / "validate" + +directory "#{$root}/.stamps" + +Dir.glob("#{$root}/backends/*/tasks.rake") do |rakefile| + load rakefile +end + +directory "#{$root}/.stamps" + +file "#{$root}/.stamps/dev_gems" => "#{$root}/.stamps" do + Dir.chdir($root) do + sh "bundle config set --local with development" + sh "bundle install" + FileUtils.touch "#{$root}/.stamps/dev_gems" + end +end + +namespace :gen do + desc "Generate documentation for the ruby tooling" + task tool_doc: "#{$root}/.stamps/dev_gems" do + Dir.chdir($root) do + sh "bundle exec yard doc" + end + end +end + +namespace :serve do + desc <<~DESC + Start an HTML server to view the generated HTML documentation for the tool + + The default port is 8000, though it can be overridden with an argument + DESC + task :tool_doc, [:port] => "gen:tool_doc" do |_t, args| + args.with_defaults(port: 8000) + + puts <<~MSG + Server will come up on http://#{`hostname`.strip}:#{args[:port]}. + It will regenerate the documentation on every access + + MSG + sh "yard server -p #{args[:port]} --reload" + end +end + +Minitest::TestTask.create :idl_test do |t| + t.test_globs = ["#{$root}/lib/idl/tests/test_*.rb"] +end + +desc "Clean up all generated files" +task :clean do + FileUtils.rm_rf $root / "gen" + FileUtils.rm_rf $root / ".stamps" +end + +desc "Validate the arch docs" +task validate: "gen:arch" do + validator = Validator.instance + Dir.glob("#{$root}/arch/**/*.yaml") do |f| + validator.validate(f) + end + puts "All files validate against their schema" +end + +def insert_warning(str, from) + # insert a warning on the second line + lines = str.lines + first_line = lines.shift + lines.unshift(first_line, "\n# WARNING: This file is auto-generated from #{Pathname.new(from).relative_path_from($root)}\n\n").join("") +end + +(3..31).each do |hpm_num| + file "#{$root}/arch/csr/Zihpm/mhpmcounter#{hpm_num}.yaml" => [ + "#{$root}/arch/csr/Zihpm/mhpmcounterN.layout", + __FILE__ + ] do |t| + puts "Generating #{Pathname.new(t.name).relative_path_from($root)}" + erb = ERB.new(File.read($root / "arch/csr/Zihpm/mhpmcounterN.layout"), trim_mode: "-") + erb.filename = "#{$root}/arch/csr/Zihpm/mhpmcounterN.layout" + File.write(t.name, insert_warning(erb.result(binding), t.prerequisites.first)) + end + file "#{$root}/arch/csr/Zihpm/mhpmcounter#{hpm_num}h.yaml" => [ + "#{$root}/arch/csr/Zihpm/mhpmcounterNh.layout", + __FILE__ + ] do |t| + puts "Generating #{Pathname.new(t.name).relative_path_from($root)}" + erb = ERB.new(File.read($root / "arch/csr/Zihpm/mhpmcounterNh.layout"), trim_mode: "-") + erb.filename = "#{$root}/arch/csr/Zihpm/mhpmcounterNh.layout" + File.write(t.name, insert_warning(erb.result(binding), t.prerequisites.first)) + end + file "#{$root}/arch/csr/Zihpm/mhpmevent#{hpm_num}.yaml" => [ + "#{$root}/arch/csr/Zihpm/mhpmeventN.layout", + __FILE__ + ] do |t| + puts "Generating #{Pathname.new(t.name).relative_path_from($root)}" + erb = ERB.new(File.read($root / "arch/csr/Zihpm/mhpmeventN.layout"), trim_mode: "-") + erb.filename = "#{$root}/arch/csr/Zihpm/mhpmeventN.layout" + File.write(t.name, insert_warning(erb.result(binding), t.prerequisites.first)) + end + file "#{$root}/arch/csr/Zihpm/mhpmevent#{hpm_num}h.yaml" => [ + "#{$root}/arch/csr/Zihpm/mhpmeventNh.layout", + __FILE__ + ] do |t| + puts "Generating #{Pathname.new(t.name).relative_path_from($root)}" + erb = ERB.new(File.read($root / "arch/csr/Zihpm/mhpmeventNh.layout"), trim_mode: "-") + erb.filename = "#{$root}/arch/csr/Zihpm/mhpmeventNh.layout" + File.write(t.name, insert_warning(erb.result(binding), t.prerequisites.first)) + end + file "#{$root}/arch/csr/Zihpm/hpmcounter#{hpm_num}.yaml" => [ + "#{$root}/arch/csr/Zihpm/hpmcounterN.layout", + __FILE__ + ] do |t| + puts "Generating #{Pathname.new(t.name).relative_path_from($root)}" + erb = ERB.new(File.read($root / "arch/csr/Zihpm/hpmcounterN.layout"), trim_mode: "-") + erb.filename = "#{$root}/arch/csr/Zihpm/hpmcounterN.layout" + File.write(t.name, insert_warning(erb.result(binding), t.prerequisites.first)) + end + file "#{$root}/arch/csr/Zihpm/hpmcounter#{hpm_num}h.yaml" => [ + "#{$root}/arch/csr/Zihpm/hpmcounterNh.layout", + __FILE__ + ] do |t| + puts "Generating #{Pathname.new(t.name).relative_path_from($root)}" + erb = ERB.new(File.read($root / "arch/csr/Zihpm/hpmcounterNh.layout"), trim_mode: "-") + erb.filename = "#{$root}/arch/csr/Zihpm/hpmcounterNh.layout" + File.write(t.name, insert_warning(erb.result(binding), t.prerequisites.first)) + end +end + +(0..63).each do |pmpaddr_num| + file "#{$root}/arch/csr/I/pmpaddr#{pmpaddr_num}.yaml" => [ + "#{$root}/arch/csr/I/pmpaddrN.layout", + __FILE__ + ] do |t| + puts "Generating #{Pathname.new(t.name).relative_path_from($root)}" + erb = ERB.new(File.read($root / "arch/csr/I/pmpaddrN.layout"), trim_mode: "-") + erb.filename = "#{$root}/arch/csr/I/pmpaddrN.layout" + File.write(t.name, insert_warning(erb.result(binding), t.prerequisites.first)) + end +end + +(0..15).each do |pmpcfg_num| + file "#{$root}/arch/csr/I/pmpcfg#{pmpcfg_num}.yaml" => [ + "#{$root}/arch/csr/I/pmpcfgN.layout", + __FILE__ + ] do |t| + puts "Generating #{Pathname.new(t.name).relative_path_from($root)}" + erb = ERB.new(File.read($root / "arch/csr/I/pmpcfgN.layout"), trim_mode: "-") + erb.filename = "#{$root}/arch/csr/I/pmpcfgN.layout" + File.write(t.name, insert_warning(erb.result(binding), t.prerequisites.first)) + end +end + +file "#{$root}/arch/csr/I/mcounteren.yaml" => [ + "#{$root}/arch/csr/I/mcounteren.layout", + __FILE__ +] do |t| + puts "Generating #{Pathname.new(t.name).relative_path_from($root)}" + erb = ERB.new(File.read($root / "arch/csr/I/mcounteren.layout"), trim_mode: "-") + erb.filename = "#{$root}/arch/csr/I/mcounteren.layout" + File.write(t.name, insert_warning(erb.result(binding), t.prerequisites.first)) +end + +file "#{$root}/arch/csr/S/scounteren.yaml" => [ + "#{$root}/arch/csr/S/scounteren.layout", + __FILE__ +] do |t| + puts "Generating #{Pathname.new(t.name).relative_path_from($root)}" + erb = ERB.new(File.read($root / "arch/csr/S/scounteren.layout"), trim_mode: "-") + erb.filename = "#{$root}/arch/csr/S/scounteren.layout" + File.write(t.name, insert_warning(erb.result(binding), t.prerequisites.first)) +end + +file "#{$root}/arch/csr/Zicntr/mcountinhibit.yaml" => [ + "#{$root}/arch/csr/Zicntr/mcountinhibit.layout", + __FILE__ +] do |t| + puts "Generating #{Pathname.new(t.name).relative_path_from($root)}" + erb = ERB.new(File.read($root / "arch/csr/Zicntr/mcountinhibit.layout"), trim_mode: "-") + erb.filename = "#{$root}/arch/csr/Zicntr/mcountinhibit.layout" + File.write(t.name, insert_warning(erb.result(binding), t.prerequisites.first)) +end + +namespace :gen do + desc "Generate architecture files from layouts" + task :arch do + (3..31).each do |hpm_num| + Rake::Task["#{$root}/arch/csr/Zihpm/mhpmcounter#{hpm_num}.yaml"].invoke + Rake::Task["#{$root}/arch/csr/Zihpm/mhpmcounter#{hpm_num}h.yaml"].invoke + Rake::Task["#{$root}/arch/csr/Zihpm/mhpmevent#{hpm_num}.yaml"].invoke + Rake::Task["#{$root}/arch/csr/Zihpm/mhpmevent#{hpm_num}h.yaml"].invoke + + Rake::Task["#{$root}/arch/csr/Zihpm/hpmcounter#{hpm_num}.yaml"].invoke + Rake::Task["#{$root}/arch/csr/Zihpm/hpmcounter#{hpm_num}h.yaml"].invoke + end + + Rake::Task["#{$root}/arch/csr/I/mcounteren.yaml"].invoke + Rake::Task["#{$root}/arch/csr/S/scounteren.yaml"].invoke + Rake::Task["#{$root}/arch/csr/Zicntr/mcountinhibit.yaml"].invoke + + (0..63).each do |pmpaddr_num| + Rake::Task["#{$root}/arch/csr/I/pmpaddr#{pmpaddr_num}.yaml"].invoke + end + + (0..15).each do |pmpcfg_num| + Rake::Task["#{$root}/arch/csr/I/pmpcfg#{pmpcfg_num}.yaml"].invoke + end + end +end diff --git a/arch/csr/I/mcounteren.layout b/arch/csr/I/mcounteren.layout new file mode 100644 index 000000000..31a2f1db3 --- /dev/null +++ b/arch/csr/I/mcounteren.layout @@ -0,0 +1,186 @@ +# yaml-language-server: $schema=../../schemas/csr_schema.json + +mcounteren: + long_name: Machine Counter Enable + address: 0x306 + priv_mode: M + length: 32 + description: | + The counter-enable `mcounteren` register is a 32-bit register that controls the availability + of the hardware performance-monitoring counters to + <%%- if ext?(:S) -%> + S-mode + <%%- elsif ext?(:U) -%> + U-mode + <%%- else -%> + the next-lower privileged mode + <%%- end -%> + . + + The settings in this register only control accessibility. The act of reading or writing this + register does not affect the underlying counters, which continue to increment even when not + accessible. + + When the CY, TM, IR, or HPMn bit in the mcounteren register is clear, attempts to read the + `cycle`, `time`, `instret`, or `hpmcountern` register while executing in + <%%- if ext?(:S) -%> + S-mode + <%%- elsif ext?(:U) -%> + U-mode + <%%- else -%> + S-mode or U-mode + <%%- end -%> + will cause an `IllegalInstruction` exception. When one of these bits is set, access to the + corresponding register is permitted in + <%%- if ext?(:S) -%> + S-mode + <%%- elsif ext?(:U) -%> + U-mode + <%%- else -%> + the next implemented privilege mode (S-mode if implemented, otherwise U-mode). + <%%- end -%> + + [NOTE] + The counter-enable bits support two common use cases with minimal hardware. + For harts that do not need high-performance timers and counters, machine-mode software can + trap accesses and implement all features in software. For harts that need high-performance + timers and counters but are not concerned with obfuscating the underlying hardware counters, + the counters can be directly exposed to lower privilege modes. + + The `cycle`, `instret`, and `hpmcountern` CSRs are read-only shadows of `mcycle`, `minstret`, + and `mhpmcounter n`, respectively. The `time` CSR is a read-only shadow of the memory-mapped + `mtime` register. + <%%- if possible_xlens.include?(32) -%> + Analogously, on RV32I the `cycleh`, `instreth` and `hpmcounternh` CSRs are + read-only shadows of `mcycleh`, `minstreth` and `mhpmcounternh`, respectively. + On RV32I the `timeh` CSR is a read-only shadow of the upper 32 bits of the memory-mapped `mtime` + register, while time shadows only the lower 32 bits of `mtime`. + <%%- end -%> + + [NOTE] + Implementations can convert reads of the `time` and `timeh` CSRs into loads to the + memory-mapped `mtime` register, or emulate this functionality on behalf of less-privileged + modes in M-mode software. + + <%%- if !ext?(:U) -%> + In harts with U-mode, the `mcounteren` CSR must be implemented, but all fields are WARL and may + be read-only zero, indicating reads to the corresponding counter will cause an + `IllegalInstruction` exception when executing in a less-privileged mode. + In harts without U-mode, the `mcounteren` register should not exist. + <%%- end -%> + + <%%- if ext?(:S) -%> + [INFO] + The `cycle`, `instret`, and `hpmcountern` CSRs can also be made available to U-mode + through the `scounteren` CSR + <%%- if ext?(:H) -%> + and to VS-mode and/or VU-mode through `hcounteren` + <%%- end -%> + . + <%%- end -%> + + + definedBy: U # actually, defined by RV64, but must implement U-mode for this CSR to exist + fields: + CY: + location: 0 + description: | + When set, the `cycle` CSR (an alias of `mcycle`) is accessible to + <%%- if ext?(:S) -%> + S-mode. + <%%- else -%> + U-mode. + <%%- end -%> + + <%%- if ext?(:S) -%> + When `scounteren.CY` is also set, `cycle` is futher accessible to U-mode. + <%%- end -%> + + <%%- if ext?(:H) -%> + When `hcounteren.CY` is also set, `cycle` is futher accessible to VS-mode. + + When `hcounteren.CY` && `scounteren.CY` are both set, `cycle` is futher accessible to VU-mode. + <%%- end -%> + type(): | + if (COUNTENABLE_EN[2]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[2]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + 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 + IR: + location: 2 + description: | + When set, the `instret` CSR (an alias of `minstret`) is accessible to + <%%- if ext?(:S) -%> + S-mode. + <%%- else -%> + U-mode. + <%%- end -%> + + <%%- if ext?(:S) -%> + When `scounteren.IR` is also set, `instret` is futher accessible to U-mode. + <%%- end -%> + + <%%- if ext?(:H) -%> + When `hcounteren.IR` is also set, `instret` is futher accessible to VS-mode. + + When `hcounteren.IR` && `scounteren.IR` are both set, `instret` is futher accessible to VU-mode. + <%%- end -%> + type(): | + if (COUNTENABLE_EN[2]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[2]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + <%- (3..31).each do |hpm_num| -%> + HPM<%= hpm_num %>: + location: <%= hpm_num %> + description: | + When set, the `hpmcounter<%= hpm_num %>` CSR (an alias of `mhpmcounter<%= hpm_num %>`) is accessible to + <%%- if ext?(:S) -%> + S-mode. + <%%- else -%> + U-mode. + <%%- end -%> + + <%%- if ext?(:S) -%> + When `scounteren.HPM<%= hpm_num %>` is also set, `hpmcounter<%= hpm_num %>` is futher accessible to U-mode. + <%%- end -%> + + <%%- if ext?(:H) -%> + When `hcounteren.HPM<%= hpm_num %>` is also set, `hpmcounter<%= hpm_num %>` is futher accessible to VS-mode. + + When `hcounteren.HPM<%= hpm_num %>` && `scounteren.HPM<%= hpm_num %>` are both set, `hpmcounter<%= hpm_num %>` is futher accessible to VU-mode. + <%%- end -%> + type(): | + if (COUNTENABLE_EN[<%= hpm_num %>]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[<%= hpm_num %>]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + <%- end -%> diff --git a/arch/csr/I/mcounteren.yaml b/arch/csr/I/mcounteren.yaml new file mode 100644 index 000000000..4bc0daedd --- /dev/null +++ b/arch/csr/I/mcounteren.yaml @@ -0,0 +1,1055 @@ +# yaml-language-server: $schema=../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/mcounteren.layout + + +mcounteren: + long_name: Machine Counter Enable + address: 0x306 + priv_mode: M + length: 32 + description: | + The counter-enable `mcounteren` register is a 32-bit register that controls the availability + of the hardware performance-monitoring counters to + <%- if ext?(:S) -%> + S-mode + <%- elsif ext?(:U) -%> + U-mode + <%- else -%> + the next-lower privileged mode + <%- end -%> + . + + The settings in this register only control accessibility. The act of reading or writing this + register does not affect the underlying counters, which continue to increment even when not + accessible. + + When the CY, TM, IR, or HPMn bit in the mcounteren register is clear, attempts to read the + `cycle`, `time`, `instret`, or `hpmcountern` register while executing in + <%- if ext?(:S) -%> + S-mode + <%- elsif ext?(:U) -%> + U-mode + <%- else -%> + S-mode or U-mode + <%- end -%> + will cause an `IllegalInstruction` exception. When one of these bits is set, access to the + corresponding register is permitted in + <%- if ext?(:S) -%> + S-mode + <%- elsif ext?(:U) -%> + U-mode + <%- else -%> + the next implemented privilege mode (S-mode if implemented, otherwise U-mode). + <%- end -%> + + [NOTE] + The counter-enable bits support two common use cases with minimal hardware. + For harts that do not need high-performance timers and counters, machine-mode software can + trap accesses and implement all features in software. For harts that need high-performance + timers and counters but are not concerned with obfuscating the underlying hardware counters, + the counters can be directly exposed to lower privilege modes. + + The `cycle`, `instret`, and `hpmcountern` CSRs are read-only shadows of `mcycle`, `minstret`, + and `mhpmcounter n`, respectively. The `time` CSR is a read-only shadow of the memory-mapped + `mtime` register. + <%- if possible_xlens.include?(32) -%> + Analogously, on RV32I the `cycleh`, `instreth` and `hpmcounternh` CSRs are + read-only shadows of `mcycleh`, `minstreth` and `mhpmcounternh`, respectively. + On RV32I the `timeh` CSR is a read-only shadow of the upper 32 bits of the memory-mapped `mtime` + register, while time shadows only the lower 32 bits of `mtime`. + <%- end -%> + + [NOTE] + Implementations can convert reads of the `time` and `timeh` CSRs into loads to the + memory-mapped `mtime` register, or emulate this functionality on behalf of less-privileged + modes in M-mode software. + + <%- if !ext?(:U) -%> + In harts with U-mode, the `mcounteren` CSR must be implemented, but all fields are WARL and may + be read-only zero, indicating reads to the corresponding counter will cause an + `IllegalInstruction` exception when executing in a less-privileged mode. + In harts without U-mode, the `mcounteren` register should not exist. + <%- end -%> + + <%- if ext?(:S) -%> + [INFO] + The `cycle`, `instret`, and `hpmcountern` CSRs can also be made available to U-mode + through the `scounteren` CSR + <%- if ext?(:H) -%> + and to VS-mode and/or VU-mode through `hcounteren` + <%- end -%> + . + <%- end -%> + + + definedBy: U # actually, defined by RV64, but must implement U-mode for this CSR to exist + fields: + CY: + location: 0 + description: | + When set, the `cycle` CSR (an alias of `mcycle`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.CY` is also set, `cycle` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.CY` is also set, `cycle` is futher accessible to VS-mode. + + When `hcounteren.CY` && `scounteren.CY` are both set, `cycle` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[2]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[2]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + 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 + IR: + location: 2 + description: | + When set, the `instret` CSR (an alias of `minstret`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.IR` is also set, `instret` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.IR` is also set, `instret` is futher accessible to VS-mode. + + When `hcounteren.IR` && `scounteren.IR` are both set, `instret` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[2]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[2]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM3: + location: 3 + description: | + When set, the `hpmcounter3` CSR (an alias of `mhpmcounter3`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM3` is also set, `hpmcounter3` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM3` is also set, `hpmcounter3` is futher accessible to VS-mode. + + When `hcounteren.HPM3` && `scounteren.HPM3` are both set, `hpmcounter3` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[3]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[3]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM4: + location: 4 + description: | + When set, the `hpmcounter4` CSR (an alias of `mhpmcounter4`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM4` is also set, `hpmcounter4` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM4` is also set, `hpmcounter4` is futher accessible to VS-mode. + + When `hcounteren.HPM4` && `scounteren.HPM4` are both set, `hpmcounter4` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[4]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[4]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM5: + location: 5 + description: | + When set, the `hpmcounter5` CSR (an alias of `mhpmcounter5`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM5` is also set, `hpmcounter5` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM5` is also set, `hpmcounter5` is futher accessible to VS-mode. + + When `hcounteren.HPM5` && `scounteren.HPM5` are both set, `hpmcounter5` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[5]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[5]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM6: + location: 6 + description: | + When set, the `hpmcounter6` CSR (an alias of `mhpmcounter6`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM6` is also set, `hpmcounter6` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM6` is also set, `hpmcounter6` is futher accessible to VS-mode. + + When `hcounteren.HPM6` && `scounteren.HPM6` are both set, `hpmcounter6` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[6]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[6]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM7: + location: 7 + description: | + When set, the `hpmcounter7` CSR (an alias of `mhpmcounter7`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM7` is also set, `hpmcounter7` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM7` is also set, `hpmcounter7` is futher accessible to VS-mode. + + When `hcounteren.HPM7` && `scounteren.HPM7` are both set, `hpmcounter7` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[7]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[7]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM8: + location: 8 + description: | + When set, the `hpmcounter8` CSR (an alias of `mhpmcounter8`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM8` is also set, `hpmcounter8` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM8` is also set, `hpmcounter8` is futher accessible to VS-mode. + + When `hcounteren.HPM8` && `scounteren.HPM8` are both set, `hpmcounter8` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[8]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[8]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM9: + location: 9 + description: | + When set, the `hpmcounter9` CSR (an alias of `mhpmcounter9`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM9` is also set, `hpmcounter9` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM9` is also set, `hpmcounter9` is futher accessible to VS-mode. + + When `hcounteren.HPM9` && `scounteren.HPM9` are both set, `hpmcounter9` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[9]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[9]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM10: + location: 10 + description: | + When set, the `hpmcounter10` CSR (an alias of `mhpmcounter10`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM10` is also set, `hpmcounter10` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM10` is also set, `hpmcounter10` is futher accessible to VS-mode. + + When `hcounteren.HPM10` && `scounteren.HPM10` are both set, `hpmcounter10` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[10]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[10]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM11: + location: 11 + description: | + When set, the `hpmcounter11` CSR (an alias of `mhpmcounter11`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM11` is also set, `hpmcounter11` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM11` is also set, `hpmcounter11` is futher accessible to VS-mode. + + When `hcounteren.HPM11` && `scounteren.HPM11` are both set, `hpmcounter11` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[11]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[11]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM12: + location: 12 + description: | + When set, the `hpmcounter12` CSR (an alias of `mhpmcounter12`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM12` is also set, `hpmcounter12` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM12` is also set, `hpmcounter12` is futher accessible to VS-mode. + + When `hcounteren.HPM12` && `scounteren.HPM12` are both set, `hpmcounter12` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[12]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[12]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM13: + location: 13 + description: | + When set, the `hpmcounter13` CSR (an alias of `mhpmcounter13`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM13` is also set, `hpmcounter13` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM13` is also set, `hpmcounter13` is futher accessible to VS-mode. + + When `hcounteren.HPM13` && `scounteren.HPM13` are both set, `hpmcounter13` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[13]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[13]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM14: + location: 14 + description: | + When set, the `hpmcounter14` CSR (an alias of `mhpmcounter14`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM14` is also set, `hpmcounter14` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM14` is also set, `hpmcounter14` is futher accessible to VS-mode. + + When `hcounteren.HPM14` && `scounteren.HPM14` are both set, `hpmcounter14` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[14]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[14]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM15: + location: 15 + description: | + When set, the `hpmcounter15` CSR (an alias of `mhpmcounter15`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM15` is also set, `hpmcounter15` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM15` is also set, `hpmcounter15` is futher accessible to VS-mode. + + When `hcounteren.HPM15` && `scounteren.HPM15` are both set, `hpmcounter15` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[15]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[15]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM16: + location: 16 + description: | + When set, the `hpmcounter16` CSR (an alias of `mhpmcounter16`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM16` is also set, `hpmcounter16` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM16` is also set, `hpmcounter16` is futher accessible to VS-mode. + + When `hcounteren.HPM16` && `scounteren.HPM16` are both set, `hpmcounter16` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[16]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[16]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM17: + location: 17 + description: | + When set, the `hpmcounter17` CSR (an alias of `mhpmcounter17`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM17` is also set, `hpmcounter17` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM17` is also set, `hpmcounter17` is futher accessible to VS-mode. + + When `hcounteren.HPM17` && `scounteren.HPM17` are both set, `hpmcounter17` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[17]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[17]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM18: + location: 18 + description: | + When set, the `hpmcounter18` CSR (an alias of `mhpmcounter18`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM18` is also set, `hpmcounter18` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM18` is also set, `hpmcounter18` is futher accessible to VS-mode. + + When `hcounteren.HPM18` && `scounteren.HPM18` are both set, `hpmcounter18` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[18]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[18]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM19: + location: 19 + description: | + When set, the `hpmcounter19` CSR (an alias of `mhpmcounter19`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM19` is also set, `hpmcounter19` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM19` is also set, `hpmcounter19` is futher accessible to VS-mode. + + When `hcounteren.HPM19` && `scounteren.HPM19` are both set, `hpmcounter19` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[19]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[19]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM20: + location: 20 + description: | + When set, the `hpmcounter20` CSR (an alias of `mhpmcounter20`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM20` is also set, `hpmcounter20` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM20` is also set, `hpmcounter20` is futher accessible to VS-mode. + + When `hcounteren.HPM20` && `scounteren.HPM20` are both set, `hpmcounter20` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[20]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[20]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM21: + location: 21 + description: | + When set, the `hpmcounter21` CSR (an alias of `mhpmcounter21`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM21` is also set, `hpmcounter21` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM21` is also set, `hpmcounter21` is futher accessible to VS-mode. + + When `hcounteren.HPM21` && `scounteren.HPM21` are both set, `hpmcounter21` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[21]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[21]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM22: + location: 22 + description: | + When set, the `hpmcounter22` CSR (an alias of `mhpmcounter22`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM22` is also set, `hpmcounter22` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM22` is also set, `hpmcounter22` is futher accessible to VS-mode. + + When `hcounteren.HPM22` && `scounteren.HPM22` are both set, `hpmcounter22` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[22]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[22]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM23: + location: 23 + description: | + When set, the `hpmcounter23` CSR (an alias of `mhpmcounter23`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM23` is also set, `hpmcounter23` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM23` is also set, `hpmcounter23` is futher accessible to VS-mode. + + When `hcounteren.HPM23` && `scounteren.HPM23` are both set, `hpmcounter23` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[23]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[23]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM24: + location: 24 + description: | + When set, the `hpmcounter24` CSR (an alias of `mhpmcounter24`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM24` is also set, `hpmcounter24` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM24` is also set, `hpmcounter24` is futher accessible to VS-mode. + + When `hcounteren.HPM24` && `scounteren.HPM24` are both set, `hpmcounter24` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[24]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[24]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM25: + location: 25 + description: | + When set, the `hpmcounter25` CSR (an alias of `mhpmcounter25`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM25` is also set, `hpmcounter25` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM25` is also set, `hpmcounter25` is futher accessible to VS-mode. + + When `hcounteren.HPM25` && `scounteren.HPM25` are both set, `hpmcounter25` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[25]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[25]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM26: + location: 26 + description: | + When set, the `hpmcounter26` CSR (an alias of `mhpmcounter26`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM26` is also set, `hpmcounter26` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM26` is also set, `hpmcounter26` is futher accessible to VS-mode. + + When `hcounteren.HPM26` && `scounteren.HPM26` are both set, `hpmcounter26` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[26]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[26]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM27: + location: 27 + description: | + When set, the `hpmcounter27` CSR (an alias of `mhpmcounter27`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM27` is also set, `hpmcounter27` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM27` is also set, `hpmcounter27` is futher accessible to VS-mode. + + When `hcounteren.HPM27` && `scounteren.HPM27` are both set, `hpmcounter27` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[27]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[27]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM28: + location: 28 + description: | + When set, the `hpmcounter28` CSR (an alias of `mhpmcounter28`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM28` is also set, `hpmcounter28` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM28` is also set, `hpmcounter28` is futher accessible to VS-mode. + + When `hcounteren.HPM28` && `scounteren.HPM28` are both set, `hpmcounter28` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[28]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[28]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM29: + location: 29 + description: | + When set, the `hpmcounter29` CSR (an alias of `mhpmcounter29`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM29` is also set, `hpmcounter29` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM29` is also set, `hpmcounter29` is futher accessible to VS-mode. + + When `hcounteren.HPM29` && `scounteren.HPM29` are both set, `hpmcounter29` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[29]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[29]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM30: + location: 30 + description: | + When set, the `hpmcounter30` CSR (an alias of `mhpmcounter30`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM30` is also set, `hpmcounter30` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM30` is also set, `hpmcounter30` is futher accessible to VS-mode. + + When `hcounteren.HPM30` && `scounteren.HPM30` are both set, `hpmcounter30` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[30]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[30]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + HPM31: + location: 31 + description: | + When set, the `hpmcounter31` CSR (an alias of `mhpmcounter31`) is accessible to + <%- if ext?(:S) -%> + S-mode. + <%- else -%> + U-mode. + <%- end -%> + + <%- if ext?(:S) -%> + When `scounteren.HPM31` is also set, `hpmcounter31` is futher accessible to U-mode. + <%- end -%> + + <%- if ext?(:H) -%> + When `hcounteren.HPM31` is also set, `hpmcounter31` is futher accessible to VS-mode. + + When `hcounteren.HPM31` && `scounteren.HPM31` are both set, `hpmcounter31` is futher accessible to VU-mode. + <%- end -%> + type(): | + if (COUNTENABLE_EN[31]) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (COUNTENABLE_EN[31]) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/I/pmpaddr0.yaml b/arch/csr/I/pmpaddr0.yaml new file mode 100644 index 000000000..b742489a1 --- /dev/null +++ b/arch/csr/I/pmpaddr0.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr0: + long_name: PMP Address 0 + address: 0x3B0 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 0 + (or, if `pmp1cfg.A` == TOR, for PMP entry 1). + type(): | + if (NUM_PMP_ENTRIES > 0) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 0) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 0) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg0].pmp0cfg[4] == 1)) { + return CSR[pmpaddr0].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg0].pmp0cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr0].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr0].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg0].pmp0cfg[4] == 1)) { + return CSR[pmpaddr0].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg0].pmp0cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr0].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr0].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr1.yaml b/arch/csr/I/pmpaddr1.yaml new file mode 100644 index 000000000..43b00bb13 --- /dev/null +++ b/arch/csr/I/pmpaddr1.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr1: + long_name: PMP Address 1 + address: 0x3B1 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 1 + (or, if `pmp2cfg.A` == TOR, for PMP entry 2). + type(): | + if (NUM_PMP_ENTRIES > 1) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 1) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 1) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg0].pmp1cfg[4] == 1)) { + return CSR[pmpaddr1].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg0].pmp1cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr1].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr1].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg0].pmp1cfg[4] == 1)) { + return CSR[pmpaddr1].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg0].pmp1cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr1].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr1].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr10.yaml b/arch/csr/I/pmpaddr10.yaml new file mode 100644 index 000000000..6682bbb57 --- /dev/null +++ b/arch/csr/I/pmpaddr10.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr10: + long_name: PMP Address 10 + address: 0x3BA + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 10 + (or, if `pmp11cfg.A` == TOR, for PMP entry 11). + type(): | + if (NUM_PMP_ENTRIES > 10) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 10) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 10) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg2].pmp10cfg[4] == 1)) { + return CSR[pmpaddr10].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg2].pmp10cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr10].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr10].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg2].pmp10cfg[4] == 1)) { + return CSR[pmpaddr10].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg2].pmp10cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr10].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr10].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr11.yaml b/arch/csr/I/pmpaddr11.yaml new file mode 100644 index 000000000..33e582d65 --- /dev/null +++ b/arch/csr/I/pmpaddr11.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr11: + long_name: PMP Address 11 + address: 0x3BB + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 11 + (or, if `pmp12cfg.A` == TOR, for PMP entry 12). + type(): | + if (NUM_PMP_ENTRIES > 11) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 11) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 11) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg2].pmp11cfg[4] == 1)) { + return CSR[pmpaddr11].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg2].pmp11cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr11].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr11].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg2].pmp11cfg[4] == 1)) { + return CSR[pmpaddr11].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg2].pmp11cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr11].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr11].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr12.yaml b/arch/csr/I/pmpaddr12.yaml new file mode 100644 index 000000000..85c28ef3a --- /dev/null +++ b/arch/csr/I/pmpaddr12.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr12: + long_name: PMP Address 12 + address: 0x3BC + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 12 + (or, if `pmp13cfg.A` == TOR, for PMP entry 13). + type(): | + if (NUM_PMP_ENTRIES > 12) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 12) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 12) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg3].pmp12cfg[4] == 1)) { + return CSR[pmpaddr12].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg3].pmp12cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr12].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr12].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg2].pmp12cfg[4] == 1)) { + return CSR[pmpaddr12].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg2].pmp12cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr12].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr12].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr13.yaml b/arch/csr/I/pmpaddr13.yaml new file mode 100644 index 000000000..bba8b3e16 --- /dev/null +++ b/arch/csr/I/pmpaddr13.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr13: + long_name: PMP Address 13 + address: 0x3BD + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 13 + (or, if `pmp14cfg.A` == TOR, for PMP entry 14). + type(): | + if (NUM_PMP_ENTRIES > 13) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 13) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 13) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg3].pmp13cfg[4] == 1)) { + return CSR[pmpaddr13].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg3].pmp13cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr13].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr13].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg2].pmp13cfg[4] == 1)) { + return CSR[pmpaddr13].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg2].pmp13cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr13].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr13].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr14.yaml b/arch/csr/I/pmpaddr14.yaml new file mode 100644 index 000000000..0540fa722 --- /dev/null +++ b/arch/csr/I/pmpaddr14.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr14: + long_name: PMP Address 14 + address: 0x3BE + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 14 + (or, if `pmp15cfg.A` == TOR, for PMP entry 15). + type(): | + if (NUM_PMP_ENTRIES > 14) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 14) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 14) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg3].pmp14cfg[4] == 1)) { + return CSR[pmpaddr14].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg3].pmp14cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr14].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr14].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg2].pmp14cfg[4] == 1)) { + return CSR[pmpaddr14].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg2].pmp14cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr14].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr14].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr15.yaml b/arch/csr/I/pmpaddr15.yaml new file mode 100644 index 000000000..e9c13dd0a --- /dev/null +++ b/arch/csr/I/pmpaddr15.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr15: + long_name: PMP Address 15 + address: 0x3BF + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 15 + (or, if `pmp16cfg.A` == TOR, for PMP entry 16). + type(): | + if (NUM_PMP_ENTRIES > 15) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 15) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 15) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg3].pmp15cfg[4] == 1)) { + return CSR[pmpaddr15].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg3].pmp15cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr15].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr15].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg2].pmp15cfg[4] == 1)) { + return CSR[pmpaddr15].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg2].pmp15cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr15].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr15].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr16.yaml b/arch/csr/I/pmpaddr16.yaml new file mode 100644 index 000000000..28ce31c9b --- /dev/null +++ b/arch/csr/I/pmpaddr16.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr16: + long_name: PMP Address 16 + address: 0x3C0 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 16 + (or, if `pmp17cfg.A` == TOR, for PMP entry 17). + type(): | + if (NUM_PMP_ENTRIES > 16) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 16) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 16) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg4].pmp16cfg[4] == 1)) { + return CSR[pmpaddr16].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg4].pmp16cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr16].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr16].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg4].pmp16cfg[4] == 1)) { + return CSR[pmpaddr16].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg4].pmp16cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr16].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr16].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr17.yaml b/arch/csr/I/pmpaddr17.yaml new file mode 100644 index 000000000..12557de34 --- /dev/null +++ b/arch/csr/I/pmpaddr17.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr17: + long_name: PMP Address 17 + address: 0x3C1 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 17 + (or, if `pmp18cfg.A` == TOR, for PMP entry 18). + type(): | + if (NUM_PMP_ENTRIES > 17) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 17) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 17) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg4].pmp17cfg[4] == 1)) { + return CSR[pmpaddr17].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg4].pmp17cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr17].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr17].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg4].pmp17cfg[4] == 1)) { + return CSR[pmpaddr17].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg4].pmp17cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr17].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr17].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr18.yaml b/arch/csr/I/pmpaddr18.yaml new file mode 100644 index 000000000..286597808 --- /dev/null +++ b/arch/csr/I/pmpaddr18.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr18: + long_name: PMP Address 18 + address: 0x3C2 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 18 + (or, if `pmp19cfg.A` == TOR, for PMP entry 19). + type(): | + if (NUM_PMP_ENTRIES > 18) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 18) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 18) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg4].pmp18cfg[4] == 1)) { + return CSR[pmpaddr18].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg4].pmp18cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr18].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr18].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg4].pmp18cfg[4] == 1)) { + return CSR[pmpaddr18].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg4].pmp18cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr18].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr18].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr19.yaml b/arch/csr/I/pmpaddr19.yaml new file mode 100644 index 000000000..d3574b45f --- /dev/null +++ b/arch/csr/I/pmpaddr19.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr19: + long_name: PMP Address 19 + address: 0x3C3 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 19 + (or, if `pmp20cfg.A` == TOR, for PMP entry 20). + type(): | + if (NUM_PMP_ENTRIES > 19) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 19) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 19) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg4].pmp19cfg[4] == 1)) { + return CSR[pmpaddr19].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg4].pmp19cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr19].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr19].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg4].pmp19cfg[4] == 1)) { + return CSR[pmpaddr19].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg4].pmp19cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr19].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr19].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr2.yaml b/arch/csr/I/pmpaddr2.yaml new file mode 100644 index 000000000..f3b917afa --- /dev/null +++ b/arch/csr/I/pmpaddr2.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr2: + long_name: PMP Address 2 + address: 0x3B2 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 2 + (or, if `pmp3cfg.A` == TOR, for PMP entry 3). + type(): | + if (NUM_PMP_ENTRIES > 2) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 2) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 2) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg0].pmp2cfg[4] == 1)) { + return CSR[pmpaddr2].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg0].pmp2cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr2].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr2].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg0].pmp2cfg[4] == 1)) { + return CSR[pmpaddr2].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg0].pmp2cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr2].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr2].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr20.yaml b/arch/csr/I/pmpaddr20.yaml new file mode 100644 index 000000000..68d185a3e --- /dev/null +++ b/arch/csr/I/pmpaddr20.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr20: + long_name: PMP Address 20 + address: 0x3C4 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 20 + (or, if `pmp21cfg.A` == TOR, for PMP entry 21). + type(): | + if (NUM_PMP_ENTRIES > 20) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 20) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 20) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg5].pmp20cfg[4] == 1)) { + return CSR[pmpaddr20].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg5].pmp20cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr20].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr20].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg4].pmp20cfg[4] == 1)) { + return CSR[pmpaddr20].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg4].pmp20cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr20].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr20].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr21.yaml b/arch/csr/I/pmpaddr21.yaml new file mode 100644 index 000000000..2130f99ba --- /dev/null +++ b/arch/csr/I/pmpaddr21.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr21: + long_name: PMP Address 21 + address: 0x3C5 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 21 + (or, if `pmp22cfg.A` == TOR, for PMP entry 22). + type(): | + if (NUM_PMP_ENTRIES > 21) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 21) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 21) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg5].pmp21cfg[4] == 1)) { + return CSR[pmpaddr21].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg5].pmp21cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr21].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr21].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg4].pmp21cfg[4] == 1)) { + return CSR[pmpaddr21].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg4].pmp21cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr21].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr21].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr22.yaml b/arch/csr/I/pmpaddr22.yaml new file mode 100644 index 000000000..a215bd97b --- /dev/null +++ b/arch/csr/I/pmpaddr22.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr22: + long_name: PMP Address 22 + address: 0x3C6 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 22 + (or, if `pmp23cfg.A` == TOR, for PMP entry 23). + type(): | + if (NUM_PMP_ENTRIES > 22) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 22) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 22) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg5].pmp22cfg[4] == 1)) { + return CSR[pmpaddr22].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg5].pmp22cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr22].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr22].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg4].pmp22cfg[4] == 1)) { + return CSR[pmpaddr22].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg4].pmp22cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr22].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr22].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr23.yaml b/arch/csr/I/pmpaddr23.yaml new file mode 100644 index 000000000..9facede46 --- /dev/null +++ b/arch/csr/I/pmpaddr23.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr23: + long_name: PMP Address 23 + address: 0x3C7 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 23 + (or, if `pmp24cfg.A` == TOR, for PMP entry 24). + type(): | + if (NUM_PMP_ENTRIES > 23) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 23) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 23) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg5].pmp23cfg[4] == 1)) { + return CSR[pmpaddr23].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg5].pmp23cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr23].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr23].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg4].pmp23cfg[4] == 1)) { + return CSR[pmpaddr23].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg4].pmp23cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr23].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr23].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr24.yaml b/arch/csr/I/pmpaddr24.yaml new file mode 100644 index 000000000..a1b1bae82 --- /dev/null +++ b/arch/csr/I/pmpaddr24.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr24: + long_name: PMP Address 24 + address: 0x3C8 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 24 + (or, if `pmp25cfg.A` == TOR, for PMP entry 25). + type(): | + if (NUM_PMP_ENTRIES > 24) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 24) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 24) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg6].pmp24cfg[4] == 1)) { + return CSR[pmpaddr24].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg6].pmp24cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr24].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr24].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg6].pmp24cfg[4] == 1)) { + return CSR[pmpaddr24].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg6].pmp24cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr24].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr24].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr25.yaml b/arch/csr/I/pmpaddr25.yaml new file mode 100644 index 000000000..4c87df3f4 --- /dev/null +++ b/arch/csr/I/pmpaddr25.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr25: + long_name: PMP Address 25 + address: 0x3C9 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 25 + (or, if `pmp26cfg.A` == TOR, for PMP entry 26). + type(): | + if (NUM_PMP_ENTRIES > 25) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 25) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 25) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg6].pmp25cfg[4] == 1)) { + return CSR[pmpaddr25].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg6].pmp25cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr25].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr25].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg6].pmp25cfg[4] == 1)) { + return CSR[pmpaddr25].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg6].pmp25cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr25].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr25].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr26.yaml b/arch/csr/I/pmpaddr26.yaml new file mode 100644 index 000000000..bbd7b53f8 --- /dev/null +++ b/arch/csr/I/pmpaddr26.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr26: + long_name: PMP Address 26 + address: 0x3CA + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 26 + (or, if `pmp27cfg.A` == TOR, for PMP entry 27). + type(): | + if (NUM_PMP_ENTRIES > 26) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 26) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 26) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg6].pmp26cfg[4] == 1)) { + return CSR[pmpaddr26].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg6].pmp26cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr26].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr26].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg6].pmp26cfg[4] == 1)) { + return CSR[pmpaddr26].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg6].pmp26cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr26].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr26].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr27.yaml b/arch/csr/I/pmpaddr27.yaml new file mode 100644 index 000000000..87874a594 --- /dev/null +++ b/arch/csr/I/pmpaddr27.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr27: + long_name: PMP Address 27 + address: 0x3CB + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 27 + (or, if `pmp28cfg.A` == TOR, for PMP entry 28). + type(): | + if (NUM_PMP_ENTRIES > 27) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 27) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 27) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg6].pmp27cfg[4] == 1)) { + return CSR[pmpaddr27].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg6].pmp27cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr27].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr27].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg6].pmp27cfg[4] == 1)) { + return CSR[pmpaddr27].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg6].pmp27cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr27].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr27].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr28.yaml b/arch/csr/I/pmpaddr28.yaml new file mode 100644 index 000000000..21261c8f8 --- /dev/null +++ b/arch/csr/I/pmpaddr28.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr28: + long_name: PMP Address 28 + address: 0x3CC + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 28 + (or, if `pmp29cfg.A` == TOR, for PMP entry 29). + type(): | + if (NUM_PMP_ENTRIES > 28) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 28) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 28) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg7].pmp28cfg[4] == 1)) { + return CSR[pmpaddr28].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg7].pmp28cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr28].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr28].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg6].pmp28cfg[4] == 1)) { + return CSR[pmpaddr28].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg6].pmp28cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr28].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr28].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr29.yaml b/arch/csr/I/pmpaddr29.yaml new file mode 100644 index 000000000..33116599d --- /dev/null +++ b/arch/csr/I/pmpaddr29.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr29: + long_name: PMP Address 29 + address: 0x3CD + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 29 + (or, if `pmp30cfg.A` == TOR, for PMP entry 30). + type(): | + if (NUM_PMP_ENTRIES > 29) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 29) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 29) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg7].pmp29cfg[4] == 1)) { + return CSR[pmpaddr29].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg7].pmp29cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr29].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr29].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg6].pmp29cfg[4] == 1)) { + return CSR[pmpaddr29].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg6].pmp29cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr29].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr29].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr3.yaml b/arch/csr/I/pmpaddr3.yaml new file mode 100644 index 000000000..d4cc0c6ff --- /dev/null +++ b/arch/csr/I/pmpaddr3.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr3: + long_name: PMP Address 3 + address: 0x3B3 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 3 + (or, if `pmp4cfg.A` == TOR, for PMP entry 4). + type(): | + if (NUM_PMP_ENTRIES > 3) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 3) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 3) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg0].pmp3cfg[4] == 1)) { + return CSR[pmpaddr3].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg0].pmp3cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr3].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr3].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg0].pmp3cfg[4] == 1)) { + return CSR[pmpaddr3].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg0].pmp3cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr3].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr3].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr30.yaml b/arch/csr/I/pmpaddr30.yaml new file mode 100644 index 000000000..f2ec5c203 --- /dev/null +++ b/arch/csr/I/pmpaddr30.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr30: + long_name: PMP Address 30 + address: 0x3CE + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 30 + (or, if `pmp31cfg.A` == TOR, for PMP entry 31). + type(): | + if (NUM_PMP_ENTRIES > 30) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 30) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 30) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg7].pmp30cfg[4] == 1)) { + return CSR[pmpaddr30].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg7].pmp30cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr30].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr30].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg6].pmp30cfg[4] == 1)) { + return CSR[pmpaddr30].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg6].pmp30cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr30].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr30].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr31.yaml b/arch/csr/I/pmpaddr31.yaml new file mode 100644 index 000000000..fe93468dc --- /dev/null +++ b/arch/csr/I/pmpaddr31.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr31: + long_name: PMP Address 31 + address: 0x3CF + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 31 + (or, if `pmp32cfg.A` == TOR, for PMP entry 32). + type(): | + if (NUM_PMP_ENTRIES > 31) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 31) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 31) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg7].pmp31cfg[4] == 1)) { + return CSR[pmpaddr31].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg7].pmp31cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr31].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr31].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg6].pmp31cfg[4] == 1)) { + return CSR[pmpaddr31].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg6].pmp31cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr31].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr31].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr32.yaml b/arch/csr/I/pmpaddr32.yaml new file mode 100644 index 000000000..132086fcf --- /dev/null +++ b/arch/csr/I/pmpaddr32.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr32: + long_name: PMP Address 32 + address: 0x3D0 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 32 + (or, if `pmp33cfg.A` == TOR, for PMP entry 33). + type(): | + if (NUM_PMP_ENTRIES > 32) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 32) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 32) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg8].pmp32cfg[4] == 1)) { + return CSR[pmpaddr32].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg8].pmp32cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr32].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr32].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg8].pmp32cfg[4] == 1)) { + return CSR[pmpaddr32].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg8].pmp32cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr32].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr32].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr33.yaml b/arch/csr/I/pmpaddr33.yaml new file mode 100644 index 000000000..6acc29c6d --- /dev/null +++ b/arch/csr/I/pmpaddr33.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr33: + long_name: PMP Address 33 + address: 0x3D1 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 33 + (or, if `pmp34cfg.A` == TOR, for PMP entry 34). + type(): | + if (NUM_PMP_ENTRIES > 33) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 33) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 33) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg8].pmp33cfg[4] == 1)) { + return CSR[pmpaddr33].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg8].pmp33cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr33].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr33].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg8].pmp33cfg[4] == 1)) { + return CSR[pmpaddr33].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg8].pmp33cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr33].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr33].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr34.yaml b/arch/csr/I/pmpaddr34.yaml new file mode 100644 index 000000000..c1dec2b52 --- /dev/null +++ b/arch/csr/I/pmpaddr34.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr34: + long_name: PMP Address 34 + address: 0x3D2 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 34 + (or, if `pmp35cfg.A` == TOR, for PMP entry 35). + type(): | + if (NUM_PMP_ENTRIES > 34) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 34) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 34) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg8].pmp34cfg[4] == 1)) { + return CSR[pmpaddr34].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg8].pmp34cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr34].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr34].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg8].pmp34cfg[4] == 1)) { + return CSR[pmpaddr34].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg8].pmp34cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr34].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr34].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr35.yaml b/arch/csr/I/pmpaddr35.yaml new file mode 100644 index 000000000..c024e3a59 --- /dev/null +++ b/arch/csr/I/pmpaddr35.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr35: + long_name: PMP Address 35 + address: 0x3D3 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 35 + (or, if `pmp36cfg.A` == TOR, for PMP entry 36). + type(): | + if (NUM_PMP_ENTRIES > 35) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 35) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 35) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg8].pmp35cfg[4] == 1)) { + return CSR[pmpaddr35].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg8].pmp35cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr35].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr35].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg8].pmp35cfg[4] == 1)) { + return CSR[pmpaddr35].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg8].pmp35cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr35].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr35].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr36.yaml b/arch/csr/I/pmpaddr36.yaml new file mode 100644 index 000000000..c31ab9209 --- /dev/null +++ b/arch/csr/I/pmpaddr36.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr36: + long_name: PMP Address 36 + address: 0x3D4 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 36 + (or, if `pmp37cfg.A` == TOR, for PMP entry 37). + type(): | + if (NUM_PMP_ENTRIES > 36) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 36) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 36) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg9].pmp36cfg[4] == 1)) { + return CSR[pmpaddr36].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg9].pmp36cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr36].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr36].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg8].pmp36cfg[4] == 1)) { + return CSR[pmpaddr36].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg8].pmp36cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr36].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr36].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr37.yaml b/arch/csr/I/pmpaddr37.yaml new file mode 100644 index 000000000..034687bc2 --- /dev/null +++ b/arch/csr/I/pmpaddr37.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr37: + long_name: PMP Address 37 + address: 0x3D5 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 37 + (or, if `pmp38cfg.A` == TOR, for PMP entry 38). + type(): | + if (NUM_PMP_ENTRIES > 37) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 37) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 37) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg9].pmp37cfg[4] == 1)) { + return CSR[pmpaddr37].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg9].pmp37cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr37].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr37].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg8].pmp37cfg[4] == 1)) { + return CSR[pmpaddr37].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg8].pmp37cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr37].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr37].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr38.yaml b/arch/csr/I/pmpaddr38.yaml new file mode 100644 index 000000000..36dd1a686 --- /dev/null +++ b/arch/csr/I/pmpaddr38.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr38: + long_name: PMP Address 38 + address: 0x3D6 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 38 + (or, if `pmp39cfg.A` == TOR, for PMP entry 39). + type(): | + if (NUM_PMP_ENTRIES > 38) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 38) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 38) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg9].pmp38cfg[4] == 1)) { + return CSR[pmpaddr38].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg9].pmp38cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr38].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr38].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg8].pmp38cfg[4] == 1)) { + return CSR[pmpaddr38].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg8].pmp38cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr38].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr38].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr39.yaml b/arch/csr/I/pmpaddr39.yaml new file mode 100644 index 000000000..a9b8f0aad --- /dev/null +++ b/arch/csr/I/pmpaddr39.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr39: + long_name: PMP Address 39 + address: 0x3D7 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 39 + (or, if `pmp40cfg.A` == TOR, for PMP entry 40). + type(): | + if (NUM_PMP_ENTRIES > 39) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 39) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 39) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg9].pmp39cfg[4] == 1)) { + return CSR[pmpaddr39].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg9].pmp39cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr39].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr39].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg8].pmp39cfg[4] == 1)) { + return CSR[pmpaddr39].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg8].pmp39cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr39].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr39].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr4.yaml b/arch/csr/I/pmpaddr4.yaml new file mode 100644 index 000000000..9bd5ca12b --- /dev/null +++ b/arch/csr/I/pmpaddr4.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr4: + long_name: PMP Address 4 + address: 0x3B4 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 4 + (or, if `pmp5cfg.A` == TOR, for PMP entry 5). + type(): | + if (NUM_PMP_ENTRIES > 4) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 4) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 4) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg1].pmp4cfg[4] == 1)) { + return CSR[pmpaddr4].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg1].pmp4cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr4].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr4].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg0].pmp4cfg[4] == 1)) { + return CSR[pmpaddr4].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg0].pmp4cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr4].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr4].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr40.yaml b/arch/csr/I/pmpaddr40.yaml new file mode 100644 index 000000000..fbc1cdf45 --- /dev/null +++ b/arch/csr/I/pmpaddr40.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr40: + long_name: PMP Address 40 + address: 0x3D8 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 40 + (or, if `pmp41cfg.A` == TOR, for PMP entry 41). + type(): | + if (NUM_PMP_ENTRIES > 40) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 40) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 40) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg10].pmp40cfg[4] == 1)) { + return CSR[pmpaddr40].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg10].pmp40cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr40].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr40].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg10].pmp40cfg[4] == 1)) { + return CSR[pmpaddr40].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg10].pmp40cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr40].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr40].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr41.yaml b/arch/csr/I/pmpaddr41.yaml new file mode 100644 index 000000000..2dba42eb5 --- /dev/null +++ b/arch/csr/I/pmpaddr41.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr41: + long_name: PMP Address 41 + address: 0x3D9 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 41 + (or, if `pmp42cfg.A` == TOR, for PMP entry 42). + type(): | + if (NUM_PMP_ENTRIES > 41) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 41) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 41) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg10].pmp41cfg[4] == 1)) { + return CSR[pmpaddr41].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg10].pmp41cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr41].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr41].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg10].pmp41cfg[4] == 1)) { + return CSR[pmpaddr41].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg10].pmp41cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr41].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr41].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr42.yaml b/arch/csr/I/pmpaddr42.yaml new file mode 100644 index 000000000..d0fec5a9f --- /dev/null +++ b/arch/csr/I/pmpaddr42.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr42: + long_name: PMP Address 42 + address: 0x3DA + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 42 + (or, if `pmp43cfg.A` == TOR, for PMP entry 43). + type(): | + if (NUM_PMP_ENTRIES > 42) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 42) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 42) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg10].pmp42cfg[4] == 1)) { + return CSR[pmpaddr42].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg10].pmp42cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr42].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr42].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg10].pmp42cfg[4] == 1)) { + return CSR[pmpaddr42].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg10].pmp42cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr42].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr42].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr43.yaml b/arch/csr/I/pmpaddr43.yaml new file mode 100644 index 000000000..bf2bdbadd --- /dev/null +++ b/arch/csr/I/pmpaddr43.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr43: + long_name: PMP Address 43 + address: 0x3DB + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 43 + (or, if `pmp44cfg.A` == TOR, for PMP entry 44). + type(): | + if (NUM_PMP_ENTRIES > 43) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 43) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 43) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg10].pmp43cfg[4] == 1)) { + return CSR[pmpaddr43].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg10].pmp43cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr43].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr43].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg10].pmp43cfg[4] == 1)) { + return CSR[pmpaddr43].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg10].pmp43cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr43].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr43].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr44.yaml b/arch/csr/I/pmpaddr44.yaml new file mode 100644 index 000000000..bc5a7507d --- /dev/null +++ b/arch/csr/I/pmpaddr44.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr44: + long_name: PMP Address 44 + address: 0x3DC + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 44 + (or, if `pmp45cfg.A` == TOR, for PMP entry 45). + type(): | + if (NUM_PMP_ENTRIES > 44) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 44) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 44) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg11].pmp44cfg[4] == 1)) { + return CSR[pmpaddr44].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg11].pmp44cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr44].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr44].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg10].pmp44cfg[4] == 1)) { + return CSR[pmpaddr44].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg10].pmp44cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr44].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr44].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr45.yaml b/arch/csr/I/pmpaddr45.yaml new file mode 100644 index 000000000..5573bf233 --- /dev/null +++ b/arch/csr/I/pmpaddr45.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr45: + long_name: PMP Address 45 + address: 0x3DD + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 45 + (or, if `pmp46cfg.A` == TOR, for PMP entry 46). + type(): | + if (NUM_PMP_ENTRIES > 45) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 45) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 45) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg11].pmp45cfg[4] == 1)) { + return CSR[pmpaddr45].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg11].pmp45cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr45].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr45].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg10].pmp45cfg[4] == 1)) { + return CSR[pmpaddr45].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg10].pmp45cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr45].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr45].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr46.yaml b/arch/csr/I/pmpaddr46.yaml new file mode 100644 index 000000000..a4ca912ec --- /dev/null +++ b/arch/csr/I/pmpaddr46.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr46: + long_name: PMP Address 46 + address: 0x3DE + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 46 + (or, if `pmp47cfg.A` == TOR, for PMP entry 47). + type(): | + if (NUM_PMP_ENTRIES > 46) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 46) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 46) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg11].pmp46cfg[4] == 1)) { + return CSR[pmpaddr46].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg11].pmp46cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr46].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr46].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg10].pmp46cfg[4] == 1)) { + return CSR[pmpaddr46].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg10].pmp46cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr46].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr46].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr47.yaml b/arch/csr/I/pmpaddr47.yaml new file mode 100644 index 000000000..daeac852b --- /dev/null +++ b/arch/csr/I/pmpaddr47.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr47: + long_name: PMP Address 47 + address: 0x3DF + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 47 + (or, if `pmp48cfg.A` == TOR, for PMP entry 48). + type(): | + if (NUM_PMP_ENTRIES > 47) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 47) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 47) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg11].pmp47cfg[4] == 1)) { + return CSR[pmpaddr47].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg11].pmp47cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr47].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr47].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg10].pmp47cfg[4] == 1)) { + return CSR[pmpaddr47].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg10].pmp47cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr47].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr47].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr48.yaml b/arch/csr/I/pmpaddr48.yaml new file mode 100644 index 000000000..11d113ff4 --- /dev/null +++ b/arch/csr/I/pmpaddr48.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr48: + long_name: PMP Address 48 + address: 0x3E0 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 48 + (or, if `pmp49cfg.A` == TOR, for PMP entry 49). + type(): | + if (NUM_PMP_ENTRIES > 48) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 48) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 48) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg12].pmp48cfg[4] == 1)) { + return CSR[pmpaddr48].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg12].pmp48cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr48].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr48].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg12].pmp48cfg[4] == 1)) { + return CSR[pmpaddr48].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg12].pmp48cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr48].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr48].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr49.yaml b/arch/csr/I/pmpaddr49.yaml new file mode 100644 index 000000000..d61bff065 --- /dev/null +++ b/arch/csr/I/pmpaddr49.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr49: + long_name: PMP Address 49 + address: 0x3E1 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 49 + (or, if `pmp50cfg.A` == TOR, for PMP entry 50). + type(): | + if (NUM_PMP_ENTRIES > 49) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 49) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 49) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg12].pmp49cfg[4] == 1)) { + return CSR[pmpaddr49].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg12].pmp49cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr49].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr49].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg12].pmp49cfg[4] == 1)) { + return CSR[pmpaddr49].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg12].pmp49cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr49].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr49].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr5.yaml b/arch/csr/I/pmpaddr5.yaml new file mode 100644 index 000000000..caab71abf --- /dev/null +++ b/arch/csr/I/pmpaddr5.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr5: + long_name: PMP Address 5 + address: 0x3B5 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 5 + (or, if `pmp6cfg.A` == TOR, for PMP entry 6). + type(): | + if (NUM_PMP_ENTRIES > 5) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 5) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 5) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg1].pmp5cfg[4] == 1)) { + return CSR[pmpaddr5].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg1].pmp5cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr5].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr5].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg0].pmp5cfg[4] == 1)) { + return CSR[pmpaddr5].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg0].pmp5cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr5].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr5].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr50.yaml b/arch/csr/I/pmpaddr50.yaml new file mode 100644 index 000000000..8a4aa4752 --- /dev/null +++ b/arch/csr/I/pmpaddr50.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr50: + long_name: PMP Address 50 + address: 0x3E2 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 50 + (or, if `pmp51cfg.A` == TOR, for PMP entry 51). + type(): | + if (NUM_PMP_ENTRIES > 50) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 50) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 50) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg12].pmp50cfg[4] == 1)) { + return CSR[pmpaddr50].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg12].pmp50cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr50].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr50].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg12].pmp50cfg[4] == 1)) { + return CSR[pmpaddr50].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg12].pmp50cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr50].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr50].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr51.yaml b/arch/csr/I/pmpaddr51.yaml new file mode 100644 index 000000000..7d738bd17 --- /dev/null +++ b/arch/csr/I/pmpaddr51.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr51: + long_name: PMP Address 51 + address: 0x3E3 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 51 + (or, if `pmp52cfg.A` == TOR, for PMP entry 52). + type(): | + if (NUM_PMP_ENTRIES > 51) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 51) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 51) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg12].pmp51cfg[4] == 1)) { + return CSR[pmpaddr51].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg12].pmp51cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr51].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr51].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg12].pmp51cfg[4] == 1)) { + return CSR[pmpaddr51].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg12].pmp51cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr51].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr51].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr52.yaml b/arch/csr/I/pmpaddr52.yaml new file mode 100644 index 000000000..757f3d3a9 --- /dev/null +++ b/arch/csr/I/pmpaddr52.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr52: + long_name: PMP Address 52 + address: 0x3E4 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 52 + (or, if `pmp53cfg.A` == TOR, for PMP entry 53). + type(): | + if (NUM_PMP_ENTRIES > 52) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 52) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 52) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg13].pmp52cfg[4] == 1)) { + return CSR[pmpaddr52].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg13].pmp52cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr52].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr52].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg12].pmp52cfg[4] == 1)) { + return CSR[pmpaddr52].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg12].pmp52cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr52].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr52].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr53.yaml b/arch/csr/I/pmpaddr53.yaml new file mode 100644 index 000000000..deeedd184 --- /dev/null +++ b/arch/csr/I/pmpaddr53.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr53: + long_name: PMP Address 53 + address: 0x3E5 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 53 + (or, if `pmp54cfg.A` == TOR, for PMP entry 54). + type(): | + if (NUM_PMP_ENTRIES > 53) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 53) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 53) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg13].pmp53cfg[4] == 1)) { + return CSR[pmpaddr53].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg13].pmp53cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr53].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr53].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg12].pmp53cfg[4] == 1)) { + return CSR[pmpaddr53].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg12].pmp53cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr53].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr53].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr54.yaml b/arch/csr/I/pmpaddr54.yaml new file mode 100644 index 000000000..f4a95068e --- /dev/null +++ b/arch/csr/I/pmpaddr54.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr54: + long_name: PMP Address 54 + address: 0x3E6 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 54 + (or, if `pmp55cfg.A` == TOR, for PMP entry 55). + type(): | + if (NUM_PMP_ENTRIES > 54) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 54) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 54) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg13].pmp54cfg[4] == 1)) { + return CSR[pmpaddr54].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg13].pmp54cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr54].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr54].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg12].pmp54cfg[4] == 1)) { + return CSR[pmpaddr54].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg12].pmp54cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr54].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr54].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr55.yaml b/arch/csr/I/pmpaddr55.yaml new file mode 100644 index 000000000..2e7a23b87 --- /dev/null +++ b/arch/csr/I/pmpaddr55.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr55: + long_name: PMP Address 55 + address: 0x3E7 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 55 + (or, if `pmp56cfg.A` == TOR, for PMP entry 56). + type(): | + if (NUM_PMP_ENTRIES > 55) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 55) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 55) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg13].pmp55cfg[4] == 1)) { + return CSR[pmpaddr55].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg13].pmp55cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr55].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr55].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg12].pmp55cfg[4] == 1)) { + return CSR[pmpaddr55].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg12].pmp55cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr55].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr55].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr56.yaml b/arch/csr/I/pmpaddr56.yaml new file mode 100644 index 000000000..79eb4e50a --- /dev/null +++ b/arch/csr/I/pmpaddr56.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr56: + long_name: PMP Address 56 + address: 0x3E8 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 56 + (or, if `pmp57cfg.A` == TOR, for PMP entry 57). + type(): | + if (NUM_PMP_ENTRIES > 56) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 56) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 56) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg14].pmp56cfg[4] == 1)) { + return CSR[pmpaddr56].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg14].pmp56cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr56].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr56].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg14].pmp56cfg[4] == 1)) { + return CSR[pmpaddr56].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg14].pmp56cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr56].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr56].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr57.yaml b/arch/csr/I/pmpaddr57.yaml new file mode 100644 index 000000000..aff51a529 --- /dev/null +++ b/arch/csr/I/pmpaddr57.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr57: + long_name: PMP Address 57 + address: 0x3E9 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 57 + (or, if `pmp58cfg.A` == TOR, for PMP entry 58). + type(): | + if (NUM_PMP_ENTRIES > 57) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 57) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 57) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg14].pmp57cfg[4] == 1)) { + return CSR[pmpaddr57].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg14].pmp57cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr57].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr57].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg14].pmp57cfg[4] == 1)) { + return CSR[pmpaddr57].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg14].pmp57cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr57].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr57].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr58.yaml b/arch/csr/I/pmpaddr58.yaml new file mode 100644 index 000000000..81e18fef2 --- /dev/null +++ b/arch/csr/I/pmpaddr58.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr58: + long_name: PMP Address 58 + address: 0x3EA + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 58 + (or, if `pmp59cfg.A` == TOR, for PMP entry 59). + type(): | + if (NUM_PMP_ENTRIES > 58) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 58) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 58) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg14].pmp58cfg[4] == 1)) { + return CSR[pmpaddr58].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg14].pmp58cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr58].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr58].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg14].pmp58cfg[4] == 1)) { + return CSR[pmpaddr58].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg14].pmp58cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr58].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr58].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr59.yaml b/arch/csr/I/pmpaddr59.yaml new file mode 100644 index 000000000..172468ce4 --- /dev/null +++ b/arch/csr/I/pmpaddr59.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr59: + long_name: PMP Address 59 + address: 0x3EB + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 59 + (or, if `pmp60cfg.A` == TOR, for PMP entry 60). + type(): | + if (NUM_PMP_ENTRIES > 59) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 59) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 59) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg14].pmp59cfg[4] == 1)) { + return CSR[pmpaddr59].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg14].pmp59cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr59].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr59].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg14].pmp59cfg[4] == 1)) { + return CSR[pmpaddr59].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg14].pmp59cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr59].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr59].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr6.yaml b/arch/csr/I/pmpaddr6.yaml new file mode 100644 index 000000000..275db523d --- /dev/null +++ b/arch/csr/I/pmpaddr6.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr6: + long_name: PMP Address 6 + address: 0x3B6 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 6 + (or, if `pmp7cfg.A` == TOR, for PMP entry 7). + type(): | + if (NUM_PMP_ENTRIES > 6) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 6) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 6) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg1].pmp6cfg[4] == 1)) { + return CSR[pmpaddr6].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg1].pmp6cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr6].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr6].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg0].pmp6cfg[4] == 1)) { + return CSR[pmpaddr6].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg0].pmp6cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr6].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr6].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr60.yaml b/arch/csr/I/pmpaddr60.yaml new file mode 100644 index 000000000..ba2af46bc --- /dev/null +++ b/arch/csr/I/pmpaddr60.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr60: + long_name: PMP Address 60 + address: 0x3EC + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 60 + (or, if `pmp61cfg.A` == TOR, for PMP entry 61). + type(): | + if (NUM_PMP_ENTRIES > 60) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 60) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 60) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg15].pmp60cfg[4] == 1)) { + return CSR[pmpaddr60].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg15].pmp60cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr60].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr60].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg14].pmp60cfg[4] == 1)) { + return CSR[pmpaddr60].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg14].pmp60cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr60].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr60].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr61.yaml b/arch/csr/I/pmpaddr61.yaml new file mode 100644 index 000000000..5364966db --- /dev/null +++ b/arch/csr/I/pmpaddr61.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr61: + long_name: PMP Address 61 + address: 0x3ED + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 61 + (or, if `pmp62cfg.A` == TOR, for PMP entry 62). + type(): | + if (NUM_PMP_ENTRIES > 61) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 61) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 61) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg15].pmp61cfg[4] == 1)) { + return CSR[pmpaddr61].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg15].pmp61cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr61].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr61].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg14].pmp61cfg[4] == 1)) { + return CSR[pmpaddr61].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg14].pmp61cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr61].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr61].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr62.yaml b/arch/csr/I/pmpaddr62.yaml new file mode 100644 index 000000000..1432c8a57 --- /dev/null +++ b/arch/csr/I/pmpaddr62.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr62: + long_name: PMP Address 62 + address: 0x3EE + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 62 + (or, if `pmp63cfg.A` == TOR, for PMP entry 63). + type(): | + if (NUM_PMP_ENTRIES > 62) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 62) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 62) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg15].pmp62cfg[4] == 1)) { + return CSR[pmpaddr62].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg15].pmp62cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr62].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr62].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg14].pmp62cfg[4] == 1)) { + return CSR[pmpaddr62].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg14].pmp62cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr62].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr62].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr63.yaml b/arch/csr/I/pmpaddr63.yaml new file mode 100644 index 000000000..7742b1f83 --- /dev/null +++ b/arch/csr/I/pmpaddr63.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr63: + long_name: PMP Address 63 + address: 0x3EF + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 63 + (or, if `pmp64cfg.A` == TOR, for PMP entry 64). + type(): | + if (NUM_PMP_ENTRIES > 63) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 63) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 63) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg15].pmp63cfg[4] == 1)) { + return CSR[pmpaddr63].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg15].pmp63cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr63].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr63].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg14].pmp63cfg[4] == 1)) { + return CSR[pmpaddr63].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg14].pmp63cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr63].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr63].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr7.yaml b/arch/csr/I/pmpaddr7.yaml new file mode 100644 index 000000000..c2fbacd6e --- /dev/null +++ b/arch/csr/I/pmpaddr7.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr7: + long_name: PMP Address 7 + address: 0x3B7 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 7 + (or, if `pmp8cfg.A` == TOR, for PMP entry 8). + type(): | + if (NUM_PMP_ENTRIES > 7) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 7) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 7) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg1].pmp7cfg[4] == 1)) { + return CSR[pmpaddr7].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg1].pmp7cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr7].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr7].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg0].pmp7cfg[4] == 1)) { + return CSR[pmpaddr7].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg0].pmp7cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr7].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr7].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr8.yaml b/arch/csr/I/pmpaddr8.yaml new file mode 100644 index 000000000..399c8d67e --- /dev/null +++ b/arch/csr/I/pmpaddr8.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr8: + long_name: PMP Address 8 + address: 0x3B8 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 8 + (or, if `pmp9cfg.A` == TOR, for PMP entry 9). + type(): | + if (NUM_PMP_ENTRIES > 8) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 8) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 8) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg2].pmp8cfg[4] == 1)) { + return CSR[pmpaddr8].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg2].pmp8cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr8].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr8].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg2].pmp8cfg[4] == 1)) { + return CSR[pmpaddr8].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg2].pmp8cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr8].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr8].ADDR; + } + } diff --git a/arch/csr/I/pmpaddr9.yaml b/arch/csr/I/pmpaddr9.yaml new file mode 100644 index 000000000..94b57f7f3 --- /dev/null +++ b/arch/csr/I/pmpaddr9.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpaddrN.layout + + + +pmpaddr9: + long_name: PMP Address 9 + address: 0x3B9 + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry 9 + (or, if `pmp10cfg.A` == TOR, for PMP entry 10). + type(): | + if (NUM_PMP_ENTRIES > 9) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 9) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > 9) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg2].pmp9cfg[4] == 1)) { + return CSR[pmpaddr9].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg2].pmp9cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr9].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr9].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg2].pmp9cfg[4] == 1)) { + return CSR[pmpaddr9].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg2].pmp9cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr9].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr9].ADDR; + } + } diff --git a/arch/csr/I/pmpaddrN.layout b/arch/csr/I/pmpaddrN.layout new file mode 100644 index 000000000..432d81dfe --- /dev/null +++ b/arch/csr/I/pmpaddrN.layout @@ -0,0 +1,77 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +<%- + raise "'pmpaddr_num' must be defined" if pmpaddr_num.nil? + pmpcfg_num_32 = (pmpaddr_num / 4) + pmpcfg_num_64 = (pmpaddr_num / 8)*2 +-%> + +pmpaddr<%= pmpaddr_num %>: + long_name: PMP Address <%= pmpaddr_num %> + address: 0x<%= (0x3B0 + pmpaddr_num).to_s(16).upcase %> + priv_mode: M + length: MXLEN + description: PMP entry address + definedBy: I + fields: + ADDR: + location: 63-0 + description: | + Bits <%%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry <%= pmpaddr_num %> + (or, if `pmp<%= pmpaddr_num+1 %>cfg.A` == TOR, for PMP entry <%= pmpaddr_num + 1 %>). + type(): | + if (NUM_PMP_ENTRIES > <%= pmpaddr_num %>) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > <%= pmpaddr_num %>) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.ADDR >= (PHYS_ADDR_WIDTH >> 2)) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else if (NUM_PMP_ENTRIES > <%= pmpaddr_num %>) { + return UNDEFINED_LEGAL_DETERMINISTIC; + } else { + return csr_value.ADDR; + } + sw_read(): | + # when the mode is NAPOT and PMP_GRANULARITY >= 16, + # bits (PMP_GRANULARITY-4):0 must read as ones + if (XLEN == 32) { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg<%= pmpcfg_num_32 %>].pmp<%= pmpaddr_num %>cfg[4] == 1)) { + return CSR[pmpaddr<%= pmpaddr_num %>].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg<%= pmpcfg_num_32 %>].pmp<%= pmpaddr_num %>cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr<%= pmpaddr_num %>].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr<%= pmpaddr_num %>].ADDR; + } + } else { + if ((PMP_GRANULARITY >= 16) && + (CSR[pmpcfg<%= pmpcfg_num_64 %>].pmp<%= pmpaddr_num %>cfg[4] == 1)) { + return CSR[pmpaddr<%= pmpaddr_num %>].ADDR | {PMP_GRANULARITY-3{1'b1}}; + + # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, + # bits (PMP_GRANULARITY-3):0 must read as zeros + } else if ((PMP_GRANULARITY >= 8) && + (CSR[pmpcfg<%= pmpcfg_num_64 %>].pmp<%= pmpaddr_num %>cfg[4] == 0)) { + Bits mask = {PMP_GRANULARITY-2{1'b1}}; + return CSR[pmpaddr<%= pmpaddr_num %>].ADDR & ~mask; + + # no modifications needed + } else { + return CSR[pmpaddr<%= pmpaddr_num %>].ADDR; + } + } diff --git a/arch/csr/I/pmpcfg0.yaml b/arch/csr/I/pmpcfg0.yaml new file mode 100644 index 000000000..b5c5bbc0e --- /dev/null +++ b/arch/csr/I/pmpcfg0.yaml @@ -0,0 +1,490 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpcfgN.layout + + + +pmpcfg0: + long_name: PMP Configuration Register 0 + address: 0x3A0 + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + pmp0cfg: + location: 7-0 + description: | + *PMP configuration for entry 0* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 7 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 6:5 ! _Reserved_ Writes shall be ignored. + h! A ! 4:3 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 2 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 1 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 0 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 0) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 0) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg0].pmp0cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp0cfg & 0x1) == 0) && ((csr_value.pmp0cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp0cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp0cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg0].pmp0cfg; + pmp1cfg: + location: 15-8 + description: | + *PMP configuration for entry 1* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 15 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 14:13 ! _Reserved_ Writes shall be ignored. + h! A ! 12:11 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 10 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 9 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 8 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 1) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 1) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg0].pmp1cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp2cfg & 0x1) == 0) && ((csr_value.pmp2cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp2cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp2cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg0].pmp1cfg; + pmp2cfg: + location: 23-16 + description: | + *PMP configuration for entry 2* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 23 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 22:21 ! _Reserved_ Writes shall be ignored. + h! A ! 20:19 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 18 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 17 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 16 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 2) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 2) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg0].pmp2cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp4cfg & 0x1) == 0) && ((csr_value.pmp4cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp4cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp4cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg0].pmp2cfg; + pmp3cfg: + location: 31-24 + description: | + *PMP configuration for entry 3* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 31 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 30:29 ! _Reserved_ Writes shall be ignored. + h! A ! 28:27 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 26 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 25 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 24 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 3) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 3) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg0].pmp3cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp6cfg & 0x1) == 0) && ((csr_value.pmp6cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp6cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp6cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg0].pmp3cfg; + pmp4cfg: + location: 39-32 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 4* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 39 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 38:37 ! _Reserved_ Writes shall be ignored. + h! A ! 36:35 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 34 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 33 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 32 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 4) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 4) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg0].pmp4cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp8cfg & 0x1) == 0) && ((csr_value.pmp8cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp8cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp8cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg0].pmp4cfg; + pmp5cfg: + location: 47-40 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 5* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 47 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 46:45 ! _Reserved_ Writes shall be ignored. + h! A ! 44:43 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 42 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 41 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 40 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 5) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 5) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg0].pmp5cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp10cfg & 0x1) == 0) && ((csr_value.pmp10cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp10cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp10cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg0].pmp5cfg; + pmp6cfg: + location: 55-48 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 6* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 55 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 54:53 ! _Reserved_ Writes shall be ignored. + h! A ! 52:51 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 50 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 49 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 48 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 6) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 6) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg0].pmp6cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp12cfg & 0x1) == 0) && ((csr_value.pmp12cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp12cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp12cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg0].pmp6cfg; + pmp7cfg: + location: 63-56 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 7* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 63 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 62:61 ! _Reserved_ Writes shall be ignored. + h! A ! 60:59 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 58 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 57 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 56 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 7) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 7) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg0].pmp7cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp14cfg & 0x1) == 0) && ((csr_value.pmp14cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp14cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp14cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg0].pmp7cfg; diff --git a/arch/csr/I/pmpcfg1.yaml b/arch/csr/I/pmpcfg1.yaml new file mode 100644 index 000000000..97e1a4f8a --- /dev/null +++ b/arch/csr/I/pmpcfg1.yaml @@ -0,0 +1,251 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpcfgN.layout + + + +pmpcfg1: + base: 32 # odd numbered pmpcfg registers do not exist in RV64 + long_name: PMP Configuration Register 1 + address: 0x3A1 + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + pmp4cfg: + location: 7-0 + description: | + *PMP configuration for entry 4* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 7 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 6:5 ! _Reserved_ Writes shall be ignored. + h! A ! 4:3 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 2 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 1 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 0 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 4) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 4) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg1].pmp4cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp4cfg & 0x1) == 0) && ((csr_value.pmp4cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp4cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp4cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg1].pmp4cfg; + pmp5cfg: + location: 15-8 + description: | + *PMP configuration for entry 5* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 15 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 14:13 ! _Reserved_ Writes shall be ignored. + h! A ! 12:11 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 10 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 9 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 8 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 5) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 5) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg1].pmp5cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp6cfg & 0x1) == 0) && ((csr_value.pmp6cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp6cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp6cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg1].pmp5cfg; + pmp6cfg: + location: 23-16 + description: | + *PMP configuration for entry 6* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 23 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 22:21 ! _Reserved_ Writes shall be ignored. + h! A ! 20:19 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 18 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 17 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 16 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 6) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 6) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg1].pmp6cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp8cfg & 0x1) == 0) && ((csr_value.pmp8cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp8cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp8cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg1].pmp6cfg; + pmp7cfg: + location: 31-24 + description: | + *PMP configuration for entry 7* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 31 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 30:29 ! _Reserved_ Writes shall be ignored. + h! A ! 28:27 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 26 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 25 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 24 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 7) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 7) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg1].pmp7cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp10cfg & 0x1) == 0) && ((csr_value.pmp10cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp10cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp10cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg1].pmp7cfg; diff --git a/arch/csr/I/pmpcfg10.yaml b/arch/csr/I/pmpcfg10.yaml new file mode 100644 index 000000000..6cad2358c --- /dev/null +++ b/arch/csr/I/pmpcfg10.yaml @@ -0,0 +1,490 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpcfgN.layout + + + +pmpcfg10: + long_name: PMP Configuration Register 10 + address: 0x3AA + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + pmp40cfg: + location: 7-0 + description: | + *PMP configuration for entry 40* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 7 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 6:5 ! _Reserved_ Writes shall be ignored. + h! A ! 4:3 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 2 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 1 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 0 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 40) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 40) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg10].pmp40cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp40cfg & 0x1) == 0) && ((csr_value.pmp40cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp40cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp40cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg10].pmp40cfg; + pmp41cfg: + location: 15-8 + description: | + *PMP configuration for entry 41* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 15 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 14:13 ! _Reserved_ Writes shall be ignored. + h! A ! 12:11 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 10 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 9 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 8 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 41) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 41) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg10].pmp41cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp42cfg & 0x1) == 0) && ((csr_value.pmp42cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp42cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp42cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg10].pmp41cfg; + pmp42cfg: + location: 23-16 + description: | + *PMP configuration for entry 42* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 23 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 22:21 ! _Reserved_ Writes shall be ignored. + h! A ! 20:19 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 18 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 17 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 16 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 42) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 42) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg10].pmp42cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp44cfg & 0x1) == 0) && ((csr_value.pmp44cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp44cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp44cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg10].pmp42cfg; + pmp43cfg: + location: 31-24 + description: | + *PMP configuration for entry 43* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 31 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 30:29 ! _Reserved_ Writes shall be ignored. + h! A ! 28:27 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 26 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 25 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 24 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 43) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 43) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg10].pmp43cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp46cfg & 0x1) == 0) && ((csr_value.pmp46cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp46cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp46cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg10].pmp43cfg; + pmp44cfg: + location: 39-32 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 44* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 39 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 38:37 ! _Reserved_ Writes shall be ignored. + h! A ! 36:35 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 34 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 33 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 32 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 44) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 44) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg10].pmp44cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp48cfg & 0x1) == 0) && ((csr_value.pmp48cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp48cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp48cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg10].pmp44cfg; + pmp45cfg: + location: 47-40 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 45* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 47 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 46:45 ! _Reserved_ Writes shall be ignored. + h! A ! 44:43 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 42 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 41 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 40 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 45) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 45) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg10].pmp45cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp50cfg & 0x1) == 0) && ((csr_value.pmp50cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp50cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp50cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg10].pmp45cfg; + pmp46cfg: + location: 55-48 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 46* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 55 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 54:53 ! _Reserved_ Writes shall be ignored. + h! A ! 52:51 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 50 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 49 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 48 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 46) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 46) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg10].pmp46cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp52cfg & 0x1) == 0) && ((csr_value.pmp52cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp52cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp52cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg10].pmp46cfg; + pmp47cfg: + location: 63-56 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 47* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 63 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 62:61 ! _Reserved_ Writes shall be ignored. + h! A ! 60:59 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 58 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 57 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 56 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 47) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 47) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg10].pmp47cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp54cfg & 0x1) == 0) && ((csr_value.pmp54cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp54cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp54cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg10].pmp47cfg; diff --git a/arch/csr/I/pmpcfg11.yaml b/arch/csr/I/pmpcfg11.yaml new file mode 100644 index 000000000..3f4574321 --- /dev/null +++ b/arch/csr/I/pmpcfg11.yaml @@ -0,0 +1,251 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpcfgN.layout + + + +pmpcfg11: + base: 32 # odd numbered pmpcfg registers do not exist in RV64 + long_name: PMP Configuration Register 11 + address: 0x3AB + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + pmp44cfg: + location: 7-0 + description: | + *PMP configuration for entry 44* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 7 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 6:5 ! _Reserved_ Writes shall be ignored. + h! A ! 4:3 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 2 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 1 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 0 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 44) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 44) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg11].pmp44cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp44cfg & 0x1) == 0) && ((csr_value.pmp44cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp44cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp44cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg11].pmp44cfg; + pmp45cfg: + location: 15-8 + description: | + *PMP configuration for entry 45* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 15 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 14:13 ! _Reserved_ Writes shall be ignored. + h! A ! 12:11 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 10 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 9 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 8 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 45) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 45) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg11].pmp45cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp46cfg & 0x1) == 0) && ((csr_value.pmp46cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp46cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp46cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg11].pmp45cfg; + pmp46cfg: + location: 23-16 + description: | + *PMP configuration for entry 46* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 23 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 22:21 ! _Reserved_ Writes shall be ignored. + h! A ! 20:19 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 18 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 17 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 16 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 46) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 46) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg11].pmp46cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp48cfg & 0x1) == 0) && ((csr_value.pmp48cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp48cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp48cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg11].pmp46cfg; + pmp47cfg: + location: 31-24 + description: | + *PMP configuration for entry 47* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 31 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 30:29 ! _Reserved_ Writes shall be ignored. + h! A ! 28:27 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 26 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 25 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 24 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 47) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 47) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg11].pmp47cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp50cfg & 0x1) == 0) && ((csr_value.pmp50cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp50cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp50cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg11].pmp47cfg; diff --git a/arch/csr/I/pmpcfg12.yaml b/arch/csr/I/pmpcfg12.yaml new file mode 100644 index 000000000..0c1f85ce6 --- /dev/null +++ b/arch/csr/I/pmpcfg12.yaml @@ -0,0 +1,490 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpcfgN.layout + + + +pmpcfg12: + long_name: PMP Configuration Register 12 + address: 0x3AC + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + pmp48cfg: + location: 7-0 + description: | + *PMP configuration for entry 48* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 7 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 6:5 ! _Reserved_ Writes shall be ignored. + h! A ! 4:3 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 2 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 1 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 0 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 48) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 48) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg12].pmp48cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp48cfg & 0x1) == 0) && ((csr_value.pmp48cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp48cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp48cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg12].pmp48cfg; + pmp49cfg: + location: 15-8 + description: | + *PMP configuration for entry 49* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 15 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 14:13 ! _Reserved_ Writes shall be ignored. + h! A ! 12:11 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 10 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 9 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 8 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 49) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 49) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg12].pmp49cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp50cfg & 0x1) == 0) && ((csr_value.pmp50cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp50cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp50cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg12].pmp49cfg; + pmp50cfg: + location: 23-16 + description: | + *PMP configuration for entry 50* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 23 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 22:21 ! _Reserved_ Writes shall be ignored. + h! A ! 20:19 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 18 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 17 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 16 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 50) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 50) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg12].pmp50cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp52cfg & 0x1) == 0) && ((csr_value.pmp52cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp52cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp52cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg12].pmp50cfg; + pmp51cfg: + location: 31-24 + description: | + *PMP configuration for entry 51* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 31 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 30:29 ! _Reserved_ Writes shall be ignored. + h! A ! 28:27 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 26 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 25 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 24 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 51) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 51) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg12].pmp51cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp54cfg & 0x1) == 0) && ((csr_value.pmp54cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp54cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp54cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg12].pmp51cfg; + pmp52cfg: + location: 39-32 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 52* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 39 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 38:37 ! _Reserved_ Writes shall be ignored. + h! A ! 36:35 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 34 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 33 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 32 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 52) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 52) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg12].pmp52cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp56cfg & 0x1) == 0) && ((csr_value.pmp56cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp56cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp56cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg12].pmp52cfg; + pmp53cfg: + location: 47-40 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 53* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 47 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 46:45 ! _Reserved_ Writes shall be ignored. + h! A ! 44:43 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 42 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 41 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 40 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 53) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 53) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg12].pmp53cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp58cfg & 0x1) == 0) && ((csr_value.pmp58cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp58cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp58cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg12].pmp53cfg; + pmp54cfg: + location: 55-48 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 54* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 55 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 54:53 ! _Reserved_ Writes shall be ignored. + h! A ! 52:51 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 50 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 49 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 48 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 54) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 54) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg12].pmp54cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp60cfg & 0x1) == 0) && ((csr_value.pmp60cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp60cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp60cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg12].pmp54cfg; + pmp55cfg: + location: 63-56 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 55* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 63 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 62:61 ! _Reserved_ Writes shall be ignored. + h! A ! 60:59 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 58 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 57 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 56 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 55) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 55) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg12].pmp55cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp62cfg & 0x1) == 0) && ((csr_value.pmp62cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp62cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp62cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg12].pmp55cfg; diff --git a/arch/csr/I/pmpcfg13.yaml b/arch/csr/I/pmpcfg13.yaml new file mode 100644 index 000000000..86ac77006 --- /dev/null +++ b/arch/csr/I/pmpcfg13.yaml @@ -0,0 +1,251 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpcfgN.layout + + + +pmpcfg13: + base: 32 # odd numbered pmpcfg registers do not exist in RV64 + long_name: PMP Configuration Register 13 + address: 0x3AD + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + pmp52cfg: + location: 7-0 + description: | + *PMP configuration for entry 52* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 7 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 6:5 ! _Reserved_ Writes shall be ignored. + h! A ! 4:3 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 2 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 1 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 0 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 52) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 52) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg13].pmp52cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp52cfg & 0x1) == 0) && ((csr_value.pmp52cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp52cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp52cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg13].pmp52cfg; + pmp53cfg: + location: 15-8 + description: | + *PMP configuration for entry 53* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 15 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 14:13 ! _Reserved_ Writes shall be ignored. + h! A ! 12:11 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 10 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 9 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 8 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 53) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 53) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg13].pmp53cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp54cfg & 0x1) == 0) && ((csr_value.pmp54cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp54cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp54cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg13].pmp53cfg; + pmp54cfg: + location: 23-16 + description: | + *PMP configuration for entry 54* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 23 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 22:21 ! _Reserved_ Writes shall be ignored. + h! A ! 20:19 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 18 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 17 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 16 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 54) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 54) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg13].pmp54cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp56cfg & 0x1) == 0) && ((csr_value.pmp56cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp56cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp56cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg13].pmp54cfg; + pmp55cfg: + location: 31-24 + description: | + *PMP configuration for entry 55* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 31 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 30:29 ! _Reserved_ Writes shall be ignored. + h! A ! 28:27 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 26 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 25 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 24 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 55) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 55) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg13].pmp55cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp58cfg & 0x1) == 0) && ((csr_value.pmp58cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp58cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp58cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg13].pmp55cfg; diff --git a/arch/csr/I/pmpcfg14.yaml b/arch/csr/I/pmpcfg14.yaml new file mode 100644 index 000000000..40d6be697 --- /dev/null +++ b/arch/csr/I/pmpcfg14.yaml @@ -0,0 +1,490 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpcfgN.layout + + + +pmpcfg14: + long_name: PMP Configuration Register 14 + address: 0x3AE + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + pmp56cfg: + location: 7-0 + description: | + *PMP configuration for entry 56* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 7 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 6:5 ! _Reserved_ Writes shall be ignored. + h! A ! 4:3 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 2 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 1 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 0 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 56) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 56) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg14].pmp56cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp56cfg & 0x1) == 0) && ((csr_value.pmp56cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp56cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp56cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg14].pmp56cfg; + pmp57cfg: + location: 15-8 + description: | + *PMP configuration for entry 57* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 15 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 14:13 ! _Reserved_ Writes shall be ignored. + h! A ! 12:11 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 10 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 9 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 8 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 57) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 57) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg14].pmp57cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp58cfg & 0x1) == 0) && ((csr_value.pmp58cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp58cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp58cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg14].pmp57cfg; + pmp58cfg: + location: 23-16 + description: | + *PMP configuration for entry 58* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 23 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 22:21 ! _Reserved_ Writes shall be ignored. + h! A ! 20:19 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 18 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 17 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 16 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 58) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 58) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg14].pmp58cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp60cfg & 0x1) == 0) && ((csr_value.pmp60cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp60cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp60cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg14].pmp58cfg; + pmp59cfg: + location: 31-24 + description: | + *PMP configuration for entry 59* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 31 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 30:29 ! _Reserved_ Writes shall be ignored. + h! A ! 28:27 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 26 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 25 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 24 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 59) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 59) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg14].pmp59cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp62cfg & 0x1) == 0) && ((csr_value.pmp62cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp62cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp62cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg14].pmp59cfg; + pmp60cfg: + location: 39-32 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 60* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 39 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 38:37 ! _Reserved_ Writes shall be ignored. + h! A ! 36:35 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 34 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 33 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 32 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 60) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 60) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg14].pmp60cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp64cfg & 0x1) == 0) && ((csr_value.pmp64cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp64cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp64cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg14].pmp60cfg; + pmp61cfg: + location: 47-40 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 61* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 47 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 46:45 ! _Reserved_ Writes shall be ignored. + h! A ! 44:43 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 42 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 41 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 40 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 61) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 61) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg14].pmp61cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp66cfg & 0x1) == 0) && ((csr_value.pmp66cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp66cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp66cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg14].pmp61cfg; + pmp62cfg: + location: 55-48 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 62* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 55 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 54:53 ! _Reserved_ Writes shall be ignored. + h! A ! 52:51 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 50 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 49 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 48 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 62) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 62) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg14].pmp62cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp68cfg & 0x1) == 0) && ((csr_value.pmp68cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp68cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp68cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg14].pmp62cfg; + pmp63cfg: + location: 63-56 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 63* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 63 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 62:61 ! _Reserved_ Writes shall be ignored. + h! A ! 60:59 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 58 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 57 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 56 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 63) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 63) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg14].pmp63cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp70cfg & 0x1) == 0) && ((csr_value.pmp70cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp70cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp70cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg14].pmp63cfg; diff --git a/arch/csr/I/pmpcfg15.yaml b/arch/csr/I/pmpcfg15.yaml new file mode 100644 index 000000000..420aef0cc --- /dev/null +++ b/arch/csr/I/pmpcfg15.yaml @@ -0,0 +1,251 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpcfgN.layout + + + +pmpcfg15: + base: 32 # odd numbered pmpcfg registers do not exist in RV64 + long_name: PMP Configuration Register 15 + address: 0x3AF + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + pmp60cfg: + location: 7-0 + description: | + *PMP configuration for entry 60* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 7 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 6:5 ! _Reserved_ Writes shall be ignored. + h! A ! 4:3 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 2 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 1 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 0 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 60) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 60) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg15].pmp60cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp60cfg & 0x1) == 0) && ((csr_value.pmp60cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp60cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp60cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg15].pmp60cfg; + pmp61cfg: + location: 15-8 + description: | + *PMP configuration for entry 61* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 15 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 14:13 ! _Reserved_ Writes shall be ignored. + h! A ! 12:11 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 10 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 9 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 8 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 61) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 61) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg15].pmp61cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp62cfg & 0x1) == 0) && ((csr_value.pmp62cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp62cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp62cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg15].pmp61cfg; + pmp62cfg: + location: 23-16 + description: | + *PMP configuration for entry 62* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 23 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 22:21 ! _Reserved_ Writes shall be ignored. + h! A ! 20:19 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 18 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 17 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 16 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 62) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 62) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg15].pmp62cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp64cfg & 0x1) == 0) && ((csr_value.pmp64cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp64cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp64cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg15].pmp62cfg; + pmp63cfg: + location: 31-24 + description: | + *PMP configuration for entry 63* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 31 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 30:29 ! _Reserved_ Writes shall be ignored. + h! A ! 28:27 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 26 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 25 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 24 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 63) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 63) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg15].pmp63cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp66cfg & 0x1) == 0) && ((csr_value.pmp66cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp66cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp66cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg15].pmp63cfg; diff --git a/arch/csr/I/pmpcfg2.yaml b/arch/csr/I/pmpcfg2.yaml new file mode 100644 index 000000000..4c57f21d5 --- /dev/null +++ b/arch/csr/I/pmpcfg2.yaml @@ -0,0 +1,490 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpcfgN.layout + + + +pmpcfg2: + long_name: PMP Configuration Register 2 + address: 0x3A2 + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + pmp8cfg: + location: 7-0 + description: | + *PMP configuration for entry 8* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 7 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 6:5 ! _Reserved_ Writes shall be ignored. + h! A ! 4:3 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 2 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 1 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 0 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 8) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 8) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg2].pmp8cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp8cfg & 0x1) == 0) && ((csr_value.pmp8cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp8cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp8cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg2].pmp8cfg; + pmp9cfg: + location: 15-8 + description: | + *PMP configuration for entry 9* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 15 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 14:13 ! _Reserved_ Writes shall be ignored. + h! A ! 12:11 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 10 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 9 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 8 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 9) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 9) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg2].pmp9cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp10cfg & 0x1) == 0) && ((csr_value.pmp10cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp10cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp10cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg2].pmp9cfg; + pmp10cfg: + location: 23-16 + description: | + *PMP configuration for entry 10* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 23 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 22:21 ! _Reserved_ Writes shall be ignored. + h! A ! 20:19 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 18 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 17 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 16 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 10) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 10) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg2].pmp10cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp12cfg & 0x1) == 0) && ((csr_value.pmp12cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp12cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp12cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg2].pmp10cfg; + pmp11cfg: + location: 31-24 + description: | + *PMP configuration for entry 11* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 31 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 30:29 ! _Reserved_ Writes shall be ignored. + h! A ! 28:27 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 26 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 25 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 24 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 11) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 11) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg2].pmp11cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp14cfg & 0x1) == 0) && ((csr_value.pmp14cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp14cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp14cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg2].pmp11cfg; + pmp12cfg: + location: 39-32 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 12* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 39 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 38:37 ! _Reserved_ Writes shall be ignored. + h! A ! 36:35 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 34 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 33 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 32 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 12) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 12) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg2].pmp12cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp16cfg & 0x1) == 0) && ((csr_value.pmp16cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp16cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp16cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg2].pmp12cfg; + pmp13cfg: + location: 47-40 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 13* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 47 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 46:45 ! _Reserved_ Writes shall be ignored. + h! A ! 44:43 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 42 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 41 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 40 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 13) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 13) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg2].pmp13cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp18cfg & 0x1) == 0) && ((csr_value.pmp18cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp18cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp18cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg2].pmp13cfg; + pmp14cfg: + location: 55-48 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 14* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 55 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 54:53 ! _Reserved_ Writes shall be ignored. + h! A ! 52:51 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 50 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 49 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 48 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 14) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 14) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg2].pmp14cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp20cfg & 0x1) == 0) && ((csr_value.pmp20cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp20cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp20cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg2].pmp14cfg; + pmp15cfg: + location: 63-56 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 15* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 63 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 62:61 ! _Reserved_ Writes shall be ignored. + h! A ! 60:59 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 58 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 57 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 56 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 15) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 15) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg2].pmp15cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp22cfg & 0x1) == 0) && ((csr_value.pmp22cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp22cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp22cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg2].pmp15cfg; diff --git a/arch/csr/I/pmpcfg3.yaml b/arch/csr/I/pmpcfg3.yaml new file mode 100644 index 000000000..e6461f88a --- /dev/null +++ b/arch/csr/I/pmpcfg3.yaml @@ -0,0 +1,251 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpcfgN.layout + + + +pmpcfg3: + base: 32 # odd numbered pmpcfg registers do not exist in RV64 + long_name: PMP Configuration Register 3 + address: 0x3A3 + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + pmp12cfg: + location: 7-0 + description: | + *PMP configuration for entry 12* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 7 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 6:5 ! _Reserved_ Writes shall be ignored. + h! A ! 4:3 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 2 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 1 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 0 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 12) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 12) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg3].pmp12cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp12cfg & 0x1) == 0) && ((csr_value.pmp12cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp12cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp12cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg3].pmp12cfg; + pmp13cfg: + location: 15-8 + description: | + *PMP configuration for entry 13* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 15 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 14:13 ! _Reserved_ Writes shall be ignored. + h! A ! 12:11 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 10 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 9 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 8 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 13) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 13) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg3].pmp13cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp14cfg & 0x1) == 0) && ((csr_value.pmp14cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp14cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp14cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg3].pmp13cfg; + pmp14cfg: + location: 23-16 + description: | + *PMP configuration for entry 14* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 23 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 22:21 ! _Reserved_ Writes shall be ignored. + h! A ! 20:19 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 18 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 17 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 16 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 14) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 14) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg3].pmp14cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp16cfg & 0x1) == 0) && ((csr_value.pmp16cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp16cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp16cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg3].pmp14cfg; + pmp15cfg: + location: 31-24 + description: | + *PMP configuration for entry 15* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 31 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 30:29 ! _Reserved_ Writes shall be ignored. + h! A ! 28:27 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 26 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 25 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 24 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 15) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 15) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg3].pmp15cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp18cfg & 0x1) == 0) && ((csr_value.pmp18cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp18cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp18cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg3].pmp15cfg; diff --git a/arch/csr/I/pmpcfg4.yaml b/arch/csr/I/pmpcfg4.yaml new file mode 100644 index 000000000..b6ce4391d --- /dev/null +++ b/arch/csr/I/pmpcfg4.yaml @@ -0,0 +1,490 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpcfgN.layout + + + +pmpcfg4: + long_name: PMP Configuration Register 4 + address: 0x3A4 + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + pmp16cfg: + location: 7-0 + description: | + *PMP configuration for entry 16* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 7 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 6:5 ! _Reserved_ Writes shall be ignored. + h! A ! 4:3 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 2 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 1 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 0 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 16) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 16) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg4].pmp16cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp16cfg & 0x1) == 0) && ((csr_value.pmp16cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp16cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp16cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg4].pmp16cfg; + pmp17cfg: + location: 15-8 + description: | + *PMP configuration for entry 17* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 15 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 14:13 ! _Reserved_ Writes shall be ignored. + h! A ! 12:11 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 10 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 9 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 8 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 17) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 17) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg4].pmp17cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp18cfg & 0x1) == 0) && ((csr_value.pmp18cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp18cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp18cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg4].pmp17cfg; + pmp18cfg: + location: 23-16 + description: | + *PMP configuration for entry 18* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 23 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 22:21 ! _Reserved_ Writes shall be ignored. + h! A ! 20:19 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 18 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 17 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 16 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 18) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 18) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg4].pmp18cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp20cfg & 0x1) == 0) && ((csr_value.pmp20cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp20cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp20cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg4].pmp18cfg; + pmp19cfg: + location: 31-24 + description: | + *PMP configuration for entry 19* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 31 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 30:29 ! _Reserved_ Writes shall be ignored. + h! A ! 28:27 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 26 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 25 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 24 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 19) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 19) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg4].pmp19cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp22cfg & 0x1) == 0) && ((csr_value.pmp22cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp22cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp22cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg4].pmp19cfg; + pmp20cfg: + location: 39-32 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 20* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 39 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 38:37 ! _Reserved_ Writes shall be ignored. + h! A ! 36:35 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 34 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 33 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 32 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 20) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 20) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg4].pmp20cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp24cfg & 0x1) == 0) && ((csr_value.pmp24cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp24cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp24cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg4].pmp20cfg; + pmp21cfg: + location: 47-40 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 21* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 47 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 46:45 ! _Reserved_ Writes shall be ignored. + h! A ! 44:43 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 42 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 41 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 40 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 21) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 21) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg4].pmp21cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp26cfg & 0x1) == 0) && ((csr_value.pmp26cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp26cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp26cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg4].pmp21cfg; + pmp22cfg: + location: 55-48 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 22* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 55 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 54:53 ! _Reserved_ Writes shall be ignored. + h! A ! 52:51 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 50 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 49 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 48 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 22) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 22) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg4].pmp22cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp28cfg & 0x1) == 0) && ((csr_value.pmp28cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp28cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp28cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg4].pmp22cfg; + pmp23cfg: + location: 63-56 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 23* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 63 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 62:61 ! _Reserved_ Writes shall be ignored. + h! A ! 60:59 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 58 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 57 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 56 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 23) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 23) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg4].pmp23cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp30cfg & 0x1) == 0) && ((csr_value.pmp30cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp30cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp30cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg4].pmp23cfg; diff --git a/arch/csr/I/pmpcfg5.yaml b/arch/csr/I/pmpcfg5.yaml new file mode 100644 index 000000000..0c386184f --- /dev/null +++ b/arch/csr/I/pmpcfg5.yaml @@ -0,0 +1,251 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpcfgN.layout + + + +pmpcfg5: + base: 32 # odd numbered pmpcfg registers do not exist in RV64 + long_name: PMP Configuration Register 5 + address: 0x3A5 + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + pmp20cfg: + location: 7-0 + description: | + *PMP configuration for entry 20* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 7 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 6:5 ! _Reserved_ Writes shall be ignored. + h! A ! 4:3 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 2 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 1 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 0 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 20) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 20) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg5].pmp20cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp20cfg & 0x1) == 0) && ((csr_value.pmp20cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp20cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp20cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg5].pmp20cfg; + pmp21cfg: + location: 15-8 + description: | + *PMP configuration for entry 21* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 15 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 14:13 ! _Reserved_ Writes shall be ignored. + h! A ! 12:11 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 10 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 9 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 8 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 21) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 21) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg5].pmp21cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp22cfg & 0x1) == 0) && ((csr_value.pmp22cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp22cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp22cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg5].pmp21cfg; + pmp22cfg: + location: 23-16 + description: | + *PMP configuration for entry 22* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 23 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 22:21 ! _Reserved_ Writes shall be ignored. + h! A ! 20:19 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 18 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 17 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 16 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 22) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 22) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg5].pmp22cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp24cfg & 0x1) == 0) && ((csr_value.pmp24cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp24cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp24cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg5].pmp22cfg; + pmp23cfg: + location: 31-24 + description: | + *PMP configuration for entry 23* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 31 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 30:29 ! _Reserved_ Writes shall be ignored. + h! A ! 28:27 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 26 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 25 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 24 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 23) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 23) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg5].pmp23cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp26cfg & 0x1) == 0) && ((csr_value.pmp26cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp26cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp26cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg5].pmp23cfg; diff --git a/arch/csr/I/pmpcfg6.yaml b/arch/csr/I/pmpcfg6.yaml new file mode 100644 index 000000000..ce01e41aa --- /dev/null +++ b/arch/csr/I/pmpcfg6.yaml @@ -0,0 +1,490 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpcfgN.layout + + + +pmpcfg6: + long_name: PMP Configuration Register 6 + address: 0x3A6 + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + pmp24cfg: + location: 7-0 + description: | + *PMP configuration for entry 24* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 7 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 6:5 ! _Reserved_ Writes shall be ignored. + h! A ! 4:3 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 2 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 1 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 0 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 24) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 24) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg6].pmp24cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp24cfg & 0x1) == 0) && ((csr_value.pmp24cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp24cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp24cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg6].pmp24cfg; + pmp25cfg: + location: 15-8 + description: | + *PMP configuration for entry 25* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 15 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 14:13 ! _Reserved_ Writes shall be ignored. + h! A ! 12:11 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 10 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 9 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 8 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 25) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 25) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg6].pmp25cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp26cfg & 0x1) == 0) && ((csr_value.pmp26cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp26cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp26cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg6].pmp25cfg; + pmp26cfg: + location: 23-16 + description: | + *PMP configuration for entry 26* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 23 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 22:21 ! _Reserved_ Writes shall be ignored. + h! A ! 20:19 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 18 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 17 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 16 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 26) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 26) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg6].pmp26cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp28cfg & 0x1) == 0) && ((csr_value.pmp28cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp28cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp28cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg6].pmp26cfg; + pmp27cfg: + location: 31-24 + description: | + *PMP configuration for entry 27* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 31 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 30:29 ! _Reserved_ Writes shall be ignored. + h! A ! 28:27 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 26 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 25 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 24 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 27) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 27) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg6].pmp27cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp30cfg & 0x1) == 0) && ((csr_value.pmp30cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp30cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp30cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg6].pmp27cfg; + pmp28cfg: + location: 39-32 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 28* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 39 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 38:37 ! _Reserved_ Writes shall be ignored. + h! A ! 36:35 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 34 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 33 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 32 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 28) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 28) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg6].pmp28cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp32cfg & 0x1) == 0) && ((csr_value.pmp32cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp32cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp32cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg6].pmp28cfg; + pmp29cfg: + location: 47-40 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 29* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 47 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 46:45 ! _Reserved_ Writes shall be ignored. + h! A ! 44:43 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 42 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 41 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 40 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 29) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 29) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg6].pmp29cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp34cfg & 0x1) == 0) && ((csr_value.pmp34cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp34cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp34cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg6].pmp29cfg; + pmp30cfg: + location: 55-48 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 30* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 55 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 54:53 ! _Reserved_ Writes shall be ignored. + h! A ! 52:51 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 50 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 49 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 48 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 30) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 30) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg6].pmp30cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp36cfg & 0x1) == 0) && ((csr_value.pmp36cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp36cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp36cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg6].pmp30cfg; + pmp31cfg: + location: 63-56 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 31* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 63 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 62:61 ! _Reserved_ Writes shall be ignored. + h! A ! 60:59 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 58 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 57 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 56 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 31) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 31) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg6].pmp31cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp38cfg & 0x1) == 0) && ((csr_value.pmp38cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp38cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp38cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg6].pmp31cfg; diff --git a/arch/csr/I/pmpcfg7.yaml b/arch/csr/I/pmpcfg7.yaml new file mode 100644 index 000000000..861d8cf1c --- /dev/null +++ b/arch/csr/I/pmpcfg7.yaml @@ -0,0 +1,251 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpcfgN.layout + + + +pmpcfg7: + base: 32 # odd numbered pmpcfg registers do not exist in RV64 + long_name: PMP Configuration Register 7 + address: 0x3A7 + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + pmp28cfg: + location: 7-0 + description: | + *PMP configuration for entry 28* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 7 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 6:5 ! _Reserved_ Writes shall be ignored. + h! A ! 4:3 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 2 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 1 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 0 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 28) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 28) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg7].pmp28cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp28cfg & 0x1) == 0) && ((csr_value.pmp28cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp28cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp28cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg7].pmp28cfg; + pmp29cfg: + location: 15-8 + description: | + *PMP configuration for entry 29* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 15 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 14:13 ! _Reserved_ Writes shall be ignored. + h! A ! 12:11 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 10 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 9 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 8 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 29) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 29) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg7].pmp29cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp30cfg & 0x1) == 0) && ((csr_value.pmp30cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp30cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp30cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg7].pmp29cfg; + pmp30cfg: + location: 23-16 + description: | + *PMP configuration for entry 30* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 23 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 22:21 ! _Reserved_ Writes shall be ignored. + h! A ! 20:19 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 18 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 17 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 16 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 30) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 30) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg7].pmp30cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp32cfg & 0x1) == 0) && ((csr_value.pmp32cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp32cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp32cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg7].pmp30cfg; + pmp31cfg: + location: 31-24 + description: | + *PMP configuration for entry 31* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 31 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 30:29 ! _Reserved_ Writes shall be ignored. + h! A ! 28:27 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 26 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 25 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 24 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 31) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 31) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg7].pmp31cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp34cfg & 0x1) == 0) && ((csr_value.pmp34cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp34cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp34cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg7].pmp31cfg; diff --git a/arch/csr/I/pmpcfg8.yaml b/arch/csr/I/pmpcfg8.yaml new file mode 100644 index 000000000..67f8a3671 --- /dev/null +++ b/arch/csr/I/pmpcfg8.yaml @@ -0,0 +1,490 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpcfgN.layout + + + +pmpcfg8: + long_name: PMP Configuration Register 8 + address: 0x3A8 + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + pmp32cfg: + location: 7-0 + description: | + *PMP configuration for entry 32* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 7 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 6:5 ! _Reserved_ Writes shall be ignored. + h! A ! 4:3 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 2 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 1 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 0 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 32) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 32) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg8].pmp32cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp32cfg & 0x1) == 0) && ((csr_value.pmp32cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp32cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp32cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg8].pmp32cfg; + pmp33cfg: + location: 15-8 + description: | + *PMP configuration for entry 33* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 15 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 14:13 ! _Reserved_ Writes shall be ignored. + h! A ! 12:11 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 10 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 9 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 8 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 33) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 33) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg8].pmp33cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp34cfg & 0x1) == 0) && ((csr_value.pmp34cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp34cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp34cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg8].pmp33cfg; + pmp34cfg: + location: 23-16 + description: | + *PMP configuration for entry 34* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 23 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 22:21 ! _Reserved_ Writes shall be ignored. + h! A ! 20:19 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 18 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 17 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 16 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 34) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 34) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg8].pmp34cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp36cfg & 0x1) == 0) && ((csr_value.pmp36cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp36cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp36cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg8].pmp34cfg; + pmp35cfg: + location: 31-24 + description: | + *PMP configuration for entry 35* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 31 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 30:29 ! _Reserved_ Writes shall be ignored. + h! A ! 28:27 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 26 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 25 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 24 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 35) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 35) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg8].pmp35cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp38cfg & 0x1) == 0) && ((csr_value.pmp38cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp38cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp38cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg8].pmp35cfg; + pmp36cfg: + location: 39-32 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 36* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 39 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 38:37 ! _Reserved_ Writes shall be ignored. + h! A ! 36:35 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 34 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 33 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 32 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 36) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 36) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg8].pmp36cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp40cfg & 0x1) == 0) && ((csr_value.pmp40cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp40cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp40cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg8].pmp36cfg; + pmp37cfg: + location: 47-40 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 37* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 47 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 46:45 ! _Reserved_ Writes shall be ignored. + h! A ! 44:43 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 42 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 41 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 40 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 37) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 37) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg8].pmp37cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp42cfg & 0x1) == 0) && ((csr_value.pmp42cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp42cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp42cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg8].pmp37cfg; + pmp38cfg: + location: 55-48 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 38* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 55 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 54:53 ! _Reserved_ Writes shall be ignored. + h! A ! 52:51 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 50 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 49 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 48 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 38) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 38) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg8].pmp38cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp44cfg & 0x1) == 0) && ((csr_value.pmp44cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp44cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp44cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg8].pmp38cfg; + pmp39cfg: + location: 63-56 + base: 32 # upper half doesn't exist in RV32 + description: | + *PMP configuration for entry 39* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 63 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 62:61 ! _Reserved_ Writes shall be ignored. + h! A ! 60:59 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 58 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 57 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 56 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 39) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 39) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg8].pmp39cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp46cfg & 0x1) == 0) && ((csr_value.pmp46cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp46cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp46cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg8].pmp39cfg; diff --git a/arch/csr/I/pmpcfg9.yaml b/arch/csr/I/pmpcfg9.yaml new file mode 100644 index 000000000..d83c7969c --- /dev/null +++ b/arch/csr/I/pmpcfg9.yaml @@ -0,0 +1,251 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/I/pmpcfgN.layout + + + +pmpcfg9: + base: 32 # odd numbered pmpcfg registers do not exist in RV64 + long_name: PMP Configuration Register 9 + address: 0x3A9 + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + pmp36cfg: + location: 7-0 + description: | + *PMP configuration for entry 36* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 7 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 6:5 ! _Reserved_ Writes shall be ignored. + h! A ! 4:3 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 2 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 1 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 0 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 36) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 36) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg9].pmp36cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp36cfg & 0x1) == 0) && ((csr_value.pmp36cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp36cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp36cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg9].pmp36cfg; + pmp37cfg: + location: 15-8 + description: | + *PMP configuration for entry 37* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 15 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 14:13 ! _Reserved_ Writes shall be ignored. + h! A ! 12:11 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 10 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 9 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 8 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 37) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 37) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg9].pmp37cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp38cfg & 0x1) == 0) && ((csr_value.pmp38cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp38cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp38cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg9].pmp37cfg; + pmp38cfg: + location: 23-16 + description: | + *PMP configuration for entry 38* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 23 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 22:21 ! _Reserved_ Writes shall be ignored. + h! A ! 20:19 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 18 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 17 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 16 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 38) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 38) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg9].pmp38cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp40cfg & 0x1) == 0) && ((csr_value.pmp40cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp40cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp40cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg9].pmp38cfg; + pmp39cfg: + location: 31-24 + description: | + *PMP configuration for entry 39* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! 31 ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! 30:29 ! _Reserved_ Writes shall be ignored. + h! A ! 28:27 + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%- end -%> + + h! X ! 26 ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! 25 ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! 24 ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > 39) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > 39) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[pmpcfg9].pmp39cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp42cfg & 0x1) == 0) && ((csr_value.pmp42cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp42cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp42cfg; + } + } + } + # fall through: keep old value + return CSR[pmpcfg9].pmp39cfg; diff --git a/arch/csr/I/pmpcfgN.layout b/arch/csr/I/pmpcfgN.layout new file mode 100644 index 000000000..6a57fca6e --- /dev/null +++ b/arch/csr/I/pmpcfgN.layout @@ -0,0 +1,79 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +<%- raise "'pmpcfg_num' must be defined" if pmpcfg_num.nil? -%> + +pmpcfg<%= pmpcfg_num %>: + <%- if pmpcfg_num.odd? -%> + base: 32 # odd numbered pmpcfg registers do not exist in RV64 + <%- end -%> + long_name: PMP Configuration Register <%= pmpcfg_num %> + address: 0x<%= (0x3A0 + pmpcfg_num).to_s(16).upcase %> + priv_mode: M + length: MXLEN + description: PMP entry configuration + definedBy: I + fields: + <%- (pmpcfg_num.odd? ? 4 : 8).times do |i| -%> + pmp<%= pmpcfg_num*4 + i %>cfg: + location: <%= ((i+1)*8)-1 %>-<%= i*8 %> + <%- if i >= 4 -%> + base: 32 # upper half doesn't exist in RV32 + <%- end -%> + description: | + *PMP configuration for entry <%= pmpcfg_num*4 + i %>* + + The bits are as follows: + + [%autowidth] + !=== + ! Name ! Location ! Description + + h! L ! <%= ((i+1)*8)-1 %> ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. + h! - ! <%= ((i+1)*8)-2 %>:<%= ((i+1)*8)-3 %> ! _Reserved_ Writes shall be ignored. + h! A ! <%= ((i+1)*8)-4 %>:<%= ((i+1)*8)-5 %> + a! Address matching mode. One of: + + * *OFF* (0) - Null region (disabled) + * *TOR* (1) - Top of range + <%%- if PMP_GRANULARITY < 2 -%> + * *NA4* (2) - Naturally aligned four-byte region + <%%- end -%> + * *NAPOT* (3) - Natrually aligned power of two + + <%%- if PMP_GRANULARITY >= 2 -%> + Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). + <%%- end -%> + + h! X ! <%= ((i)*8)+2 %> ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. + h! W ! <%= ((i)*8)+1 %> ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. + h! R ! <%= ((i)*8)+0 %> ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. + !=== + + The combination of R = 0, W = 1 is reserved. + type(): | + if (NUM_PMP_ENTRIES > <%= pmpcfg_num*4 + i %>) { + return CsrFieldType::RWR; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_PMP_ENTRIES > <%= pmpcfg_num*4 + i %>) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if ((CSR[<%= "pmpcfg#{pmpcfg_num}" %>].pmp<%= pmpcfg_num*4 + i %>cfg & 0x80) == 0) { + # entry is not locked + if (!(((csr_value.pmp<%= pmpcfg_num*4 + i + i %>cfg & 0x1) == 0) && ((csr_value.pmp<%= pmpcfg_num*4 + i + i %>cfg & 0x2) == 0x2))) { + # not R = 0, W =1, which is reserved + if ((PMP_GRANULARITY < 2) || + ((csr_value.pmp<%= pmpcfg_num*4 + i + i %>cfg & 0x18) != 0x10)) { + # NA4 is not allowed when PMP granularity is larger than 4 bytes + return csr_value.pmp<%= pmpcfg_num*4 + i + i %>cfg; + } + } + } + # fall through: keep old value + return CSR[<%= "pmpcfg#{pmpcfg_num}" %>].pmp<%= pmpcfg_num*4 + i %>cfg; + <%- end -%> diff --git a/arch/csr/S/scounteren.layout b/arch/csr/S/scounteren.layout new file mode 100644 index 000000000..598a4b940 --- /dev/null +++ b/arch/csr/S/scounteren.layout @@ -0,0 +1,81 @@ +# yaml-language-server: $schema=../../schemas/csr_schema.json + +scounteren: + long_name: Supervisor Counter Enable + address: 0x106 + priv_mode: M + length: 32 + description: | + Delegates control of the hardware performance-monitoring counters + to U-mode + definedBy: S + fields: + CY: + location: 0 + 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 + 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 + <%- (3..31).each do |hpm_num| -%> + HPM<%= hpm_num %>: + location: <%= hpm_num %> + description: | + 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 + <%- 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[scountern]) & $bits(CSR[mcounteren]); \ No newline at end of file diff --git a/arch/csr/S/scounteren.yaml b/arch/csr/S/scounteren.yaml new file mode 100644 index 000000000..f9a7140e2 --- /dev/null +++ b/arch/csr/S/scounteren.yaml @@ -0,0 +1,642 @@ +# yaml-language-server: $schema=../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/S/scounteren.layout + + +scounteren: + long_name: Supervisor Counter Enable + address: 0x106 + priv_mode: M + length: 32 + description: | + Delegates control of the hardware performance-monitoring counters + to U-mode + definedBy: S + fields: + CY: + location: 0 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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[scountern]) & $bits(CSR[mcounteren]); \ No newline at end of file diff --git a/arch/csr/mcountinhibit.yaml b/arch/csr/Zicntr/mcountinhibit.layout similarity index 82% rename from arch/csr/mcountinhibit.yaml rename to arch/csr/Zicntr/mcountinhibit.layout index 1566b5f65..a1a052450 100644 --- a/arch/csr/mcountinhibit.yaml +++ b/arch/csr/Zicntr/mcountinhibit.layout @@ -1,4 +1,4 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json +# yaml-language-server: $schema=../../../schemas/csr_schema.json mcountinhibit: long_name: Machine Counter Inhibit @@ -37,7 +37,7 @@ mcountinhibit: cannot be inhibited with the `mcountinhibit` mechanism. ==== - definedBy: I + definedBy: [Zicntr, Zihpm] fields: CY: location: 0 @@ -53,10 +53,15 @@ mcountinhibit: return COUNTINHIBIT_EN[2] ? CsrFieldType::RW : CsrFieldType::RO; reset_value(): | return COUNTINHIBIT_EN[2] ? UNDEFINED_LEGAL : 0; - <%- NUM_HPM_COUNTERS.times do |hpm_num| -%> - HPM<%= hpm_num + 3 %>: - location: <%= 3 + hpm_num %> - description: When set, `hpmcounter<%= 3 + hpm_num %>.COUNT` stops counting in all privilege modes. + <%- (3..31).each do |hpm_num| -%> + HPM<%= hpm_num %>: + location: <%= hpm_num %> + description: | + <%%- if NUM_HPM_COUNTERS > <%= hpm_num - 3%> -%> + 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. + <%%- end -%> type(): | return COUNTINHIBIT_EN[<%= hpm_num %>] ? CsrFieldType::RW : CsrFieldType::RO; reset_value(): | diff --git a/arch/csr/Zicntr/mcountinhibit.yaml b/arch/csr/Zicntr/mcountinhibit.yaml new file mode 100644 index 000000000..0c5f3176e --- /dev/null +++ b/arch/csr/Zicntr/mcountinhibit.yaml @@ -0,0 +1,406 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zicntr/mcountinhibit.layout + + +mcountinhibit: + long_name: Machine Counter Inhibit + address: 0x320 + priv_mode: M + length: 32 + description: | + Bits to inhibit (stops counting) performance counters. + + The counter-inhibit register `mcountinhibit` is a *WARL* register that + controls which of the hardware performance-monitoring counters + increment. The settings in this register only control whether the + counters increment; their accessibility is not affected by the setting + of this register. + + When the CY, IR, or HPM__n__ bit in the `mcountinhibit` register is clear, + the `mcycle`, `minstret`, or `mhpmcountern` register increments as usual. + When the CY, IR, or HPM_n_ bit is set, the corresponding counter does + not increment. + + The `mcycle` CSR may be shared between harts on the same core, in which + case the `mcountinhibit.CY` field is also shared between those harts, + and so writes to `mcountinhibit.CY` will be visible to those harts. + + If the `mcountinhibit` register is not implemented, the implementation + behaves as though the register were set to zero. + + [NOTE] + ==== + When the `mcycle` and `minstret` counters are not needed, it is desirable + to conditionally inhibit them to reduce energy consumption. Providing a + single CSR to inhibit all counters also allows the counters to be + atomically sampled. + + Because the `mtime` counter can be shared between multiple cores, it + cannot be inhibited with the `mcountinhibit` mechanism. + ==== + + definedBy: [Zicntr, Zihpm] + fields: + CY: + location: 0 + description: When set, `mcycle.COUNT` stops counting in all privilege modes. + type(): | + return COUNTINHIBIT_EN[0] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[0] ? UNDEFINED_LEGAL : 0; + IR: + location: 2 + description: When set, `minstret.COUNT` stops counting in all privilege modes. + type(): | + return COUNTINHIBIT_EN[2] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[2] ? UNDEFINED_LEGAL : 0; + HPM3: + location: 3 + description: | + <%- if NUM_HPM_COUNTERS > 0 -%> + When set, `hpmcounter3.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter3 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[3] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[3] ? UNDEFINED_LEGAL : 0; + HPM4: + location: 4 + description: | + <%- if NUM_HPM_COUNTERS > 1 -%> + When set, `hpmcounter4.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter4 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[4] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[4] ? UNDEFINED_LEGAL : 0; + HPM5: + location: 5 + description: | + <%- if NUM_HPM_COUNTERS > 2 -%> + When set, `hpmcounter5.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter5 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[5] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[5] ? UNDEFINED_LEGAL : 0; + HPM6: + location: 6 + description: | + <%- if NUM_HPM_COUNTERS > 3 -%> + When set, `hpmcounter6.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter6 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[6] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[6] ? UNDEFINED_LEGAL : 0; + HPM7: + location: 7 + description: | + <%- if NUM_HPM_COUNTERS > 4 -%> + When set, `hpmcounter7.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter7 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[7] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[7] ? UNDEFINED_LEGAL : 0; + HPM8: + location: 8 + description: | + <%- if NUM_HPM_COUNTERS > 5 -%> + When set, `hpmcounter8.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter8 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[8] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[8] ? UNDEFINED_LEGAL : 0; + HPM9: + location: 9 + description: | + <%- if NUM_HPM_COUNTERS > 6 -%> + When set, `hpmcounter9.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter9 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[9] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[9] ? UNDEFINED_LEGAL : 0; + HPM10: + location: 10 + description: | + <%- if NUM_HPM_COUNTERS > 7 -%> + When set, `hpmcounter10.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter10 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[10] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[10] ? UNDEFINED_LEGAL : 0; + HPM11: + location: 11 + description: | + <%- if NUM_HPM_COUNTERS > 8 -%> + When set, `hpmcounter11.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter11 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[11] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[11] ? UNDEFINED_LEGAL : 0; + HPM12: + location: 12 + description: | + <%- if NUM_HPM_COUNTERS > 9 -%> + When set, `hpmcounter12.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter12 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[12] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[12] ? UNDEFINED_LEGAL : 0; + HPM13: + location: 13 + description: | + <%- if NUM_HPM_COUNTERS > 10 -%> + When set, `hpmcounter13.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter13 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[13] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[13] ? UNDEFINED_LEGAL : 0; + HPM14: + location: 14 + description: | + <%- if NUM_HPM_COUNTERS > 11 -%> + When set, `hpmcounter14.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter14 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[14] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[14] ? UNDEFINED_LEGAL : 0; + HPM15: + location: 15 + description: | + <%- if NUM_HPM_COUNTERS > 12 -%> + When set, `hpmcounter15.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter15 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[15] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[15] ? UNDEFINED_LEGAL : 0; + HPM16: + location: 16 + description: | + <%- if NUM_HPM_COUNTERS > 13 -%> + When set, `hpmcounter16.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter16 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[16] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[16] ? UNDEFINED_LEGAL : 0; + HPM17: + location: 17 + description: | + <%- if NUM_HPM_COUNTERS > 14 -%> + When set, `hpmcounter17.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter17 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[17] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[17] ? UNDEFINED_LEGAL : 0; + HPM18: + location: 18 + description: | + <%- if NUM_HPM_COUNTERS > 15 -%> + When set, `hpmcounter18.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter18 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[18] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[18] ? UNDEFINED_LEGAL : 0; + HPM19: + location: 19 + description: | + <%- if NUM_HPM_COUNTERS > 16 -%> + When set, `hpmcounter19.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter19 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[19] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[19] ? UNDEFINED_LEGAL : 0; + HPM20: + location: 20 + description: | + <%- if NUM_HPM_COUNTERS > 17 -%> + When set, `hpmcounter20.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter20 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[20] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[20] ? UNDEFINED_LEGAL : 0; + HPM21: + location: 21 + description: | + <%- if NUM_HPM_COUNTERS > 18 -%> + When set, `hpmcounter21.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter21 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[21] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[21] ? UNDEFINED_LEGAL : 0; + HPM22: + location: 22 + description: | + <%- if NUM_HPM_COUNTERS > 19 -%> + When set, `hpmcounter22.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter22 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[22] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[22] ? UNDEFINED_LEGAL : 0; + HPM23: + location: 23 + description: | + <%- if NUM_HPM_COUNTERS > 20 -%> + When set, `hpmcounter23.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter23 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[23] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[23] ? UNDEFINED_LEGAL : 0; + HPM24: + location: 24 + description: | + <%- if NUM_HPM_COUNTERS > 21 -%> + When set, `hpmcounter24.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter24 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[24] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[24] ? UNDEFINED_LEGAL : 0; + HPM25: + location: 25 + description: | + <%- if NUM_HPM_COUNTERS > 22 -%> + When set, `hpmcounter25.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter25 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[25] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[25] ? UNDEFINED_LEGAL : 0; + HPM26: + location: 26 + description: | + <%- if NUM_HPM_COUNTERS > 23 -%> + When set, `hpmcounter26.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter26 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[26] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[26] ? UNDEFINED_LEGAL : 0; + HPM27: + location: 27 + description: | + <%- if NUM_HPM_COUNTERS > 24 -%> + When set, `hpmcounter27.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter27 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[27] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[27] ? UNDEFINED_LEGAL : 0; + HPM28: + location: 28 + description: | + <%- if NUM_HPM_COUNTERS > 25 -%> + When set, `hpmcounter28.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter28 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[28] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[28] ? UNDEFINED_LEGAL : 0; + HPM29: + location: 29 + description: | + <%- if NUM_HPM_COUNTERS > 26 -%> + When set, `hpmcounter29.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter29 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[29] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[29] ? UNDEFINED_LEGAL : 0; + HPM30: + location: 30 + description: | + <%- if NUM_HPM_COUNTERS > 27 -%> + When set, `hpmcounter30.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter30 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[30] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[30] ? UNDEFINED_LEGAL : 0; + HPM31: + location: 31 + description: | + <%- if NUM_HPM_COUNTERS > 28 -%> + When set, `hpmcounter31.COUNT` stops counting in all privilege modes. + <%- else -%> + Since hpmcounter31 is not implemented, this field is read-only zero. + <%- end -%> + type(): | + return COUNTINHIBIT_EN[31] ? CsrFieldType::RW : CsrFieldType::RO; + reset_value(): | + return COUNTINHIBIT_EN[31] ? UNDEFINED_LEGAL : 0; diff --git a/arch/csr/Zihpm/hpmcounter10.yaml b/arch/csr/Zihpm/hpmcounter10.yaml new file mode 100644 index 000000000..9031ecf2f --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter10.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter10: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC0A + description: | + Alias for M-mode CSR `mhpmcounter10`. + + Privilege mode access is controlled with `mcounteren.HPM10`, `scounteren.HPM10`, and `hcounteren.HPM10` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM10`# .2+h! [.rotate]#`scounteren.HPM10`# .2+h! [.rotate]#`hcounteren.HPM10`# + 4+^.>h! `hpmcounter10` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter10.COUNT + description: Alias of `mhpmcounter10.COUNT`. + 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].HPM10 == 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].HPM10 & CSR[scounteren].HPM10) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM10 == 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].HPM10 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM10 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM10 & CSR[scounteren].HPM10) == 1'b0) && (CSR[mcounteren].HPM10 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM10 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(10); diff --git a/arch/csr/Zihpm/hpmcounter10h.yaml b/arch/csr/Zihpm/hpmcounter10h.yaml new file mode 100644 index 000000000..3a7451f16 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter10h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter10h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC8A + description: | + Alias for M-mode CSR `mhpmcounter10h`. + + Privilege mode access is controlled with `mcounteren.HPM10`, `scounteren.HPM10`, and `hcounteren.HPM10` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM10`# .2+h! [.rotate]#`scounteren.HPM10`# .2+h! [.rotate]#`hcounteren.HPM10`# + 4+^.>h! `hpmcounter10h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter10h.COUNT + description: Alias of `mhpmcounter10h.COUNT`. + 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].HPM10 == 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].HPM10 & CSR[scounteren].HPM10) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM10 == 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].HPM10 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM10 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM10 & CSR[scounteren].HPM10) == 1'b0) && (CSR[mcounteren].HPM10 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM10 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(10)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter11.yaml b/arch/csr/Zihpm/hpmcounter11.yaml new file mode 100644 index 000000000..aab87d958 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter11.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter11: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC0B + description: | + Alias for M-mode CSR `mhpmcounter11`. + + Privilege mode access is controlled with `mcounteren.HPM11`, `scounteren.HPM11`, and `hcounteren.HPM11` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM11`# .2+h! [.rotate]#`scounteren.HPM11`# .2+h! [.rotate]#`hcounteren.HPM11`# + 4+^.>h! `hpmcounter11` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter11.COUNT + description: Alias of `mhpmcounter11.COUNT`. + 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].HPM11 == 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].HPM11 & CSR[scounteren].HPM11) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM11 == 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].HPM11 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM11 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM11 & CSR[scounteren].HPM11) == 1'b0) && (CSR[mcounteren].HPM11 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM11 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(11); diff --git a/arch/csr/Zihpm/hpmcounter11h.yaml b/arch/csr/Zihpm/hpmcounter11h.yaml new file mode 100644 index 000000000..1e03d1c2b --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter11h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter11h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC8B + description: | + Alias for M-mode CSR `mhpmcounter11h`. + + Privilege mode access is controlled with `mcounteren.HPM11`, `scounteren.HPM11`, and `hcounteren.HPM11` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM11`# .2+h! [.rotate]#`scounteren.HPM11`# .2+h! [.rotate]#`hcounteren.HPM11`# + 4+^.>h! `hpmcounter11h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter11h.COUNT + description: Alias of `mhpmcounter11h.COUNT`. + 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].HPM11 == 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].HPM11 & CSR[scounteren].HPM11) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM11 == 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].HPM11 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM11 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM11 & CSR[scounteren].HPM11) == 1'b0) && (CSR[mcounteren].HPM11 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM11 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(11)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter12.yaml b/arch/csr/Zihpm/hpmcounter12.yaml new file mode 100644 index 000000000..65e4d3f66 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter12.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter12: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC0C + description: | + Alias for M-mode CSR `mhpmcounter12`. + + Privilege mode access is controlled with `mcounteren.HPM12`, `scounteren.HPM12`, and `hcounteren.HPM12` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM12`# .2+h! [.rotate]#`scounteren.HPM12`# .2+h! [.rotate]#`hcounteren.HPM12`# + 4+^.>h! `hpmcounter12` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter12.COUNT + description: Alias of `mhpmcounter12.COUNT`. + 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].HPM12 == 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].HPM12 & CSR[scounteren].HPM12) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM12 == 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].HPM12 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM12 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM12 & CSR[scounteren].HPM12) == 1'b0) && (CSR[mcounteren].HPM12 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM12 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(12); diff --git a/arch/csr/Zihpm/hpmcounter12h.yaml b/arch/csr/Zihpm/hpmcounter12h.yaml new file mode 100644 index 000000000..2e5ae6d91 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter12h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter12h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC8C + description: | + Alias for M-mode CSR `mhpmcounter12h`. + + Privilege mode access is controlled with `mcounteren.HPM12`, `scounteren.HPM12`, and `hcounteren.HPM12` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM12`# .2+h! [.rotate]#`scounteren.HPM12`# .2+h! [.rotate]#`hcounteren.HPM12`# + 4+^.>h! `hpmcounter12h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter12h.COUNT + description: Alias of `mhpmcounter12h.COUNT`. + 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].HPM12 == 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].HPM12 & CSR[scounteren].HPM12) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM12 == 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].HPM12 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM12 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM12 & CSR[scounteren].HPM12) == 1'b0) && (CSR[mcounteren].HPM12 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM12 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(12)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter13.yaml b/arch/csr/Zihpm/hpmcounter13.yaml new file mode 100644 index 000000000..178377f4a --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter13.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter13: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC0D + description: | + Alias for M-mode CSR `mhpmcounter13`. + + Privilege mode access is controlled with `mcounteren.HPM13`, `scounteren.HPM13`, and `hcounteren.HPM13` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM13`# .2+h! [.rotate]#`scounteren.HPM13`# .2+h! [.rotate]#`hcounteren.HPM13`# + 4+^.>h! `hpmcounter13` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter13.COUNT + description: Alias of `mhpmcounter13.COUNT`. + 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].HPM13 == 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].HPM13 & CSR[scounteren].HPM13) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM13 == 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].HPM13 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM13 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM13 & CSR[scounteren].HPM13) == 1'b0) && (CSR[mcounteren].HPM13 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM13 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(13); diff --git a/arch/csr/Zihpm/hpmcounter13h.yaml b/arch/csr/Zihpm/hpmcounter13h.yaml new file mode 100644 index 000000000..c96783e56 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter13h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter13h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC8D + description: | + Alias for M-mode CSR `mhpmcounter13h`. + + Privilege mode access is controlled with `mcounteren.HPM13`, `scounteren.HPM13`, and `hcounteren.HPM13` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM13`# .2+h! [.rotate]#`scounteren.HPM13`# .2+h! [.rotate]#`hcounteren.HPM13`# + 4+^.>h! `hpmcounter13h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter13h.COUNT + description: Alias of `mhpmcounter13h.COUNT`. + 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].HPM13 == 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].HPM13 & CSR[scounteren].HPM13) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM13 == 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].HPM13 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM13 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM13 & CSR[scounteren].HPM13) == 1'b0) && (CSR[mcounteren].HPM13 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM13 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(13)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter14.yaml b/arch/csr/Zihpm/hpmcounter14.yaml new file mode 100644 index 000000000..987d174b6 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter14.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter14: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC0E + description: | + Alias for M-mode CSR `mhpmcounter14`. + + Privilege mode access is controlled with `mcounteren.HPM14`, `scounteren.HPM14`, and `hcounteren.HPM14` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM14`# .2+h! [.rotate]#`scounteren.HPM14`# .2+h! [.rotate]#`hcounteren.HPM14`# + 4+^.>h! `hpmcounter14` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter14.COUNT + description: Alias of `mhpmcounter14.COUNT`. + 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].HPM14 == 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].HPM14 & CSR[scounteren].HPM14) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM14 == 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].HPM14 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM14 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM14 & CSR[scounteren].HPM14) == 1'b0) && (CSR[mcounteren].HPM14 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM14 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(14); diff --git a/arch/csr/Zihpm/hpmcounter14h.yaml b/arch/csr/Zihpm/hpmcounter14h.yaml new file mode 100644 index 000000000..2384eb300 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter14h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter14h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC8E + description: | + Alias for M-mode CSR `mhpmcounter14h`. + + Privilege mode access is controlled with `mcounteren.HPM14`, `scounteren.HPM14`, and `hcounteren.HPM14` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM14`# .2+h! [.rotate]#`scounteren.HPM14`# .2+h! [.rotate]#`hcounteren.HPM14`# + 4+^.>h! `hpmcounter14h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter14h.COUNT + description: Alias of `mhpmcounter14h.COUNT`. + 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].HPM14 == 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].HPM14 & CSR[scounteren].HPM14) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM14 == 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].HPM14 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM14 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM14 & CSR[scounteren].HPM14) == 1'b0) && (CSR[mcounteren].HPM14 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM14 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(14)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter15.yaml b/arch/csr/Zihpm/hpmcounter15.yaml new file mode 100644 index 000000000..07b5bd564 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter15.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter15: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC0F + description: | + Alias for M-mode CSR `mhpmcounter15`. + + Privilege mode access is controlled with `mcounteren.HPM15`, `scounteren.HPM15`, and `hcounteren.HPM15` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM15`# .2+h! [.rotate]#`scounteren.HPM15`# .2+h! [.rotate]#`hcounteren.HPM15`# + 4+^.>h! `hpmcounter15` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter15.COUNT + description: Alias of `mhpmcounter15.COUNT`. + 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].HPM15 == 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].HPM15 & CSR[scounteren].HPM15) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM15 == 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].HPM15 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM15 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM15 & CSR[scounteren].HPM15) == 1'b0) && (CSR[mcounteren].HPM15 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM15 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(15); diff --git a/arch/csr/Zihpm/hpmcounter15h.yaml b/arch/csr/Zihpm/hpmcounter15h.yaml new file mode 100644 index 000000000..100af9439 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter15h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter15h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC8F + description: | + Alias for M-mode CSR `mhpmcounter15h`. + + Privilege mode access is controlled with `mcounteren.HPM15`, `scounteren.HPM15`, and `hcounteren.HPM15` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM15`# .2+h! [.rotate]#`scounteren.HPM15`# .2+h! [.rotate]#`hcounteren.HPM15`# + 4+^.>h! `hpmcounter15h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter15h.COUNT + description: Alias of `mhpmcounter15h.COUNT`. + 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].HPM15 == 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].HPM15 & CSR[scounteren].HPM15) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM15 == 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].HPM15 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM15 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM15 & CSR[scounteren].HPM15) == 1'b0) && (CSR[mcounteren].HPM15 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM15 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(15)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter16.yaml b/arch/csr/Zihpm/hpmcounter16.yaml new file mode 100644 index 000000000..8e020be28 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter16.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter16: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC10 + description: | + Alias for M-mode CSR `mhpmcounter16`. + + Privilege mode access is controlled with `mcounteren.HPM16`, `scounteren.HPM16`, and `hcounteren.HPM16` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM16`# .2+h! [.rotate]#`scounteren.HPM16`# .2+h! [.rotate]#`hcounteren.HPM16`# + 4+^.>h! `hpmcounter16` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter16.COUNT + description: Alias of `mhpmcounter16.COUNT`. + 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].HPM16 == 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].HPM16 & CSR[scounteren].HPM16) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM16 == 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].HPM16 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM16 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM16 & CSR[scounteren].HPM16) == 1'b0) && (CSR[mcounteren].HPM16 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM16 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(16); diff --git a/arch/csr/Zihpm/hpmcounter16h.yaml b/arch/csr/Zihpm/hpmcounter16h.yaml new file mode 100644 index 000000000..16e66d217 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter16h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter16h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC90 + description: | + Alias for M-mode CSR `mhpmcounter16h`. + + Privilege mode access is controlled with `mcounteren.HPM16`, `scounteren.HPM16`, and `hcounteren.HPM16` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM16`# .2+h! [.rotate]#`scounteren.HPM16`# .2+h! [.rotate]#`hcounteren.HPM16`# + 4+^.>h! `hpmcounter16h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter16h.COUNT + description: Alias of `mhpmcounter16h.COUNT`. + 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].HPM16 == 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].HPM16 & CSR[scounteren].HPM16) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM16 == 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].HPM16 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM16 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM16 & CSR[scounteren].HPM16) == 1'b0) && (CSR[mcounteren].HPM16 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM16 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(16)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter17.yaml b/arch/csr/Zihpm/hpmcounter17.yaml new file mode 100644 index 000000000..0dfdd4387 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter17.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter17: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC11 + description: | + Alias for M-mode CSR `mhpmcounter17`. + + Privilege mode access is controlled with `mcounteren.HPM17`, `scounteren.HPM17`, and `hcounteren.HPM17` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM17`# .2+h! [.rotate]#`scounteren.HPM17`# .2+h! [.rotate]#`hcounteren.HPM17`# + 4+^.>h! `hpmcounter17` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter17.COUNT + description: Alias of `mhpmcounter17.COUNT`. + 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].HPM17 == 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].HPM17 & CSR[scounteren].HPM17) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM17 == 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].HPM17 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM17 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM17 & CSR[scounteren].HPM17) == 1'b0) && (CSR[mcounteren].HPM17 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM17 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(17); diff --git a/arch/csr/Zihpm/hpmcounter17h.yaml b/arch/csr/Zihpm/hpmcounter17h.yaml new file mode 100644 index 000000000..5a2649d52 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter17h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter17h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC91 + description: | + Alias for M-mode CSR `mhpmcounter17h`. + + Privilege mode access is controlled with `mcounteren.HPM17`, `scounteren.HPM17`, and `hcounteren.HPM17` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM17`# .2+h! [.rotate]#`scounteren.HPM17`# .2+h! [.rotate]#`hcounteren.HPM17`# + 4+^.>h! `hpmcounter17h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter17h.COUNT + description: Alias of `mhpmcounter17h.COUNT`. + 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].HPM17 == 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].HPM17 & CSR[scounteren].HPM17) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM17 == 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].HPM17 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM17 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM17 & CSR[scounteren].HPM17) == 1'b0) && (CSR[mcounteren].HPM17 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM17 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(17)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter18.yaml b/arch/csr/Zihpm/hpmcounter18.yaml new file mode 100644 index 000000000..f0e8bebb8 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter18.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter18: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC12 + description: | + Alias for M-mode CSR `mhpmcounter18`. + + Privilege mode access is controlled with `mcounteren.HPM18`, `scounteren.HPM18`, and `hcounteren.HPM18` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM18`# .2+h! [.rotate]#`scounteren.HPM18`# .2+h! [.rotate]#`hcounteren.HPM18`# + 4+^.>h! `hpmcounter18` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter18.COUNT + description: Alias of `mhpmcounter18.COUNT`. + 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].HPM18 == 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].HPM18 & CSR[scounteren].HPM18) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM18 == 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].HPM18 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM18 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM18 & CSR[scounteren].HPM18) == 1'b0) && (CSR[mcounteren].HPM18 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM18 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(18); diff --git a/arch/csr/Zihpm/hpmcounter18h.yaml b/arch/csr/Zihpm/hpmcounter18h.yaml new file mode 100644 index 000000000..49fe2315f --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter18h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter18h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC92 + description: | + Alias for M-mode CSR `mhpmcounter18h`. + + Privilege mode access is controlled with `mcounteren.HPM18`, `scounteren.HPM18`, and `hcounteren.HPM18` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM18`# .2+h! [.rotate]#`scounteren.HPM18`# .2+h! [.rotate]#`hcounteren.HPM18`# + 4+^.>h! `hpmcounter18h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter18h.COUNT + description: Alias of `mhpmcounter18h.COUNT`. + 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].HPM18 == 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].HPM18 & CSR[scounteren].HPM18) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM18 == 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].HPM18 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM18 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM18 & CSR[scounteren].HPM18) == 1'b0) && (CSR[mcounteren].HPM18 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM18 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(18)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter19.yaml b/arch/csr/Zihpm/hpmcounter19.yaml new file mode 100644 index 000000000..777813047 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter19.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter19: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC13 + description: | + Alias for M-mode CSR `mhpmcounter19`. + + Privilege mode access is controlled with `mcounteren.HPM19`, `scounteren.HPM19`, and `hcounteren.HPM19` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM19`# .2+h! [.rotate]#`scounteren.HPM19`# .2+h! [.rotate]#`hcounteren.HPM19`# + 4+^.>h! `hpmcounter19` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter19.COUNT + description: Alias of `mhpmcounter19.COUNT`. + 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].HPM19 == 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].HPM19 & CSR[scounteren].HPM19) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM19 == 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].HPM19 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM19 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM19 & CSR[scounteren].HPM19) == 1'b0) && (CSR[mcounteren].HPM19 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM19 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(19); diff --git a/arch/csr/Zihpm/hpmcounter19h.yaml b/arch/csr/Zihpm/hpmcounter19h.yaml new file mode 100644 index 000000000..452d8a18b --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter19h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter19h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC93 + description: | + Alias for M-mode CSR `mhpmcounter19h`. + + Privilege mode access is controlled with `mcounteren.HPM19`, `scounteren.HPM19`, and `hcounteren.HPM19` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM19`# .2+h! [.rotate]#`scounteren.HPM19`# .2+h! [.rotate]#`hcounteren.HPM19`# + 4+^.>h! `hpmcounter19h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter19h.COUNT + description: Alias of `mhpmcounter19h.COUNT`. + 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].HPM19 == 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].HPM19 & CSR[scounteren].HPM19) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM19 == 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].HPM19 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM19 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM19 & CSR[scounteren].HPM19) == 1'b0) && (CSR[mcounteren].HPM19 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM19 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(19)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter20.yaml b/arch/csr/Zihpm/hpmcounter20.yaml new file mode 100644 index 000000000..7ac865d6b --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter20.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter20: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC14 + description: | + Alias for M-mode CSR `mhpmcounter20`. + + Privilege mode access is controlled with `mcounteren.HPM20`, `scounteren.HPM20`, and `hcounteren.HPM20` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM20`# .2+h! [.rotate]#`scounteren.HPM20`# .2+h! [.rotate]#`hcounteren.HPM20`# + 4+^.>h! `hpmcounter20` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter20.COUNT + description: Alias of `mhpmcounter20.COUNT`. + 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].HPM20 == 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].HPM20 & CSR[scounteren].HPM20) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM20 == 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].HPM20 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM20 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM20 & CSR[scounteren].HPM20) == 1'b0) && (CSR[mcounteren].HPM20 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM20 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(20); diff --git a/arch/csr/Zihpm/hpmcounter20h.yaml b/arch/csr/Zihpm/hpmcounter20h.yaml new file mode 100644 index 000000000..a6da4f917 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter20h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter20h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC94 + description: | + Alias for M-mode CSR `mhpmcounter20h`. + + Privilege mode access is controlled with `mcounteren.HPM20`, `scounteren.HPM20`, and `hcounteren.HPM20` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM20`# .2+h! [.rotate]#`scounteren.HPM20`# .2+h! [.rotate]#`hcounteren.HPM20`# + 4+^.>h! `hpmcounter20h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter20h.COUNT + description: Alias of `mhpmcounter20h.COUNT`. + 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].HPM20 == 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].HPM20 & CSR[scounteren].HPM20) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM20 == 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].HPM20 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM20 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM20 & CSR[scounteren].HPM20) == 1'b0) && (CSR[mcounteren].HPM20 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM20 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(20)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter21.yaml b/arch/csr/Zihpm/hpmcounter21.yaml new file mode 100644 index 000000000..87d589a7c --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter21.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter21: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC15 + description: | + Alias for M-mode CSR `mhpmcounter21`. + + Privilege mode access is controlled with `mcounteren.HPM21`, `scounteren.HPM21`, and `hcounteren.HPM21` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM21`# .2+h! [.rotate]#`scounteren.HPM21`# .2+h! [.rotate]#`hcounteren.HPM21`# + 4+^.>h! `hpmcounter21` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter21.COUNT + description: Alias of `mhpmcounter21.COUNT`. + 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].HPM21 == 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].HPM21 & CSR[scounteren].HPM21) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM21 == 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].HPM21 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM21 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM21 & CSR[scounteren].HPM21) == 1'b0) && (CSR[mcounteren].HPM21 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM21 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(21); diff --git a/arch/csr/Zihpm/hpmcounter21h.yaml b/arch/csr/Zihpm/hpmcounter21h.yaml new file mode 100644 index 000000000..bb5efd3a2 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter21h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter21h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC95 + description: | + Alias for M-mode CSR `mhpmcounter21h`. + + Privilege mode access is controlled with `mcounteren.HPM21`, `scounteren.HPM21`, and `hcounteren.HPM21` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM21`# .2+h! [.rotate]#`scounteren.HPM21`# .2+h! [.rotate]#`hcounteren.HPM21`# + 4+^.>h! `hpmcounter21h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter21h.COUNT + description: Alias of `mhpmcounter21h.COUNT`. + 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].HPM21 == 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].HPM21 & CSR[scounteren].HPM21) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM21 == 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].HPM21 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM21 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM21 & CSR[scounteren].HPM21) == 1'b0) && (CSR[mcounteren].HPM21 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM21 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(21)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter22.yaml b/arch/csr/Zihpm/hpmcounter22.yaml new file mode 100644 index 000000000..a0caf09aa --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter22.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter22: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC16 + description: | + Alias for M-mode CSR `mhpmcounter22`. + + Privilege mode access is controlled with `mcounteren.HPM22`, `scounteren.HPM22`, and `hcounteren.HPM22` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM22`# .2+h! [.rotate]#`scounteren.HPM22`# .2+h! [.rotate]#`hcounteren.HPM22`# + 4+^.>h! `hpmcounter22` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter22.COUNT + description: Alias of `mhpmcounter22.COUNT`. + 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].HPM22 == 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].HPM22 & CSR[scounteren].HPM22) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM22 == 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].HPM22 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM22 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM22 & CSR[scounteren].HPM22) == 1'b0) && (CSR[mcounteren].HPM22 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM22 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(22); diff --git a/arch/csr/Zihpm/hpmcounter22h.yaml b/arch/csr/Zihpm/hpmcounter22h.yaml new file mode 100644 index 000000000..fb6f268b3 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter22h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter22h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC96 + description: | + Alias for M-mode CSR `mhpmcounter22h`. + + Privilege mode access is controlled with `mcounteren.HPM22`, `scounteren.HPM22`, and `hcounteren.HPM22` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM22`# .2+h! [.rotate]#`scounteren.HPM22`# .2+h! [.rotate]#`hcounteren.HPM22`# + 4+^.>h! `hpmcounter22h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter22h.COUNT + description: Alias of `mhpmcounter22h.COUNT`. + 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].HPM22 == 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].HPM22 & CSR[scounteren].HPM22) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM22 == 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].HPM22 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM22 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM22 & CSR[scounteren].HPM22) == 1'b0) && (CSR[mcounteren].HPM22 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM22 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(22)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter23.yaml b/arch/csr/Zihpm/hpmcounter23.yaml new file mode 100644 index 000000000..61b9852f8 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter23.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter23: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC17 + description: | + Alias for M-mode CSR `mhpmcounter23`. + + Privilege mode access is controlled with `mcounteren.HPM23`, `scounteren.HPM23`, and `hcounteren.HPM23` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM23`# .2+h! [.rotate]#`scounteren.HPM23`# .2+h! [.rotate]#`hcounteren.HPM23`# + 4+^.>h! `hpmcounter23` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter23.COUNT + description: Alias of `mhpmcounter23.COUNT`. + 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].HPM23 == 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].HPM23 & CSR[scounteren].HPM23) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM23 == 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].HPM23 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM23 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM23 & CSR[scounteren].HPM23) == 1'b0) && (CSR[mcounteren].HPM23 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM23 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(23); diff --git a/arch/csr/Zihpm/hpmcounter23h.yaml b/arch/csr/Zihpm/hpmcounter23h.yaml new file mode 100644 index 000000000..b73760519 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter23h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter23h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC97 + description: | + Alias for M-mode CSR `mhpmcounter23h`. + + Privilege mode access is controlled with `mcounteren.HPM23`, `scounteren.HPM23`, and `hcounteren.HPM23` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM23`# .2+h! [.rotate]#`scounteren.HPM23`# .2+h! [.rotate]#`hcounteren.HPM23`# + 4+^.>h! `hpmcounter23h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter23h.COUNT + description: Alias of `mhpmcounter23h.COUNT`. + 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].HPM23 == 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].HPM23 & CSR[scounteren].HPM23) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM23 == 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].HPM23 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM23 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM23 & CSR[scounteren].HPM23) == 1'b0) && (CSR[mcounteren].HPM23 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM23 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(23)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter24.yaml b/arch/csr/Zihpm/hpmcounter24.yaml new file mode 100644 index 000000000..ac1fe9c06 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter24.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter24: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC18 + description: | + Alias for M-mode CSR `mhpmcounter24`. + + Privilege mode access is controlled with `mcounteren.HPM24`, `scounteren.HPM24`, and `hcounteren.HPM24` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM24`# .2+h! [.rotate]#`scounteren.HPM24`# .2+h! [.rotate]#`hcounteren.HPM24`# + 4+^.>h! `hpmcounter24` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter24.COUNT + description: Alias of `mhpmcounter24.COUNT`. + 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].HPM24 == 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].HPM24 & CSR[scounteren].HPM24) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM24 == 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].HPM24 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM24 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM24 & CSR[scounteren].HPM24) == 1'b0) && (CSR[mcounteren].HPM24 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM24 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(24); diff --git a/arch/csr/Zihpm/hpmcounter24h.yaml b/arch/csr/Zihpm/hpmcounter24h.yaml new file mode 100644 index 000000000..686702928 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter24h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter24h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC98 + description: | + Alias for M-mode CSR `mhpmcounter24h`. + + Privilege mode access is controlled with `mcounteren.HPM24`, `scounteren.HPM24`, and `hcounteren.HPM24` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM24`# .2+h! [.rotate]#`scounteren.HPM24`# .2+h! [.rotate]#`hcounteren.HPM24`# + 4+^.>h! `hpmcounter24h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter24h.COUNT + description: Alias of `mhpmcounter24h.COUNT`. + 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].HPM24 == 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].HPM24 & CSR[scounteren].HPM24) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM24 == 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].HPM24 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM24 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM24 & CSR[scounteren].HPM24) == 1'b0) && (CSR[mcounteren].HPM24 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM24 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(24)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter25.yaml b/arch/csr/Zihpm/hpmcounter25.yaml new file mode 100644 index 000000000..4b74677a8 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter25.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter25: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC19 + description: | + Alias for M-mode CSR `mhpmcounter25`. + + Privilege mode access is controlled with `mcounteren.HPM25`, `scounteren.HPM25`, and `hcounteren.HPM25` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM25`# .2+h! [.rotate]#`scounteren.HPM25`# .2+h! [.rotate]#`hcounteren.HPM25`# + 4+^.>h! `hpmcounter25` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter25.COUNT + description: Alias of `mhpmcounter25.COUNT`. + 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].HPM25 == 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].HPM25 & CSR[scounteren].HPM25) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM25 == 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].HPM25 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM25 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM25 & CSR[scounteren].HPM25) == 1'b0) && (CSR[mcounteren].HPM25 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM25 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(25); diff --git a/arch/csr/Zihpm/hpmcounter25h.yaml b/arch/csr/Zihpm/hpmcounter25h.yaml new file mode 100644 index 000000000..11bfe5be9 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter25h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter25h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC99 + description: | + Alias for M-mode CSR `mhpmcounter25h`. + + Privilege mode access is controlled with `mcounteren.HPM25`, `scounteren.HPM25`, and `hcounteren.HPM25` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM25`# .2+h! [.rotate]#`scounteren.HPM25`# .2+h! [.rotate]#`hcounteren.HPM25`# + 4+^.>h! `hpmcounter25h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter25h.COUNT + description: Alias of `mhpmcounter25h.COUNT`. + 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].HPM25 == 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].HPM25 & CSR[scounteren].HPM25) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM25 == 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].HPM25 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM25 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM25 & CSR[scounteren].HPM25) == 1'b0) && (CSR[mcounteren].HPM25 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM25 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(25)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter26.yaml b/arch/csr/Zihpm/hpmcounter26.yaml new file mode 100644 index 000000000..bd2de24a4 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter26.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter26: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC1A + description: | + Alias for M-mode CSR `mhpmcounter26`. + + Privilege mode access is controlled with `mcounteren.HPM26`, `scounteren.HPM26`, and `hcounteren.HPM26` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM26`# .2+h! [.rotate]#`scounteren.HPM26`# .2+h! [.rotate]#`hcounteren.HPM26`# + 4+^.>h! `hpmcounter26` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter26.COUNT + description: Alias of `mhpmcounter26.COUNT`. + 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].HPM26 == 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].HPM26 & CSR[scounteren].HPM26) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM26 == 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].HPM26 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM26 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM26 & CSR[scounteren].HPM26) == 1'b0) && (CSR[mcounteren].HPM26 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM26 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(26); diff --git a/arch/csr/Zihpm/hpmcounter26h.yaml b/arch/csr/Zihpm/hpmcounter26h.yaml new file mode 100644 index 000000000..27dfc8de6 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter26h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter26h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC9A + description: | + Alias for M-mode CSR `mhpmcounter26h`. + + Privilege mode access is controlled with `mcounteren.HPM26`, `scounteren.HPM26`, and `hcounteren.HPM26` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM26`# .2+h! [.rotate]#`scounteren.HPM26`# .2+h! [.rotate]#`hcounteren.HPM26`# + 4+^.>h! `hpmcounter26h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter26h.COUNT + description: Alias of `mhpmcounter26h.COUNT`. + 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].HPM26 == 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].HPM26 & CSR[scounteren].HPM26) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM26 == 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].HPM26 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM26 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM26 & CSR[scounteren].HPM26) == 1'b0) && (CSR[mcounteren].HPM26 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM26 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(26)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter27.yaml b/arch/csr/Zihpm/hpmcounter27.yaml new file mode 100644 index 000000000..f20dfe474 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter27.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter27: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC1B + description: | + Alias for M-mode CSR `mhpmcounter27`. + + Privilege mode access is controlled with `mcounteren.HPM27`, `scounteren.HPM27`, and `hcounteren.HPM27` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM27`# .2+h! [.rotate]#`scounteren.HPM27`# .2+h! [.rotate]#`hcounteren.HPM27`# + 4+^.>h! `hpmcounter27` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter27.COUNT + description: Alias of `mhpmcounter27.COUNT`. + 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].HPM27 == 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].HPM27 & CSR[scounteren].HPM27) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM27 == 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].HPM27 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM27 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM27 & CSR[scounteren].HPM27) == 1'b0) && (CSR[mcounteren].HPM27 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM27 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(27); diff --git a/arch/csr/Zihpm/hpmcounter27h.yaml b/arch/csr/Zihpm/hpmcounter27h.yaml new file mode 100644 index 000000000..4c276bcb5 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter27h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter27h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC9B + description: | + Alias for M-mode CSR `mhpmcounter27h`. + + Privilege mode access is controlled with `mcounteren.HPM27`, `scounteren.HPM27`, and `hcounteren.HPM27` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM27`# .2+h! [.rotate]#`scounteren.HPM27`# .2+h! [.rotate]#`hcounteren.HPM27`# + 4+^.>h! `hpmcounter27h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter27h.COUNT + description: Alias of `mhpmcounter27h.COUNT`. + 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].HPM27 == 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].HPM27 & CSR[scounteren].HPM27) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM27 == 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].HPM27 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM27 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM27 & CSR[scounteren].HPM27) == 1'b0) && (CSR[mcounteren].HPM27 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM27 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(27)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter28.yaml b/arch/csr/Zihpm/hpmcounter28.yaml new file mode 100644 index 000000000..8549443a5 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter28.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter28: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC1C + description: | + Alias for M-mode CSR `mhpmcounter28`. + + Privilege mode access is controlled with `mcounteren.HPM28`, `scounteren.HPM28`, and `hcounteren.HPM28` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM28`# .2+h! [.rotate]#`scounteren.HPM28`# .2+h! [.rotate]#`hcounteren.HPM28`# + 4+^.>h! `hpmcounter28` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter28.COUNT + description: Alias of `mhpmcounter28.COUNT`. + 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].HPM28 == 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].HPM28 & CSR[scounteren].HPM28) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM28 == 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].HPM28 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM28 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM28 & CSR[scounteren].HPM28) == 1'b0) && (CSR[mcounteren].HPM28 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM28 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(28); diff --git a/arch/csr/Zihpm/hpmcounter28h.yaml b/arch/csr/Zihpm/hpmcounter28h.yaml new file mode 100644 index 000000000..4f6b6b101 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter28h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter28h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC9C + description: | + Alias for M-mode CSR `mhpmcounter28h`. + + Privilege mode access is controlled with `mcounteren.HPM28`, `scounteren.HPM28`, and `hcounteren.HPM28` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM28`# .2+h! [.rotate]#`scounteren.HPM28`# .2+h! [.rotate]#`hcounteren.HPM28`# + 4+^.>h! `hpmcounter28h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter28h.COUNT + description: Alias of `mhpmcounter28h.COUNT`. + 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].HPM28 == 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].HPM28 & CSR[scounteren].HPM28) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM28 == 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].HPM28 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM28 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM28 & CSR[scounteren].HPM28) == 1'b0) && (CSR[mcounteren].HPM28 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM28 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(28)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter29.yaml b/arch/csr/Zihpm/hpmcounter29.yaml new file mode 100644 index 000000000..08fd1861c --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter29.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter29: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC1D + description: | + Alias for M-mode CSR `mhpmcounter29`. + + Privilege mode access is controlled with `mcounteren.HPM29`, `scounteren.HPM29`, and `hcounteren.HPM29` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM29`# .2+h! [.rotate]#`scounteren.HPM29`# .2+h! [.rotate]#`hcounteren.HPM29`# + 4+^.>h! `hpmcounter29` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter29.COUNT + description: Alias of `mhpmcounter29.COUNT`. + 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].HPM29 == 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].HPM29 & CSR[scounteren].HPM29) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM29 == 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].HPM29 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM29 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM29 & CSR[scounteren].HPM29) == 1'b0) && (CSR[mcounteren].HPM29 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM29 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(29); diff --git a/arch/csr/Zihpm/hpmcounter29h.yaml b/arch/csr/Zihpm/hpmcounter29h.yaml new file mode 100644 index 000000000..d719a89eb --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter29h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter29h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC9D + description: | + Alias for M-mode CSR `mhpmcounter29h`. + + Privilege mode access is controlled with `mcounteren.HPM29`, `scounteren.HPM29`, and `hcounteren.HPM29` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM29`# .2+h! [.rotate]#`scounteren.HPM29`# .2+h! [.rotate]#`hcounteren.HPM29`# + 4+^.>h! `hpmcounter29h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter29h.COUNT + description: Alias of `mhpmcounter29h.COUNT`. + 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].HPM29 == 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].HPM29 & CSR[scounteren].HPM29) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM29 == 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].HPM29 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM29 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM29 & CSR[scounteren].HPM29) == 1'b0) && (CSR[mcounteren].HPM29 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM29 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(29)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter3.yaml b/arch/csr/Zihpm/hpmcounter3.yaml new file mode 100644 index 000000000..67086662a --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter3.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter3: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC03 + description: | + Alias for M-mode CSR `mhpmcounter3`. + + Privilege mode access is controlled with `mcounteren.HPM3`, `scounteren.HPM3`, and `hcounteren.HPM3` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM3`# .2+h! [.rotate]#`scounteren.HPM3`# .2+h! [.rotate]#`hcounteren.HPM3`# + 4+^.>h! `hpmcounter3` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter3.COUNT + description: Alias of `mhpmcounter3.COUNT`. + 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].HPM3 == 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].HPM3 & CSR[scounteren].HPM3) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM3 == 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].HPM3 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM3 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM3 & CSR[scounteren].HPM3) == 1'b0) && (CSR[mcounteren].HPM3 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM3 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(3); diff --git a/arch/csr/Zihpm/hpmcounter30.yaml b/arch/csr/Zihpm/hpmcounter30.yaml new file mode 100644 index 000000000..aea918bd0 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter30.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter30: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC1E + description: | + Alias for M-mode CSR `mhpmcounter30`. + + Privilege mode access is controlled with `mcounteren.HPM30`, `scounteren.HPM30`, and `hcounteren.HPM30` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM30`# .2+h! [.rotate]#`scounteren.HPM30`# .2+h! [.rotate]#`hcounteren.HPM30`# + 4+^.>h! `hpmcounter30` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter30.COUNT + description: Alias of `mhpmcounter30.COUNT`. + 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].HPM30 == 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].HPM30 & CSR[scounteren].HPM30) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM30 == 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].HPM30 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM30 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM30 & CSR[scounteren].HPM30) == 1'b0) && (CSR[mcounteren].HPM30 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM30 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(30); diff --git a/arch/csr/Zihpm/hpmcounter30h.yaml b/arch/csr/Zihpm/hpmcounter30h.yaml new file mode 100644 index 000000000..9ab7f5682 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter30h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter30h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC9E + description: | + Alias for M-mode CSR `mhpmcounter30h`. + + Privilege mode access is controlled with `mcounteren.HPM30`, `scounteren.HPM30`, and `hcounteren.HPM30` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM30`# .2+h! [.rotate]#`scounteren.HPM30`# .2+h! [.rotate]#`hcounteren.HPM30`# + 4+^.>h! `hpmcounter30h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter30h.COUNT + description: Alias of `mhpmcounter30h.COUNT`. + 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].HPM30 == 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].HPM30 & CSR[scounteren].HPM30) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM30 == 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].HPM30 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM30 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM30 & CSR[scounteren].HPM30) == 1'b0) && (CSR[mcounteren].HPM30 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM30 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(30)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter31.yaml b/arch/csr/Zihpm/hpmcounter31.yaml new file mode 100644 index 000000000..9222a39ae --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter31.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter31: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC1F + description: | + Alias for M-mode CSR `mhpmcounter31`. + + Privilege mode access is controlled with `mcounteren.HPM31`, `scounteren.HPM31`, and `hcounteren.HPM31` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM31`# .2+h! [.rotate]#`scounteren.HPM31`# .2+h! [.rotate]#`hcounteren.HPM31`# + 4+^.>h! `hpmcounter31` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter31.COUNT + description: Alias of `mhpmcounter31.COUNT`. + 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].HPM31 == 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].HPM31 & CSR[scounteren].HPM31) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM31 == 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].HPM31 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM31 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM31 & CSR[scounteren].HPM31) == 1'b0) && (CSR[mcounteren].HPM31 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM31 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(31); diff --git a/arch/csr/Zihpm/hpmcounter31h.yaml b/arch/csr/Zihpm/hpmcounter31h.yaml new file mode 100644 index 000000000..2288299a1 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter31h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter31h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC9F + description: | + Alias for M-mode CSR `mhpmcounter31h`. + + Privilege mode access is controlled with `mcounteren.HPM31`, `scounteren.HPM31`, and `hcounteren.HPM31` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM31`# .2+h! [.rotate]#`scounteren.HPM31`# .2+h! [.rotate]#`hcounteren.HPM31`# + 4+^.>h! `hpmcounter31h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter31h.COUNT + description: Alias of `mhpmcounter31h.COUNT`. + 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].HPM31 == 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].HPM31 & CSR[scounteren].HPM31) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM31 == 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].HPM31 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM31 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM31 & CSR[scounteren].HPM31) == 1'b0) && (CSR[mcounteren].HPM31 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM31 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(31)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter3h.yaml b/arch/csr/Zihpm/hpmcounter3h.yaml new file mode 100644 index 000000000..6b3924710 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter3h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter3h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC83 + description: | + Alias for M-mode CSR `mhpmcounter3h`. + + Privilege mode access is controlled with `mcounteren.HPM3`, `scounteren.HPM3`, and `hcounteren.HPM3` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM3`# .2+h! [.rotate]#`scounteren.HPM3`# .2+h! [.rotate]#`hcounteren.HPM3`# + 4+^.>h! `hpmcounter3h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter3h.COUNT + description: Alias of `mhpmcounter3h.COUNT`. + 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].HPM3 == 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].HPM3 & CSR[scounteren].HPM3) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM3 == 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].HPM3 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM3 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM3 & CSR[scounteren].HPM3) == 1'b0) && (CSR[mcounteren].HPM3 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM3 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(3)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter4.yaml b/arch/csr/Zihpm/hpmcounter4.yaml new file mode 100644 index 000000000..e12ce56fe --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter4.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter4: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC04 + description: | + Alias for M-mode CSR `mhpmcounter4`. + + Privilege mode access is controlled with `mcounteren.HPM4`, `scounteren.HPM4`, and `hcounteren.HPM4` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM4`# .2+h! [.rotate]#`scounteren.HPM4`# .2+h! [.rotate]#`hcounteren.HPM4`# + 4+^.>h! `hpmcounter4` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter4.COUNT + description: Alias of `mhpmcounter4.COUNT`. + 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].HPM4 == 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].HPM4 & CSR[scounteren].HPM4) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM4 == 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].HPM4 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM4 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM4 & CSR[scounteren].HPM4) == 1'b0) && (CSR[mcounteren].HPM4 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM4 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(4); diff --git a/arch/csr/Zihpm/hpmcounter4h.yaml b/arch/csr/Zihpm/hpmcounter4h.yaml new file mode 100644 index 000000000..3190c2708 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter4h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter4h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC84 + description: | + Alias for M-mode CSR `mhpmcounter4h`. + + Privilege mode access is controlled with `mcounteren.HPM4`, `scounteren.HPM4`, and `hcounteren.HPM4` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM4`# .2+h! [.rotate]#`scounteren.HPM4`# .2+h! [.rotate]#`hcounteren.HPM4`# + 4+^.>h! `hpmcounter4h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter4h.COUNT + description: Alias of `mhpmcounter4h.COUNT`. + 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].HPM4 == 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].HPM4 & CSR[scounteren].HPM4) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM4 == 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].HPM4 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM4 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM4 & CSR[scounteren].HPM4) == 1'b0) && (CSR[mcounteren].HPM4 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM4 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(4)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter5.yaml b/arch/csr/Zihpm/hpmcounter5.yaml new file mode 100644 index 000000000..f803405df --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter5.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter5: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC05 + description: | + Alias for M-mode CSR `mhpmcounter5`. + + Privilege mode access is controlled with `mcounteren.HPM5`, `scounteren.HPM5`, and `hcounteren.HPM5` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM5`# .2+h! [.rotate]#`scounteren.HPM5`# .2+h! [.rotate]#`hcounteren.HPM5`# + 4+^.>h! `hpmcounter5` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter5.COUNT + description: Alias of `mhpmcounter5.COUNT`. + 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].HPM5 == 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].HPM5 & CSR[scounteren].HPM5) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM5 == 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].HPM5 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM5 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM5 & CSR[scounteren].HPM5) == 1'b0) && (CSR[mcounteren].HPM5 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM5 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(5); diff --git a/arch/csr/Zihpm/hpmcounter5h.yaml b/arch/csr/Zihpm/hpmcounter5h.yaml new file mode 100644 index 000000000..f9699bbdb --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter5h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter5h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC85 + description: | + Alias for M-mode CSR `mhpmcounter5h`. + + Privilege mode access is controlled with `mcounteren.HPM5`, `scounteren.HPM5`, and `hcounteren.HPM5` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM5`# .2+h! [.rotate]#`scounteren.HPM5`# .2+h! [.rotate]#`hcounteren.HPM5`# + 4+^.>h! `hpmcounter5h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter5h.COUNT + description: Alias of `mhpmcounter5h.COUNT`. + 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].HPM5 == 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].HPM5 & CSR[scounteren].HPM5) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM5 == 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].HPM5 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM5 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM5 & CSR[scounteren].HPM5) == 1'b0) && (CSR[mcounteren].HPM5 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM5 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(5)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter6.yaml b/arch/csr/Zihpm/hpmcounter6.yaml new file mode 100644 index 000000000..edc2587a1 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter6.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter6: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC06 + description: | + Alias for M-mode CSR `mhpmcounter6`. + + Privilege mode access is controlled with `mcounteren.HPM6`, `scounteren.HPM6`, and `hcounteren.HPM6` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM6`# .2+h! [.rotate]#`scounteren.HPM6`# .2+h! [.rotate]#`hcounteren.HPM6`# + 4+^.>h! `hpmcounter6` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter6.COUNT + description: Alias of `mhpmcounter6.COUNT`. + 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].HPM6 == 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].HPM6 & CSR[scounteren].HPM6) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM6 == 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].HPM6 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM6 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM6 & CSR[scounteren].HPM6) == 1'b0) && (CSR[mcounteren].HPM6 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM6 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(6); diff --git a/arch/csr/Zihpm/hpmcounter6h.yaml b/arch/csr/Zihpm/hpmcounter6h.yaml new file mode 100644 index 000000000..fd6a51b75 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter6h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter6h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC86 + description: | + Alias for M-mode CSR `mhpmcounter6h`. + + Privilege mode access is controlled with `mcounteren.HPM6`, `scounteren.HPM6`, and `hcounteren.HPM6` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM6`# .2+h! [.rotate]#`scounteren.HPM6`# .2+h! [.rotate]#`hcounteren.HPM6`# + 4+^.>h! `hpmcounter6h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter6h.COUNT + description: Alias of `mhpmcounter6h.COUNT`. + 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].HPM6 == 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].HPM6 & CSR[scounteren].HPM6) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM6 == 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].HPM6 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM6 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM6 & CSR[scounteren].HPM6) == 1'b0) && (CSR[mcounteren].HPM6 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM6 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(6)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter7.yaml b/arch/csr/Zihpm/hpmcounter7.yaml new file mode 100644 index 000000000..e0406de88 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter7.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter7: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC07 + description: | + Alias for M-mode CSR `mhpmcounter7`. + + Privilege mode access is controlled with `mcounteren.HPM7`, `scounteren.HPM7`, and `hcounteren.HPM7` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM7`# .2+h! [.rotate]#`scounteren.HPM7`# .2+h! [.rotate]#`hcounteren.HPM7`# + 4+^.>h! `hpmcounter7` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter7.COUNT + description: Alias of `mhpmcounter7.COUNT`. + 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].HPM7 == 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].HPM7 & CSR[scounteren].HPM7) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM7 == 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].HPM7 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM7 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM7 & CSR[scounteren].HPM7) == 1'b0) && (CSR[mcounteren].HPM7 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM7 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(7); diff --git a/arch/csr/Zihpm/hpmcounter7h.yaml b/arch/csr/Zihpm/hpmcounter7h.yaml new file mode 100644 index 000000000..35da13958 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter7h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter7h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC87 + description: | + Alias for M-mode CSR `mhpmcounter7h`. + + Privilege mode access is controlled with `mcounteren.HPM7`, `scounteren.HPM7`, and `hcounteren.HPM7` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM7`# .2+h! [.rotate]#`scounteren.HPM7`# .2+h! [.rotate]#`hcounteren.HPM7`# + 4+^.>h! `hpmcounter7h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter7h.COUNT + description: Alias of `mhpmcounter7h.COUNT`. + 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].HPM7 == 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].HPM7 & CSR[scounteren].HPM7) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM7 == 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].HPM7 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM7 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM7 & CSR[scounteren].HPM7) == 1'b0) && (CSR[mcounteren].HPM7 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM7 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(7)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter8.yaml b/arch/csr/Zihpm/hpmcounter8.yaml new file mode 100644 index 000000000..b6952b7ef --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter8.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter8: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC08 + description: | + Alias for M-mode CSR `mhpmcounter8`. + + Privilege mode access is controlled with `mcounteren.HPM8`, `scounteren.HPM8`, and `hcounteren.HPM8` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM8`# .2+h! [.rotate]#`scounteren.HPM8`# .2+h! [.rotate]#`hcounteren.HPM8`# + 4+^.>h! `hpmcounter8` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter8.COUNT + description: Alias of `mhpmcounter8.COUNT`. + 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].HPM8 == 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].HPM8 & CSR[scounteren].HPM8) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM8 == 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].HPM8 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM8 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM8 & CSR[scounteren].HPM8) == 1'b0) && (CSR[mcounteren].HPM8 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM8 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(8); diff --git a/arch/csr/Zihpm/hpmcounter8h.yaml b/arch/csr/Zihpm/hpmcounter8h.yaml new file mode 100644 index 000000000..26d0658be --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter8h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter8h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC88 + description: | + Alias for M-mode CSR `mhpmcounter8h`. + + Privilege mode access is controlled with `mcounteren.HPM8`, `scounteren.HPM8`, and `hcounteren.HPM8` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM8`# .2+h! [.rotate]#`scounteren.HPM8`# .2+h! [.rotate]#`hcounteren.HPM8`# + 4+^.>h! `hpmcounter8h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter8h.COUNT + description: Alias of `mhpmcounter8h.COUNT`. + 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].HPM8 == 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].HPM8 & CSR[scounteren].HPM8) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM8 == 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].HPM8 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM8 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM8 & CSR[scounteren].HPM8) == 1'b0) && (CSR[mcounteren].HPM8 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM8 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(8)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounter9.yaml b/arch/csr/Zihpm/hpmcounter9.yaml new file mode 100644 index 000000000..9ca0598a4 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter9.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterN.layout + + + +hpmcounter9: + long_name: Cycle counter for RDCYCLE Instruction + address: 0xC09 + description: | + Alias for M-mode CSR `mhpmcounter9`. + + Privilege mode access is controlled with `mcounteren.HPM9`, `scounteren.HPM9`, and `hcounteren.HPM9` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM9`# .2+h! [.rotate]#`scounteren.HPM9`# .2+h! [.rotate]#`hcounteren.HPM9`# + 4+^.>h! `hpmcounter9` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter9.COUNT + description: Alias of `mhpmcounter9.COUNT`. + 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].HPM9 == 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].HPM9 & CSR[scounteren].HPM9) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM9 == 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].HPM9 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM9 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM9 & CSR[scounteren].HPM9) == 1'b0) && (CSR[mcounteren].HPM9 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM9 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(9); diff --git a/arch/csr/Zihpm/hpmcounter9h.yaml b/arch/csr/Zihpm/hpmcounter9h.yaml new file mode 100644 index 000000000..ae482982b --- /dev/null +++ b/arch/csr/Zihpm/hpmcounter9h.yaml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/hpmcounterNh.layout + + + +hpmcounter9h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0xC89 + description: | + Alias for M-mode CSR `mhpmcounter9h`. + + Privilege mode access is controlled with `mcounteren.HPM9`, `scounteren.HPM9`, and `hcounteren.HPM9` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM9`# .2+h! [.rotate]#`scounteren.HPM9`# .2+h! [.rotate]#`hcounteren.HPM9`# + 4+^.>h! `hpmcounter9h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter9h.COUNT + description: Alias of `mhpmcounter9h.COUNT`. + 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].HPM9 == 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].HPM9 & CSR[scounteren].HPM9) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM9 == 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].HPM9 == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM9 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM9 & CSR[scounteren].HPM9) == 1'b0) && (CSR[mcounteren].HPM9 == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM9 == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(9)[63:32]; diff --git a/arch/csr/Zihpm/hpmcounterN.layout b/arch/csr/Zihpm/hpmcounterN.layout new file mode 100644 index 000000000..949658f65 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounterN.layout @@ -0,0 +1,71 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +<%- raise "'hpm_num' must be defined" if hpm_num.nil? -%> + +hpmcounter<%= hpm_num %>: + long_name: Cycle counter for RDCYCLE Instruction + address: 0x<%= (0xC03 + (hpm_num - 3)).to_s(16).upcase %> + description: | + Alias for M-mode CSR `mhpmcounter<%= hpm_num %>`. + + Privilege mode access is controlled with `mcounteren.HPM<%= hpm_num %>`, `scounteren.HPM<%= hpm_num %>`, and `hcounteren.HPM<%= hpm_num %>` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM<%= hpm_num %>`# .2+h! [.rotate]#`scounteren.HPM<%= hpm_num %>`# .2+h! [.rotate]#`hcounteren.HPM<%= hpm_num %>`# + 4+^.>h! `hpmcounter<%= hpm_num %>` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + alias: mhpmcounter<%= hpm_num %>.COUNT + description: Alias of `mhpmcounter<%= hpm_num %>.COUNT`. + 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].HPM<%= hpm_num %> == 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].HPM<%= hpm_num %> & CSR[scounteren].HPM<%= hpm_num %>) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM<%= hpm_num %> == 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].HPM<%= hpm_num %> == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM<%= hpm_num %> == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM<%= hpm_num %> & CSR[scounteren].HPM<%= hpm_num %>) == 1'b0) && (CSR[mcounteren].HPM<%= hpm_num %> == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM<%= hpm_num %> == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(<%= hpm_num %>); diff --git a/arch/csr/Zihpm/hpmcounterNh.layout b/arch/csr/Zihpm/hpmcounterNh.layout new file mode 100644 index 000000000..485578863 --- /dev/null +++ b/arch/csr/Zihpm/hpmcounterNh.layout @@ -0,0 +1,71 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +<%- raise "'hpm_num' must be defined" if hpm_num.nil? -%> + +hpmcounter<%= hpm_num %>h: + long_name: Cycle counter for RDCYCLE Instruction, high half + address: 0x<%= (0xC83 + (hpm_num - 3)).to_s(16).upcase %> + description: | + Alias for M-mode CSR `mhpmcounter<%= hpm_num %>h`. + + Privilege mode access is controlled with `mcounteren.HPM<%= hpm_num %>`, `scounteren.HPM<%= hpm_num %>`, and `hcounteren.HPM<%= hpm_num %>` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.HPM<%= hpm_num %>`# .2+h! [.rotate]#`scounteren.HPM<%= hpm_num %>`# .2+h! [.rotate]#`hcounteren.HPM<%= hpm_num %>`# + 4+^.>h! `hpmcounter<%= hpm_num %>h` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 64 + definedBy: Sscofpmf + fields: + COUNT: + location: 63-0 + alias: mhpmcounter<%= hpm_num %>h.COUNT + description: Alias of `mhpmcounter<%= hpm_num %>h.COUNT`. + 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].HPM<%= hpm_num %> == 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].HPM<%= hpm_num %> & CSR[scounteren].HPM<%= hpm_num %>) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].HPM<%= hpm_num %> == 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].HPM<%= hpm_num %> == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].HPM<%= hpm_num %> == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].HPM<%= hpm_num %> & CSR[scounteren].HPM<%= hpm_num %>) == 1'b0) && (CSR[mcounteren].HPM<%= hpm_num %> == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].HPM<%= hpm_num %> == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + return read_hpm_counter(<%= hpm_num %>)[63:32]; diff --git a/arch/csr/Zihpm/mhpmcounter10.yaml b/arch/csr/Zihpm/mhpmcounter10.yaml new file mode 100644 index 000000000..563ec1664 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter10.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter10: + long_name: Machine Hardware Performance Counter 10 + address: 0xB0A + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 7 -%> + Performance counter for event selected in `mhpmevent10.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM10` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM10`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent10.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent10.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent10..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent10.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent10.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent10.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent10.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent10.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent10.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 7) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 7) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 7) { + return read_hpm_counter(10); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter10h.yaml b/arch/csr/Zihpm/mhpmcounter10h.yaml new file mode 100644 index 000000000..95f86f1f5 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter10h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter10h: + long_name: Machine Hardware Performance Counter 10, Upper half + address: 0xB8A + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter10. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT10[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 7) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 7) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 7) { + return read_hpm_counter(10)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter11.yaml b/arch/csr/Zihpm/mhpmcounter11.yaml new file mode 100644 index 000000000..40ad6788d --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter11.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter11: + long_name: Machine Hardware Performance Counter 11 + address: 0xB0B + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 8 -%> + Performance counter for event selected in `mhpmevent11.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM11` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM11`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent11.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent11.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent11..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent11.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent11.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent11.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent11.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent11.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent11.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 8) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 8) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 8) { + return read_hpm_counter(11); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter11h.yaml b/arch/csr/Zihpm/mhpmcounter11h.yaml new file mode 100644 index 000000000..e4420e08c --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter11h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter11h: + long_name: Machine Hardware Performance Counter 11, Upper half + address: 0xB8B + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter11. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT11[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 8) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 8) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 8) { + return read_hpm_counter(11)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter12.yaml b/arch/csr/Zihpm/mhpmcounter12.yaml new file mode 100644 index 000000000..09d83529e --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter12.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter12: + long_name: Machine Hardware Performance Counter 12 + address: 0xB0C + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 9 -%> + Performance counter for event selected in `mhpmevent12.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM12` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM12`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent12.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent12.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent12..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent12.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent12.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent12.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent12.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent12.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent12.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 9) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 9) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 9) { + return read_hpm_counter(12); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter12h.yaml b/arch/csr/Zihpm/mhpmcounter12h.yaml new file mode 100644 index 000000000..09f924c6d --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter12h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter12h: + long_name: Machine Hardware Performance Counter 12, Upper half + address: 0xB8C + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter12. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT12[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 9) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 9) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 9) { + return read_hpm_counter(12)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter13.yaml b/arch/csr/Zihpm/mhpmcounter13.yaml new file mode 100644 index 000000000..1e11532da --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter13.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter13: + long_name: Machine Hardware Performance Counter 13 + address: 0xB0D + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 10 -%> + Performance counter for event selected in `mhpmevent13.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM13` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM13`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent13.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent13.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent13..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent13.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent13.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent13.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent13.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent13.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent13.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 10) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 10) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 10) { + return read_hpm_counter(13); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter13h.yaml b/arch/csr/Zihpm/mhpmcounter13h.yaml new file mode 100644 index 000000000..8365002be --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter13h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter13h: + long_name: Machine Hardware Performance Counter 13, Upper half + address: 0xB8D + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter13. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT13[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 10) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 10) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 10) { + return read_hpm_counter(13)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter14.yaml b/arch/csr/Zihpm/mhpmcounter14.yaml new file mode 100644 index 000000000..a0bb95f6f --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter14.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter14: + long_name: Machine Hardware Performance Counter 14 + address: 0xB0E + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 11 -%> + Performance counter for event selected in `mhpmevent14.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM14` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM14`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent14.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent14.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent14..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent14.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent14.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent14.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent14.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent14.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent14.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 11) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 11) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 11) { + return read_hpm_counter(14); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter14h.yaml b/arch/csr/Zihpm/mhpmcounter14h.yaml new file mode 100644 index 000000000..335459232 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter14h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter14h: + long_name: Machine Hardware Performance Counter 14, Upper half + address: 0xB8E + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter14. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT14[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 11) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 11) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 11) { + return read_hpm_counter(14)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter15.yaml b/arch/csr/Zihpm/mhpmcounter15.yaml new file mode 100644 index 000000000..0cc42d9c9 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter15.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter15: + long_name: Machine Hardware Performance Counter 15 + address: 0xB0F + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 12 -%> + Performance counter for event selected in `mhpmevent15.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM15` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM15`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent15.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent15.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent15..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent15.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent15.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent15.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent15.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent15.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent15.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 12) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 12) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 12) { + return read_hpm_counter(15); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter15h.yaml b/arch/csr/Zihpm/mhpmcounter15h.yaml new file mode 100644 index 000000000..cda4b61e1 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter15h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter15h: + long_name: Machine Hardware Performance Counter 15, Upper half + address: 0xB8F + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter15. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT15[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 12) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 12) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 12) { + return read_hpm_counter(15)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter16.yaml b/arch/csr/Zihpm/mhpmcounter16.yaml new file mode 100644 index 000000000..3fcf2cb44 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter16.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter16: + long_name: Machine Hardware Performance Counter 16 + address: 0xB10 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 13 -%> + Performance counter for event selected in `mhpmevent16.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM16` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM16`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent16.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent16.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent16..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent16.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent16.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent16.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent16.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent16.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent16.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 13) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 13) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 13) { + return read_hpm_counter(16); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter16h.yaml b/arch/csr/Zihpm/mhpmcounter16h.yaml new file mode 100644 index 000000000..29c70903f --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter16h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter16h: + long_name: Machine Hardware Performance Counter 16, Upper half + address: 0xB90 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter16. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT16[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 13) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 13) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 13) { + return read_hpm_counter(16)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter17.yaml b/arch/csr/Zihpm/mhpmcounter17.yaml new file mode 100644 index 000000000..0b52a9ebb --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter17.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter17: + long_name: Machine Hardware Performance Counter 17 + address: 0xB11 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 14 -%> + Performance counter for event selected in `mhpmevent17.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM17` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM17`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent17.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent17.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent17..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent17.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent17.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent17.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent17.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent17.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent17.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 14) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 14) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 14) { + return read_hpm_counter(17); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter17h.yaml b/arch/csr/Zihpm/mhpmcounter17h.yaml new file mode 100644 index 000000000..4c9ae8f4e --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter17h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter17h: + long_name: Machine Hardware Performance Counter 17, Upper half + address: 0xB91 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter17. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT17[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 14) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 14) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 14) { + return read_hpm_counter(17)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter18.yaml b/arch/csr/Zihpm/mhpmcounter18.yaml new file mode 100644 index 000000000..66d09f631 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter18.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter18: + long_name: Machine Hardware Performance Counter 18 + address: 0xB12 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 15 -%> + Performance counter for event selected in `mhpmevent18.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM18` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM18`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent18.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent18.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent18..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent18.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent18.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent18.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent18.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent18.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent18.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 15) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 15) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 15) { + return read_hpm_counter(18); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter18h.yaml b/arch/csr/Zihpm/mhpmcounter18h.yaml new file mode 100644 index 000000000..bb7246386 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter18h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter18h: + long_name: Machine Hardware Performance Counter 18, Upper half + address: 0xB92 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter18. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT18[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 15) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 15) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 15) { + return read_hpm_counter(18)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter19.yaml b/arch/csr/Zihpm/mhpmcounter19.yaml new file mode 100644 index 000000000..d735cd9bf --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter19.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter19: + long_name: Machine Hardware Performance Counter 19 + address: 0xB13 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 16 -%> + Performance counter for event selected in `mhpmevent19.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM19` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM19`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent19.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent19.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent19..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent19.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent19.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent19.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent19.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent19.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent19.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 16) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 16) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 16) { + return read_hpm_counter(19); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter19h.yaml b/arch/csr/Zihpm/mhpmcounter19h.yaml new file mode 100644 index 000000000..56b8d76ee --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter19h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter19h: + long_name: Machine Hardware Performance Counter 19, Upper half + address: 0xB93 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter19. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT19[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 16) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 16) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 16) { + return read_hpm_counter(19)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter20.yaml b/arch/csr/Zihpm/mhpmcounter20.yaml new file mode 100644 index 000000000..853923e36 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter20.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter20: + long_name: Machine Hardware Performance Counter 20 + address: 0xB14 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 17 -%> + Performance counter for event selected in `mhpmevent20.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM20` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM20`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent20.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent20.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent20..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent20.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent20.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent20.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent20.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent20.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent20.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 17) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 17) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 17) { + return read_hpm_counter(20); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter20h.yaml b/arch/csr/Zihpm/mhpmcounter20h.yaml new file mode 100644 index 000000000..01fe05419 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter20h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter20h: + long_name: Machine Hardware Performance Counter 20, Upper half + address: 0xB94 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter20. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT20[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 17) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 17) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 17) { + return read_hpm_counter(20)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter21.yaml b/arch/csr/Zihpm/mhpmcounter21.yaml new file mode 100644 index 000000000..34e299c90 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter21.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter21: + long_name: Machine Hardware Performance Counter 21 + address: 0xB15 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 18 -%> + Performance counter for event selected in `mhpmevent21.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM21` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM21`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent21.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent21.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent21..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent21.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent21.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent21.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent21.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent21.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent21.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 18) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 18) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 18) { + return read_hpm_counter(21); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter21h.yaml b/arch/csr/Zihpm/mhpmcounter21h.yaml new file mode 100644 index 000000000..c7a87692c --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter21h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter21h: + long_name: Machine Hardware Performance Counter 21, Upper half + address: 0xB95 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter21. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT21[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 18) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 18) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 18) { + return read_hpm_counter(21)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter22.yaml b/arch/csr/Zihpm/mhpmcounter22.yaml new file mode 100644 index 000000000..ea831f981 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter22.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter22: + long_name: Machine Hardware Performance Counter 22 + address: 0xB16 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 19 -%> + Performance counter for event selected in `mhpmevent22.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM22` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM22`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent22.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent22.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent22..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent22.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent22.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent22.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent22.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent22.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent22.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 19) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 19) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 19) { + return read_hpm_counter(22); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter22h.yaml b/arch/csr/Zihpm/mhpmcounter22h.yaml new file mode 100644 index 000000000..b71525198 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter22h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter22h: + long_name: Machine Hardware Performance Counter 22, Upper half + address: 0xB96 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter22. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT22[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 19) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 19) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 19) { + return read_hpm_counter(22)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter23.yaml b/arch/csr/Zihpm/mhpmcounter23.yaml new file mode 100644 index 000000000..ba5817bf1 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter23.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter23: + long_name: Machine Hardware Performance Counter 23 + address: 0xB17 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 20 -%> + Performance counter for event selected in `mhpmevent23.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM23` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM23`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent23.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent23.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent23..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent23.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent23.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent23.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent23.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent23.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent23.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 20) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 20) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 20) { + return read_hpm_counter(23); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter23h.yaml b/arch/csr/Zihpm/mhpmcounter23h.yaml new file mode 100644 index 000000000..ec86b74a7 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter23h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter23h: + long_name: Machine Hardware Performance Counter 23, Upper half + address: 0xB97 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter23. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT23[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 20) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 20) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 20) { + return read_hpm_counter(23)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter24.yaml b/arch/csr/Zihpm/mhpmcounter24.yaml new file mode 100644 index 000000000..4d73d1889 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter24.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter24: + long_name: Machine Hardware Performance Counter 24 + address: 0xB18 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 21 -%> + Performance counter for event selected in `mhpmevent24.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM24` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM24`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent24.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent24.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent24..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent24.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent24.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent24.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent24.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent24.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent24.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 21) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 21) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 21) { + return read_hpm_counter(24); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter24h.yaml b/arch/csr/Zihpm/mhpmcounter24h.yaml new file mode 100644 index 000000000..9b5f1ad30 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter24h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter24h: + long_name: Machine Hardware Performance Counter 24, Upper half + address: 0xB98 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter24. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT24[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 21) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 21) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 21) { + return read_hpm_counter(24)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter25.yaml b/arch/csr/Zihpm/mhpmcounter25.yaml new file mode 100644 index 000000000..77f75e8ba --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter25.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter25: + long_name: Machine Hardware Performance Counter 25 + address: 0xB19 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 22 -%> + Performance counter for event selected in `mhpmevent25.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM25` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM25`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent25.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent25.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent25..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent25.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent25.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent25.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent25.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent25.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent25.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 22) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 22) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 22) { + return read_hpm_counter(25); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter25h.yaml b/arch/csr/Zihpm/mhpmcounter25h.yaml new file mode 100644 index 000000000..d5dd1ab9b --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter25h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter25h: + long_name: Machine Hardware Performance Counter 25, Upper half + address: 0xB99 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter25. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT25[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 22) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 22) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 22) { + return read_hpm_counter(25)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter26.yaml b/arch/csr/Zihpm/mhpmcounter26.yaml new file mode 100644 index 000000000..88dd15793 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter26.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter26: + long_name: Machine Hardware Performance Counter 26 + address: 0xB1A + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 23 -%> + Performance counter for event selected in `mhpmevent26.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM26` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM26`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent26.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent26.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent26..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent26.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent26.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent26.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent26.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent26.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent26.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 23) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 23) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 23) { + return read_hpm_counter(26); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter26h.yaml b/arch/csr/Zihpm/mhpmcounter26h.yaml new file mode 100644 index 000000000..54a40eba9 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter26h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter26h: + long_name: Machine Hardware Performance Counter 26, Upper half + address: 0xB9A + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter26. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT26[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 23) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 23) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 23) { + return read_hpm_counter(26)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter27.yaml b/arch/csr/Zihpm/mhpmcounter27.yaml new file mode 100644 index 000000000..72333cf55 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter27.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter27: + long_name: Machine Hardware Performance Counter 27 + address: 0xB1B + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 24 -%> + Performance counter for event selected in `mhpmevent27.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM27` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM27`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent27.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent27.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent27..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent27.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent27.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent27.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent27.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent27.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent27.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 24) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 24) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 24) { + return read_hpm_counter(27); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter27h.yaml b/arch/csr/Zihpm/mhpmcounter27h.yaml new file mode 100644 index 000000000..62820278f --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter27h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter27h: + long_name: Machine Hardware Performance Counter 27, Upper half + address: 0xB9B + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter27. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT27[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 24) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 24) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 24) { + return read_hpm_counter(27)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter28.yaml b/arch/csr/Zihpm/mhpmcounter28.yaml new file mode 100644 index 000000000..412c224bf --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter28.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter28: + long_name: Machine Hardware Performance Counter 28 + address: 0xB1C + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 25 -%> + Performance counter for event selected in `mhpmevent28.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM28` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM28`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent28.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent28.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent28..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent28.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent28.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent28.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent28.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent28.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent28.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 25) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 25) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 25) { + return read_hpm_counter(28); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter28h.yaml b/arch/csr/Zihpm/mhpmcounter28h.yaml new file mode 100644 index 000000000..78d50048a --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter28h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter28h: + long_name: Machine Hardware Performance Counter 28, Upper half + address: 0xB9C + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter28. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT28[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 25) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 25) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 25) { + return read_hpm_counter(28)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter29.yaml b/arch/csr/Zihpm/mhpmcounter29.yaml new file mode 100644 index 000000000..f0a6065a6 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter29.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter29: + long_name: Machine Hardware Performance Counter 29 + address: 0xB1D + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 26 -%> + Performance counter for event selected in `mhpmevent29.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM29` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM29`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent29.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent29.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent29..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent29.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent29.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent29.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent29.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent29.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent29.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 26) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 26) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 26) { + return read_hpm_counter(29); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter29h.yaml b/arch/csr/Zihpm/mhpmcounter29h.yaml new file mode 100644 index 000000000..3ad8baf19 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter29h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter29h: + long_name: Machine Hardware Performance Counter 29, Upper half + address: 0xB9D + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter29. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT29[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 26) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 26) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 26) { + return read_hpm_counter(29)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter3.yaml b/arch/csr/Zihpm/mhpmcounter3.yaml new file mode 100644 index 000000000..dc5114ad1 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter3.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter3: + long_name: Machine Hardware Performance Counter 3 + address: 0xB03 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 0 -%> + Performance counter for event selected in `mhpmevent3.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM3` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM3`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent3.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent3.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent3..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent3.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent3.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent3.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent3.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent3.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent3.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 0) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 0) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 0) { + return read_hpm_counter(3); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter30.yaml b/arch/csr/Zihpm/mhpmcounter30.yaml new file mode 100644 index 000000000..632156bca --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter30.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter30: + long_name: Machine Hardware Performance Counter 30 + address: 0xB1E + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 27 -%> + Performance counter for event selected in `mhpmevent30.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM30` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM30`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent30.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent30.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent30..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent30.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent30.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent30.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent30.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent30.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent30.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 27) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 27) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 27) { + return read_hpm_counter(30); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter30h.yaml b/arch/csr/Zihpm/mhpmcounter30h.yaml new file mode 100644 index 000000000..426fcceb1 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter30h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter30h: + long_name: Machine Hardware Performance Counter 30, Upper half + address: 0xB9E + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter30. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT30[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 27) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 27) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 27) { + return read_hpm_counter(30)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter31.yaml b/arch/csr/Zihpm/mhpmcounter31.yaml new file mode 100644 index 000000000..fe9ba262a --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter31.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter31: + long_name: Machine Hardware Performance Counter 31 + address: 0xB1F + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 28 -%> + Performance counter for event selected in `mhpmevent31.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM31` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM31`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent31.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent31.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent31..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent31.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent31.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent31.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent31.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent31.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent31.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 28) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 28) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 28) { + return read_hpm_counter(31); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter31h.yaml b/arch/csr/Zihpm/mhpmcounter31h.yaml new file mode 100644 index 000000000..ad0c47bcc --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter31h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter31h: + long_name: Machine Hardware Performance Counter 31, Upper half + address: 0xB9F + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter31. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT31[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 28) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 28) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 28) { + return read_hpm_counter(31)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter3h.yaml b/arch/csr/Zihpm/mhpmcounter3h.yaml new file mode 100644 index 000000000..752b51eab --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter3h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter3h: + long_name: Machine Hardware Performance Counter 3, Upper half + address: 0xB83 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter3. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT3[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 0) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 0) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 0) { + return read_hpm_counter(3)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter4.yaml b/arch/csr/Zihpm/mhpmcounter4.yaml new file mode 100644 index 000000000..aec5021ac --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter4.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter4: + long_name: Machine Hardware Performance Counter 4 + address: 0xB04 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 1 -%> + Performance counter for event selected in `mhpmevent4.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM4` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM4`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent4.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent4.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent4..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent4.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent4.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent4.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent4.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent4.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent4.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 1) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 1) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 1) { + return read_hpm_counter(4); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter4h.yaml b/arch/csr/Zihpm/mhpmcounter4h.yaml new file mode 100644 index 000000000..ee9c8716b --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter4h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter4h: + long_name: Machine Hardware Performance Counter 4, Upper half + address: 0xB84 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter4. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT4[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 1) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 1) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 1) { + return read_hpm_counter(4)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter5.yaml b/arch/csr/Zihpm/mhpmcounter5.yaml new file mode 100644 index 000000000..2d4b4d174 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter5.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter5: + long_name: Machine Hardware Performance Counter 5 + address: 0xB05 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 2 -%> + Performance counter for event selected in `mhpmevent5.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM5` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM5`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent5.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent5.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent5..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent5.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent5.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent5.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent5.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent5.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent5.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 2) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 2) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 2) { + return read_hpm_counter(5); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter5h.yaml b/arch/csr/Zihpm/mhpmcounter5h.yaml new file mode 100644 index 000000000..cecd8952c --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter5h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter5h: + long_name: Machine Hardware Performance Counter 5, Upper half + address: 0xB85 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter5. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT5[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 2) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 2) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 2) { + return read_hpm_counter(5)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter6.yaml b/arch/csr/Zihpm/mhpmcounter6.yaml new file mode 100644 index 000000000..042206c72 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter6.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter6: + long_name: Machine Hardware Performance Counter 6 + address: 0xB06 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 3 -%> + Performance counter for event selected in `mhpmevent6.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM6` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM6`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent6.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent6.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent6..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent6.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent6.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent6.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent6.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent6.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent6.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 3) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 3) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 3) { + return read_hpm_counter(6); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter6h.yaml b/arch/csr/Zihpm/mhpmcounter6h.yaml new file mode 100644 index 000000000..eada04cc6 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter6h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter6h: + long_name: Machine Hardware Performance Counter 6, Upper half + address: 0xB86 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter6. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT6[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 3) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 3) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 3) { + return read_hpm_counter(6)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter7.yaml b/arch/csr/Zihpm/mhpmcounter7.yaml new file mode 100644 index 000000000..452273b4b --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter7.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter7: + long_name: Machine Hardware Performance Counter 7 + address: 0xB07 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 4 -%> + Performance counter for event selected in `mhpmevent7.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM7` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM7`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent7.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent7.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent7..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent7.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent7.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent7.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent7.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent7.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent7.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 4) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 4) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 4) { + return read_hpm_counter(7); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter7h.yaml b/arch/csr/Zihpm/mhpmcounter7h.yaml new file mode 100644 index 000000000..5f0ab29d5 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter7h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter7h: + long_name: Machine Hardware Performance Counter 7, Upper half + address: 0xB87 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter7. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT7[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 4) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 4) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 4) { + return read_hpm_counter(7)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter8.yaml b/arch/csr/Zihpm/mhpmcounter8.yaml new file mode 100644 index 000000000..0489a60bf --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter8.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter8: + long_name: Machine Hardware Performance Counter 8 + address: 0xB08 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 5 -%> + Performance counter for event selected in `mhpmevent8.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM8` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM8`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent8.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent8.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent8..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent8.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent8.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent8.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent8.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent8.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent8.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 5) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 5) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 5) { + return read_hpm_counter(8); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter8h.yaml b/arch/csr/Zihpm/mhpmcounter8h.yaml new file mode 100644 index 000000000..170aa9c3c --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter8h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter8h: + long_name: Machine Hardware Performance Counter 8, Upper half + address: 0xB88 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter8. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT8[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 5) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 5) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 5) { + return read_hpm_counter(8)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounter9.yaml b/arch/csr/Zihpm/mhpmcounter9.yaml new file mode 100644 index 000000000..e2283e469 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter9.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterN.layout + + + +mhpmcounter9: + long_name: Machine Hardware Performance Counter 9 + address: 0xB09 + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%- if NUM_HPM_COUNTERS > 6 -%> + Performance counter for event selected in `mhpmevent9.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM9` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM9`<%- end -%> is set + <%- if ext?(:Sscofpmf) -%> + * `mhpmevent9.MINH` is set and the current privilege level is M + <%- if ext?(:S) -%> + * `mhpmevent9.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent9..SINH`<%- end -%> is set and the current privilege level is (H)S + <%- end -%> + <%- if ext?(:U) -%> + * `mhpmevent9.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent9.SINH`<%- end -%> is set and the current privilege level is U + <%- end -%> + <%- if ext?(:H) -%> + * `mhpmevent9.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent9.SINH`<%- end -%> is set and the current privilege level is VS + * `mhpmevent9.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent9.SINH`<%- end -%> is set and the current privilege level is VU + <%- end -%> + <%- end -%> + <%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > 6) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 6) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 6) { + return read_hpm_counter(9); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounter9h.yaml b/arch/csr/Zihpm/mhpmcounter9h.yaml new file mode 100644 index 000000000..624393fc3 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounter9h.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmcounterNh.layout + + + +mhpmcounter9h: + long_name: Machine Hardware Performance Counter 9, Upper half + address: 0xB89 + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter9. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT9[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > 6) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > 6) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= 6) { + return read_hpm_counter(9)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmcounterN.layout b/arch/csr/Zihpm/mhpmcounterN.layout new file mode 100644 index 000000000..ca792d0ad --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounterN.layout @@ -0,0 +1,46 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +<%- raise("'hpm_num' must be defined") if hpm_num.nil? -%> + +<%= "mhpmcounter#{hpm_num}" %>: + long_name: Machine Hardware Performance Counter <%= hpm_num %> + address: <%= "0x" + (0xB00 + hpm_num).to_s(16).upcase %> + priv_mode: M + length: 64 + description: Programmable hardware performance counter. + definedBy: Zihpm + fields: + COUNT: + location: 63-0 + description: | + <%%- if NUM_HPM_COUNTERS > <%= hpm_num - 3 %> -%> + Performance counter for event selected in `mhpmevent<%= hpm_num %>.EVENT`. + + Increments every time event occurs unless: + + * `mcountinhibit.HPM<%= hpm_num %>` <%%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM<%= hpm_num %>`<%%- end -%> is set + <%%- if ext?(:Sscofpmf) -%> + * `mhpmevent<%= hpm_num %>.MINH` is set and the current privilege level is M + <%%- if ext?(:S) -%> + * `mhpmevent<%= hpm_num %>.SINH` <%%- if ext?(:Ssccfg) -%>or its alias `hpmevent<%= hpm_num %>..SINH`<%%- end -%> is set and the current privilege level is (H)S + <%%- end -%> + <%%- if ext?(:U) -%> + * `mhpmevent<%= hpm_num %>.UINH` <%%- if ext?(:Ssccfg) -%>or its alias `hpmevent<%= hpm_num %>.SINH`<%%- end -%> is set and the current privilege level is U + <%%- end -%> + <%%- if ext?(:H) -%> + * `mhpmevent<%= hpm_num %>.VSINH` <%%- if ext?(:Ssccfg) -%>or its alias `hpmevent<%= hpm_num %>.SINH`<%%- end -%> is set and the current privilege level is VS + * `mhpmevent<%= hpm_num %>.VUINH` <%%- if ext?(:Ssccfg) -%>or its alias `hpmevent<%= hpm_num %>.SINH`<%%- end -%> is set and the current privilege level is VU + <%%- end -%> + <%%- end -%> + <%%- else -%> + Unimplemented performance counter. Must be read-only 0 (access does not cause trap). + <%%- end -%> + + type(): 'return (NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= <%= hpm_num - 3 %>) { + return read_hpm_counter(<%= hpm_num %>); + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmcounterNh.layout b/arch/csr/Zihpm/mhpmcounterNh.layout new file mode 100644 index 000000000..62d6ff111 --- /dev/null +++ b/arch/csr/Zihpm/mhpmcounterNh.layout @@ -0,0 +1,27 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +<%- raise "'hpm_num' must be defined" if hpm_num.nil? -%> + +<%= "mhpmcounter#{hpm_num}h" %>: + long_name: Machine Hardware Performance Counter <%= hpm_num %>, Upper half + address: <%= "0x" + (0xB80 + hpm_num).to_s(16).upcase %> + priv_mode: M + length: 32 + base: 32 + description: | + Upper half of mhpmcounter<%= hpm_num %>. + definedBy: Zihpm + fields: + COUNT: + location: 32-0 + alias: mhpmcounter.COUNT<%= hpm_num %>[63:32] + description: | + Upper bits of counter. + type(): 'return (NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) ? CsrFieldType::RWH : CsrFieldType::RO;' + reset_value(): 'return (NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) ? UNDEFINED_LEGAL : 0;' + sw_read(): | + if (NUM_HPM_COUNTERS <= <%= hpm_num - 3 %>) { + return read_hpm_counter(<%= hpm_num %>)[63:32]; + } else { + return 0; + } \ No newline at end of file diff --git a/arch/csr/Zihpm/mhpmevent10.yaml b/arch/csr/Zihpm/mhpmevent10.yaml new file mode 100644 index 000000000..6959ca692 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent10.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent10: + long_name: Machine Hardware Performance Counter 10 Control + address: 0x32A + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter10 overflows. + type(): | + if (NUM_HPM_COUNTERS > 7) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 7) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter10 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 7) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 7) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter10 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 7) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 7) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter10 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 7) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 7) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter10 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 7) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 7) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter10 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 7) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 7) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter10`. + type(): | + if (NUM_HPM_COUNTERS > 7) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 7) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent10h.yaml b/arch/csr/Zihpm/mhpmevent10h.yaml new file mode 100644 index 000000000..320e0d3f4 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent10h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent10h: + long_name: Machine Hardware Performance Counter 10 Control, High half + address: 0x72A + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent10`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent10.OF + description: | + Alias of mhpmevent10.OF. + type(): | + if (NUM_HPM_COUNTERS > 7) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 7) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent10.MINH + description: | + Alias of mhpmevent10.MINH. + type(): | + if (NUM_HPM_COUNTERS > 7) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 7) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent10.SINH + description: | + Alias of mhpmevent10.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 7) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 7) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent10.UINH + description: | + Alias of mhpmevent10.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 7) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 7) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent10.VSINH + description: | + Alias of mhpmevent10.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 7) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 7) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent10.VUINH + description: | + Alias of mhpmevent10.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 7) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 7) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter10`. + alias: mhpmevent10.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 7) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 7) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent11.yaml b/arch/csr/Zihpm/mhpmevent11.yaml new file mode 100644 index 000000000..52234210c --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent11.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent11: + long_name: Machine Hardware Performance Counter 11 Control + address: 0x32B + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter11 overflows. + type(): | + if (NUM_HPM_COUNTERS > 8) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 8) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter11 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 8) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 8) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter11 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 8) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 8) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter11 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 8) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 8) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter11 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 8) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 8) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter11 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 8) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 8) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter11`. + type(): | + if (NUM_HPM_COUNTERS > 8) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 8) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent11h.yaml b/arch/csr/Zihpm/mhpmevent11h.yaml new file mode 100644 index 000000000..beedc325e --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent11h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent11h: + long_name: Machine Hardware Performance Counter 11 Control, High half + address: 0x72B + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent11`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent11.OF + description: | + Alias of mhpmevent11.OF. + type(): | + if (NUM_HPM_COUNTERS > 8) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 8) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent11.MINH + description: | + Alias of mhpmevent11.MINH. + type(): | + if (NUM_HPM_COUNTERS > 8) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 8) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent11.SINH + description: | + Alias of mhpmevent11.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 8) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 8) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent11.UINH + description: | + Alias of mhpmevent11.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 8) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 8) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent11.VSINH + description: | + Alias of mhpmevent11.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 8) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 8) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent11.VUINH + description: | + Alias of mhpmevent11.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 8) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 8) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter11`. + alias: mhpmevent11.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 8) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 8) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent12.yaml b/arch/csr/Zihpm/mhpmevent12.yaml new file mode 100644 index 000000000..3fee0eeaf --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent12.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent12: + long_name: Machine Hardware Performance Counter 12 Control + address: 0x32C + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter12 overflows. + type(): | + if (NUM_HPM_COUNTERS > 9) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 9) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter12 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 9) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 9) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter12 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 9) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 9) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter12 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 9) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 9) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter12 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 9) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 9) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter12 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 9) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 9) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter12`. + type(): | + if (NUM_HPM_COUNTERS > 9) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 9) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent12h.yaml b/arch/csr/Zihpm/mhpmevent12h.yaml new file mode 100644 index 000000000..fd4ba8ab8 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent12h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent12h: + long_name: Machine Hardware Performance Counter 12 Control, High half + address: 0x72C + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent12`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent12.OF + description: | + Alias of mhpmevent12.OF. + type(): | + if (NUM_HPM_COUNTERS > 9) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 9) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent12.MINH + description: | + Alias of mhpmevent12.MINH. + type(): | + if (NUM_HPM_COUNTERS > 9) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 9) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent12.SINH + description: | + Alias of mhpmevent12.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 9) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 9) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent12.UINH + description: | + Alias of mhpmevent12.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 9) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 9) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent12.VSINH + description: | + Alias of mhpmevent12.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 9) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 9) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent12.VUINH + description: | + Alias of mhpmevent12.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 9) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 9) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter12`. + alias: mhpmevent12.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 9) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 9) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent13.yaml b/arch/csr/Zihpm/mhpmevent13.yaml new file mode 100644 index 000000000..6e3e400db --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent13.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent13: + long_name: Machine Hardware Performance Counter 13 Control + address: 0x32D + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter13 overflows. + type(): | + if (NUM_HPM_COUNTERS > 10) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 10) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter13 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 10) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 10) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter13 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 10) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 10) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter13 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 10) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 10) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter13 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 10) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 10) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter13 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 10) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 10) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter13`. + type(): | + if (NUM_HPM_COUNTERS > 10) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 10) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent13h.yaml b/arch/csr/Zihpm/mhpmevent13h.yaml new file mode 100644 index 000000000..25dd23680 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent13h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent13h: + long_name: Machine Hardware Performance Counter 13 Control, High half + address: 0x72D + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent13`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent13.OF + description: | + Alias of mhpmevent13.OF. + type(): | + if (NUM_HPM_COUNTERS > 10) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 10) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent13.MINH + description: | + Alias of mhpmevent13.MINH. + type(): | + if (NUM_HPM_COUNTERS > 10) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 10) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent13.SINH + description: | + Alias of mhpmevent13.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 10) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 10) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent13.UINH + description: | + Alias of mhpmevent13.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 10) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 10) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent13.VSINH + description: | + Alias of mhpmevent13.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 10) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 10) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent13.VUINH + description: | + Alias of mhpmevent13.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 10) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 10) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter13`. + alias: mhpmevent13.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 10) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 10) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent14.yaml b/arch/csr/Zihpm/mhpmevent14.yaml new file mode 100644 index 000000000..add06fbd5 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent14.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent14: + long_name: Machine Hardware Performance Counter 14 Control + address: 0x32E + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter14 overflows. + type(): | + if (NUM_HPM_COUNTERS > 11) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 11) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter14 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 11) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 11) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter14 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 11) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 11) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter14 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 11) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 11) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter14 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 11) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 11) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter14 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 11) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 11) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter14`. + type(): | + if (NUM_HPM_COUNTERS > 11) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 11) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent14h.yaml b/arch/csr/Zihpm/mhpmevent14h.yaml new file mode 100644 index 000000000..5db000446 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent14h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent14h: + long_name: Machine Hardware Performance Counter 14 Control, High half + address: 0x72E + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent14`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent14.OF + description: | + Alias of mhpmevent14.OF. + type(): | + if (NUM_HPM_COUNTERS > 11) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 11) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent14.MINH + description: | + Alias of mhpmevent14.MINH. + type(): | + if (NUM_HPM_COUNTERS > 11) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 11) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent14.SINH + description: | + Alias of mhpmevent14.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 11) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 11) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent14.UINH + description: | + Alias of mhpmevent14.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 11) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 11) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent14.VSINH + description: | + Alias of mhpmevent14.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 11) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 11) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent14.VUINH + description: | + Alias of mhpmevent14.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 11) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 11) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter14`. + alias: mhpmevent14.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 11) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 11) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent15.yaml b/arch/csr/Zihpm/mhpmevent15.yaml new file mode 100644 index 000000000..f3b154037 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent15.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent15: + long_name: Machine Hardware Performance Counter 15 Control + address: 0x32F + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter15 overflows. + type(): | + if (NUM_HPM_COUNTERS > 12) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 12) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter15 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 12) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 12) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter15 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 12) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 12) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter15 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 12) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 12) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter15 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 12) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 12) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter15 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 12) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 12) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter15`. + type(): | + if (NUM_HPM_COUNTERS > 12) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 12) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent15h.yaml b/arch/csr/Zihpm/mhpmevent15h.yaml new file mode 100644 index 000000000..58db233a3 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent15h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent15h: + long_name: Machine Hardware Performance Counter 15 Control, High half + address: 0x72F + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent15`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent15.OF + description: | + Alias of mhpmevent15.OF. + type(): | + if (NUM_HPM_COUNTERS > 12) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 12) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent15.MINH + description: | + Alias of mhpmevent15.MINH. + type(): | + if (NUM_HPM_COUNTERS > 12) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 12) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent15.SINH + description: | + Alias of mhpmevent15.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 12) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 12) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent15.UINH + description: | + Alias of mhpmevent15.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 12) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 12) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent15.VSINH + description: | + Alias of mhpmevent15.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 12) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 12) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent15.VUINH + description: | + Alias of mhpmevent15.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 12) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 12) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter15`. + alias: mhpmevent15.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 12) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 12) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent16.yaml b/arch/csr/Zihpm/mhpmevent16.yaml new file mode 100644 index 000000000..8e8376180 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent16.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent16: + long_name: Machine Hardware Performance Counter 16 Control + address: 0x330 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter16 overflows. + type(): | + if (NUM_HPM_COUNTERS > 13) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 13) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter16 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 13) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 13) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter16 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 13) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 13) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter16 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 13) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 13) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter16 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 13) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 13) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter16 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 13) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 13) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter16`. + type(): | + if (NUM_HPM_COUNTERS > 13) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 13) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent16h.yaml b/arch/csr/Zihpm/mhpmevent16h.yaml new file mode 100644 index 000000000..b52cc0934 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent16h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent16h: + long_name: Machine Hardware Performance Counter 16 Control, High half + address: 0x730 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent16`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent16.OF + description: | + Alias of mhpmevent16.OF. + type(): | + if (NUM_HPM_COUNTERS > 13) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 13) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent16.MINH + description: | + Alias of mhpmevent16.MINH. + type(): | + if (NUM_HPM_COUNTERS > 13) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 13) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent16.SINH + description: | + Alias of mhpmevent16.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 13) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 13) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent16.UINH + description: | + Alias of mhpmevent16.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 13) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 13) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent16.VSINH + description: | + Alias of mhpmevent16.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 13) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 13) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent16.VUINH + description: | + Alias of mhpmevent16.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 13) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 13) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter16`. + alias: mhpmevent16.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 13) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 13) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent17.yaml b/arch/csr/Zihpm/mhpmevent17.yaml new file mode 100644 index 000000000..299dfc1e3 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent17.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent17: + long_name: Machine Hardware Performance Counter 17 Control + address: 0x331 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter17 overflows. + type(): | + if (NUM_HPM_COUNTERS > 14) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 14) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter17 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 14) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 14) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter17 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 14) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 14) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter17 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 14) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 14) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter17 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 14) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 14) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter17 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 14) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 14) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter17`. + type(): | + if (NUM_HPM_COUNTERS > 14) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 14) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent17h.yaml b/arch/csr/Zihpm/mhpmevent17h.yaml new file mode 100644 index 000000000..4ff392bdb --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent17h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent17h: + long_name: Machine Hardware Performance Counter 17 Control, High half + address: 0x731 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent17`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent17.OF + description: | + Alias of mhpmevent17.OF. + type(): | + if (NUM_HPM_COUNTERS > 14) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 14) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent17.MINH + description: | + Alias of mhpmevent17.MINH. + type(): | + if (NUM_HPM_COUNTERS > 14) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 14) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent17.SINH + description: | + Alias of mhpmevent17.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 14) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 14) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent17.UINH + description: | + Alias of mhpmevent17.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 14) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 14) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent17.VSINH + description: | + Alias of mhpmevent17.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 14) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 14) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent17.VUINH + description: | + Alias of mhpmevent17.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 14) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 14) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter17`. + alias: mhpmevent17.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 14) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 14) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent18.yaml b/arch/csr/Zihpm/mhpmevent18.yaml new file mode 100644 index 000000000..dbc4b8d4a --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent18.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent18: + long_name: Machine Hardware Performance Counter 18 Control + address: 0x332 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter18 overflows. + type(): | + if (NUM_HPM_COUNTERS > 15) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 15) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter18 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 15) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 15) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter18 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 15) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 15) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter18 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 15) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 15) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter18 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 15) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 15) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter18 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 15) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 15) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter18`. + type(): | + if (NUM_HPM_COUNTERS > 15) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 15) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent18h.yaml b/arch/csr/Zihpm/mhpmevent18h.yaml new file mode 100644 index 000000000..5e9ff5af1 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent18h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent18h: + long_name: Machine Hardware Performance Counter 18 Control, High half + address: 0x732 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent18`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent18.OF + description: | + Alias of mhpmevent18.OF. + type(): | + if (NUM_HPM_COUNTERS > 15) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 15) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent18.MINH + description: | + Alias of mhpmevent18.MINH. + type(): | + if (NUM_HPM_COUNTERS > 15) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 15) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent18.SINH + description: | + Alias of mhpmevent18.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 15) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 15) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent18.UINH + description: | + Alias of mhpmevent18.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 15) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 15) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent18.VSINH + description: | + Alias of mhpmevent18.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 15) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 15) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent18.VUINH + description: | + Alias of mhpmevent18.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 15) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 15) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter18`. + alias: mhpmevent18.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 15) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 15) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent19.yaml b/arch/csr/Zihpm/mhpmevent19.yaml new file mode 100644 index 000000000..628e58caa --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent19.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent19: + long_name: Machine Hardware Performance Counter 19 Control + address: 0x333 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter19 overflows. + type(): | + if (NUM_HPM_COUNTERS > 16) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 16) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter19 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 16) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 16) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter19 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 16) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 16) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter19 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 16) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 16) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter19 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 16) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 16) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter19 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 16) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 16) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter19`. + type(): | + if (NUM_HPM_COUNTERS > 16) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 16) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent19h.yaml b/arch/csr/Zihpm/mhpmevent19h.yaml new file mode 100644 index 000000000..cbfb14197 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent19h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent19h: + long_name: Machine Hardware Performance Counter 19 Control, High half + address: 0x733 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent19`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent19.OF + description: | + Alias of mhpmevent19.OF. + type(): | + if (NUM_HPM_COUNTERS > 16) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 16) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent19.MINH + description: | + Alias of mhpmevent19.MINH. + type(): | + if (NUM_HPM_COUNTERS > 16) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 16) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent19.SINH + description: | + Alias of mhpmevent19.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 16) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 16) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent19.UINH + description: | + Alias of mhpmevent19.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 16) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 16) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent19.VSINH + description: | + Alias of mhpmevent19.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 16) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 16) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent19.VUINH + description: | + Alias of mhpmevent19.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 16) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 16) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter19`. + alias: mhpmevent19.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 16) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 16) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent20.yaml b/arch/csr/Zihpm/mhpmevent20.yaml new file mode 100644 index 000000000..262ce599c --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent20.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent20: + long_name: Machine Hardware Performance Counter 20 Control + address: 0x334 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter20 overflows. + type(): | + if (NUM_HPM_COUNTERS > 17) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 17) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter20 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 17) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 17) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter20 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 17) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 17) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter20 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 17) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 17) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter20 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 17) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 17) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter20 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 17) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 17) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter20`. + type(): | + if (NUM_HPM_COUNTERS > 17) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 17) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent20h.yaml b/arch/csr/Zihpm/mhpmevent20h.yaml new file mode 100644 index 000000000..865e8ac2d --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent20h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent20h: + long_name: Machine Hardware Performance Counter 20 Control, High half + address: 0x734 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent20`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent20.OF + description: | + Alias of mhpmevent20.OF. + type(): | + if (NUM_HPM_COUNTERS > 17) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 17) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent20.MINH + description: | + Alias of mhpmevent20.MINH. + type(): | + if (NUM_HPM_COUNTERS > 17) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 17) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent20.SINH + description: | + Alias of mhpmevent20.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 17) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 17) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent20.UINH + description: | + Alias of mhpmevent20.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 17) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 17) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent20.VSINH + description: | + Alias of mhpmevent20.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 17) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 17) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent20.VUINH + description: | + Alias of mhpmevent20.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 17) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 17) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter20`. + alias: mhpmevent20.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 17) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 17) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent21.yaml b/arch/csr/Zihpm/mhpmevent21.yaml new file mode 100644 index 000000000..cf46106f3 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent21.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent21: + long_name: Machine Hardware Performance Counter 21 Control + address: 0x335 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter21 overflows. + type(): | + if (NUM_HPM_COUNTERS > 18) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 18) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter21 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 18) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 18) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter21 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 18) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 18) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter21 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 18) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 18) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter21 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 18) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 18) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter21 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 18) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 18) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter21`. + type(): | + if (NUM_HPM_COUNTERS > 18) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 18) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent21h.yaml b/arch/csr/Zihpm/mhpmevent21h.yaml new file mode 100644 index 000000000..fca2aa0ad --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent21h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent21h: + long_name: Machine Hardware Performance Counter 21 Control, High half + address: 0x735 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent21`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent21.OF + description: | + Alias of mhpmevent21.OF. + type(): | + if (NUM_HPM_COUNTERS > 18) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 18) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent21.MINH + description: | + Alias of mhpmevent21.MINH. + type(): | + if (NUM_HPM_COUNTERS > 18) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 18) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent21.SINH + description: | + Alias of mhpmevent21.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 18) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 18) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent21.UINH + description: | + Alias of mhpmevent21.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 18) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 18) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent21.VSINH + description: | + Alias of mhpmevent21.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 18) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 18) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent21.VUINH + description: | + Alias of mhpmevent21.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 18) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 18) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter21`. + alias: mhpmevent21.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 18) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 18) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent22.yaml b/arch/csr/Zihpm/mhpmevent22.yaml new file mode 100644 index 000000000..a74cdaa15 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent22.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent22: + long_name: Machine Hardware Performance Counter 22 Control + address: 0x336 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter22 overflows. + type(): | + if (NUM_HPM_COUNTERS > 19) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 19) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter22 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 19) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 19) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter22 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 19) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 19) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter22 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 19) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 19) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter22 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 19) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 19) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter22 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 19) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 19) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter22`. + type(): | + if (NUM_HPM_COUNTERS > 19) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 19) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent22h.yaml b/arch/csr/Zihpm/mhpmevent22h.yaml new file mode 100644 index 000000000..4a13bc58a --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent22h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent22h: + long_name: Machine Hardware Performance Counter 22 Control, High half + address: 0x736 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent22`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent22.OF + description: | + Alias of mhpmevent22.OF. + type(): | + if (NUM_HPM_COUNTERS > 19) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 19) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent22.MINH + description: | + Alias of mhpmevent22.MINH. + type(): | + if (NUM_HPM_COUNTERS > 19) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 19) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent22.SINH + description: | + Alias of mhpmevent22.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 19) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 19) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent22.UINH + description: | + Alias of mhpmevent22.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 19) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 19) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent22.VSINH + description: | + Alias of mhpmevent22.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 19) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 19) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent22.VUINH + description: | + Alias of mhpmevent22.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 19) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 19) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter22`. + alias: mhpmevent22.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 19) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 19) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent23.yaml b/arch/csr/Zihpm/mhpmevent23.yaml new file mode 100644 index 000000000..72bb4b82a --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent23.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent23: + long_name: Machine Hardware Performance Counter 23 Control + address: 0x337 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter23 overflows. + type(): | + if (NUM_HPM_COUNTERS > 20) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 20) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter23 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 20) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 20) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter23 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 20) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 20) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter23 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 20) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 20) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter23 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 20) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 20) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter23 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 20) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 20) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter23`. + type(): | + if (NUM_HPM_COUNTERS > 20) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 20) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent23h.yaml b/arch/csr/Zihpm/mhpmevent23h.yaml new file mode 100644 index 000000000..7575e256f --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent23h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent23h: + long_name: Machine Hardware Performance Counter 23 Control, High half + address: 0x737 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent23`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent23.OF + description: | + Alias of mhpmevent23.OF. + type(): | + if (NUM_HPM_COUNTERS > 20) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 20) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent23.MINH + description: | + Alias of mhpmevent23.MINH. + type(): | + if (NUM_HPM_COUNTERS > 20) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 20) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent23.SINH + description: | + Alias of mhpmevent23.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 20) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 20) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent23.UINH + description: | + Alias of mhpmevent23.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 20) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 20) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent23.VSINH + description: | + Alias of mhpmevent23.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 20) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 20) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent23.VUINH + description: | + Alias of mhpmevent23.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 20) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 20) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter23`. + alias: mhpmevent23.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 20) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 20) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent24.yaml b/arch/csr/Zihpm/mhpmevent24.yaml new file mode 100644 index 000000000..e8736658c --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent24.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent24: + long_name: Machine Hardware Performance Counter 24 Control + address: 0x338 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter24 overflows. + type(): | + if (NUM_HPM_COUNTERS > 21) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 21) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter24 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 21) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 21) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter24 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 21) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 21) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter24 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 21) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 21) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter24 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 21) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 21) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter24 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 21) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 21) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter24`. + type(): | + if (NUM_HPM_COUNTERS > 21) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 21) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent24h.yaml b/arch/csr/Zihpm/mhpmevent24h.yaml new file mode 100644 index 000000000..9289c8012 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent24h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent24h: + long_name: Machine Hardware Performance Counter 24 Control, High half + address: 0x738 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent24`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent24.OF + description: | + Alias of mhpmevent24.OF. + type(): | + if (NUM_HPM_COUNTERS > 21) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 21) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent24.MINH + description: | + Alias of mhpmevent24.MINH. + type(): | + if (NUM_HPM_COUNTERS > 21) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 21) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent24.SINH + description: | + Alias of mhpmevent24.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 21) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 21) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent24.UINH + description: | + Alias of mhpmevent24.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 21) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 21) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent24.VSINH + description: | + Alias of mhpmevent24.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 21) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 21) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent24.VUINH + description: | + Alias of mhpmevent24.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 21) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 21) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter24`. + alias: mhpmevent24.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 21) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 21) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent25.yaml b/arch/csr/Zihpm/mhpmevent25.yaml new file mode 100644 index 000000000..e42ff7a13 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent25.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent25: + long_name: Machine Hardware Performance Counter 25 Control + address: 0x339 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter25 overflows. + type(): | + if (NUM_HPM_COUNTERS > 22) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 22) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter25 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 22) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 22) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter25 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 22) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 22) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter25 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 22) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 22) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter25 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 22) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 22) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter25 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 22) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 22) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter25`. + type(): | + if (NUM_HPM_COUNTERS > 22) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 22) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent25h.yaml b/arch/csr/Zihpm/mhpmevent25h.yaml new file mode 100644 index 000000000..51fbe3ed4 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent25h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent25h: + long_name: Machine Hardware Performance Counter 25 Control, High half + address: 0x739 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent25`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent25.OF + description: | + Alias of mhpmevent25.OF. + type(): | + if (NUM_HPM_COUNTERS > 22) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 22) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent25.MINH + description: | + Alias of mhpmevent25.MINH. + type(): | + if (NUM_HPM_COUNTERS > 22) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 22) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent25.SINH + description: | + Alias of mhpmevent25.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 22) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 22) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent25.UINH + description: | + Alias of mhpmevent25.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 22) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 22) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent25.VSINH + description: | + Alias of mhpmevent25.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 22) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 22) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent25.VUINH + description: | + Alias of mhpmevent25.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 22) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 22) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter25`. + alias: mhpmevent25.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 22) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 22) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent26.yaml b/arch/csr/Zihpm/mhpmevent26.yaml new file mode 100644 index 000000000..c97db2ffb --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent26.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent26: + long_name: Machine Hardware Performance Counter 26 Control + address: 0x33A + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter26 overflows. + type(): | + if (NUM_HPM_COUNTERS > 23) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 23) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter26 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 23) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 23) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter26 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 23) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 23) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter26 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 23) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 23) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter26 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 23) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 23) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter26 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 23) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 23) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter26`. + type(): | + if (NUM_HPM_COUNTERS > 23) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 23) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent26h.yaml b/arch/csr/Zihpm/mhpmevent26h.yaml new file mode 100644 index 000000000..03e32d7c0 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent26h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent26h: + long_name: Machine Hardware Performance Counter 26 Control, High half + address: 0x73A + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent26`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent26.OF + description: | + Alias of mhpmevent26.OF. + type(): | + if (NUM_HPM_COUNTERS > 23) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 23) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent26.MINH + description: | + Alias of mhpmevent26.MINH. + type(): | + if (NUM_HPM_COUNTERS > 23) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 23) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent26.SINH + description: | + Alias of mhpmevent26.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 23) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 23) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent26.UINH + description: | + Alias of mhpmevent26.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 23) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 23) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent26.VSINH + description: | + Alias of mhpmevent26.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 23) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 23) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent26.VUINH + description: | + Alias of mhpmevent26.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 23) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 23) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter26`. + alias: mhpmevent26.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 23) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 23) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent27.yaml b/arch/csr/Zihpm/mhpmevent27.yaml new file mode 100644 index 000000000..457357e49 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent27.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent27: + long_name: Machine Hardware Performance Counter 27 Control + address: 0x33B + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter27 overflows. + type(): | + if (NUM_HPM_COUNTERS > 24) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 24) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter27 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 24) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 24) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter27 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 24) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 24) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter27 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 24) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 24) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter27 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 24) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 24) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter27 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 24) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 24) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter27`. + type(): | + if (NUM_HPM_COUNTERS > 24) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 24) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent27h.yaml b/arch/csr/Zihpm/mhpmevent27h.yaml new file mode 100644 index 000000000..66ef263f8 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent27h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent27h: + long_name: Machine Hardware Performance Counter 27 Control, High half + address: 0x73B + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent27`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent27.OF + description: | + Alias of mhpmevent27.OF. + type(): | + if (NUM_HPM_COUNTERS > 24) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 24) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent27.MINH + description: | + Alias of mhpmevent27.MINH. + type(): | + if (NUM_HPM_COUNTERS > 24) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 24) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent27.SINH + description: | + Alias of mhpmevent27.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 24) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 24) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent27.UINH + description: | + Alias of mhpmevent27.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 24) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 24) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent27.VSINH + description: | + Alias of mhpmevent27.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 24) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 24) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent27.VUINH + description: | + Alias of mhpmevent27.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 24) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 24) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter27`. + alias: mhpmevent27.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 24) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 24) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent28.yaml b/arch/csr/Zihpm/mhpmevent28.yaml new file mode 100644 index 000000000..4cae791cc --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent28.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent28: + long_name: Machine Hardware Performance Counter 28 Control + address: 0x33C + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter28 overflows. + type(): | + if (NUM_HPM_COUNTERS > 25) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 25) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter28 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 25) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 25) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter28 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 25) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 25) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter28 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 25) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 25) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter28 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 25) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 25) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter28 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 25) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 25) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter28`. + type(): | + if (NUM_HPM_COUNTERS > 25) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 25) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent28h.yaml b/arch/csr/Zihpm/mhpmevent28h.yaml new file mode 100644 index 000000000..70ca7d7d2 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent28h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent28h: + long_name: Machine Hardware Performance Counter 28 Control, High half + address: 0x73C + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent28`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent28.OF + description: | + Alias of mhpmevent28.OF. + type(): | + if (NUM_HPM_COUNTERS > 25) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 25) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent28.MINH + description: | + Alias of mhpmevent28.MINH. + type(): | + if (NUM_HPM_COUNTERS > 25) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 25) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent28.SINH + description: | + Alias of mhpmevent28.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 25) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 25) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent28.UINH + description: | + Alias of mhpmevent28.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 25) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 25) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent28.VSINH + description: | + Alias of mhpmevent28.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 25) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 25) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent28.VUINH + description: | + Alias of mhpmevent28.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 25) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 25) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter28`. + alias: mhpmevent28.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 25) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 25) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent29.yaml b/arch/csr/Zihpm/mhpmevent29.yaml new file mode 100644 index 000000000..7a00dd0d9 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent29.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent29: + long_name: Machine Hardware Performance Counter 29 Control + address: 0x33D + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter29 overflows. + type(): | + if (NUM_HPM_COUNTERS > 26) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 26) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter29 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 26) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 26) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter29 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 26) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 26) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter29 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 26) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 26) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter29 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 26) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 26) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter29 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 26) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 26) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter29`. + type(): | + if (NUM_HPM_COUNTERS > 26) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 26) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent29h.yaml b/arch/csr/Zihpm/mhpmevent29h.yaml new file mode 100644 index 000000000..a745de56f --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent29h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent29h: + long_name: Machine Hardware Performance Counter 29 Control, High half + address: 0x73D + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent29`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent29.OF + description: | + Alias of mhpmevent29.OF. + type(): | + if (NUM_HPM_COUNTERS > 26) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 26) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent29.MINH + description: | + Alias of mhpmevent29.MINH. + type(): | + if (NUM_HPM_COUNTERS > 26) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 26) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent29.SINH + description: | + Alias of mhpmevent29.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 26) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 26) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent29.UINH + description: | + Alias of mhpmevent29.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 26) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 26) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent29.VSINH + description: | + Alias of mhpmevent29.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 26) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 26) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent29.VUINH + description: | + Alias of mhpmevent29.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 26) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 26) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter29`. + alias: mhpmevent29.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 26) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 26) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent3.yaml b/arch/csr/Zihpm/mhpmevent3.yaml new file mode 100644 index 000000000..16f55d2c2 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent3.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent3: + long_name: Machine Hardware Performance Counter 3 Control + address: 0x323 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter3 overflows. + type(): | + if (NUM_HPM_COUNTERS > 0) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 0) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter3 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 0) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 0) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter3 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 0) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 0) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter3 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 0) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 0) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter3 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 0) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 0) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter3 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 0) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 0) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter3`. + type(): | + if (NUM_HPM_COUNTERS > 0) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 0) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent30.yaml b/arch/csr/Zihpm/mhpmevent30.yaml new file mode 100644 index 000000000..dc3a746cf --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent30.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent30: + long_name: Machine Hardware Performance Counter 30 Control + address: 0x33E + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter30 overflows. + type(): | + if (NUM_HPM_COUNTERS > 27) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 27) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter30 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 27) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 27) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter30 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 27) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 27) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter30 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 27) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 27) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter30 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 27) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 27) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter30 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 27) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 27) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter30`. + type(): | + if (NUM_HPM_COUNTERS > 27) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 27) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent30h.yaml b/arch/csr/Zihpm/mhpmevent30h.yaml new file mode 100644 index 000000000..08d8a6a14 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent30h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent30h: + long_name: Machine Hardware Performance Counter 30 Control, High half + address: 0x73E + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent30`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent30.OF + description: | + Alias of mhpmevent30.OF. + type(): | + if (NUM_HPM_COUNTERS > 27) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 27) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent30.MINH + description: | + Alias of mhpmevent30.MINH. + type(): | + if (NUM_HPM_COUNTERS > 27) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 27) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent30.SINH + description: | + Alias of mhpmevent30.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 27) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 27) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent30.UINH + description: | + Alias of mhpmevent30.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 27) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 27) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent30.VSINH + description: | + Alias of mhpmevent30.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 27) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 27) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent30.VUINH + description: | + Alias of mhpmevent30.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 27) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 27) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter30`. + alias: mhpmevent30.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 27) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 27) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent31.yaml b/arch/csr/Zihpm/mhpmevent31.yaml new file mode 100644 index 000000000..1eb495d76 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent31.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent31: + long_name: Machine Hardware Performance Counter 31 Control + address: 0x33F + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter31 overflows. + type(): | + if (NUM_HPM_COUNTERS > 28) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 28) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter31 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 28) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 28) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter31 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 28) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 28) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter31 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 28) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 28) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter31 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 28) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 28) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter31 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 28) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 28) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter31`. + type(): | + if (NUM_HPM_COUNTERS > 28) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 28) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent31h.yaml b/arch/csr/Zihpm/mhpmevent31h.yaml new file mode 100644 index 000000000..776a9f5df --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent31h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent31h: + long_name: Machine Hardware Performance Counter 31 Control, High half + address: 0x73F + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent31`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent31.OF + description: | + Alias of mhpmevent31.OF. + type(): | + if (NUM_HPM_COUNTERS > 28) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 28) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent31.MINH + description: | + Alias of mhpmevent31.MINH. + type(): | + if (NUM_HPM_COUNTERS > 28) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 28) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent31.SINH + description: | + Alias of mhpmevent31.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 28) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 28) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent31.UINH + description: | + Alias of mhpmevent31.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 28) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 28) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent31.VSINH + description: | + Alias of mhpmevent31.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 28) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 28) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent31.VUINH + description: | + Alias of mhpmevent31.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 28) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 28) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter31`. + alias: mhpmevent31.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 28) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 28) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent3h.yaml b/arch/csr/Zihpm/mhpmevent3h.yaml new file mode 100644 index 000000000..bbf7dd79b --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent3h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent3h: + long_name: Machine Hardware Performance Counter 3 Control, High half + address: 0x723 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent3`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent3.OF + description: | + Alias of mhpmevent3.OF. + type(): | + if (NUM_HPM_COUNTERS > 0) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 0) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent3.MINH + description: | + Alias of mhpmevent3.MINH. + type(): | + if (NUM_HPM_COUNTERS > 0) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 0) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent3.SINH + description: | + Alias of mhpmevent3.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 0) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 0) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent3.UINH + description: | + Alias of mhpmevent3.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 0) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 0) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent3.VSINH + description: | + Alias of mhpmevent3.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 0) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 0) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent3.VUINH + description: | + Alias of mhpmevent3.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 0) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 0) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter3`. + alias: mhpmevent3.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 0) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 0) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent4.yaml b/arch/csr/Zihpm/mhpmevent4.yaml new file mode 100644 index 000000000..6d95c9ee0 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent4.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent4: + long_name: Machine Hardware Performance Counter 4 Control + address: 0x324 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter4 overflows. + type(): | + if (NUM_HPM_COUNTERS > 1) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 1) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter4 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 1) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 1) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter4 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 1) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 1) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter4 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 1) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 1) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter4 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 1) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 1) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter4 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 1) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 1) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter4`. + type(): | + if (NUM_HPM_COUNTERS > 1) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 1) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent4h.yaml b/arch/csr/Zihpm/mhpmevent4h.yaml new file mode 100644 index 000000000..dba74c746 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent4h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent4h: + long_name: Machine Hardware Performance Counter 4 Control, High half + address: 0x724 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent4`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent4.OF + description: | + Alias of mhpmevent4.OF. + type(): | + if (NUM_HPM_COUNTERS > 1) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 1) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent4.MINH + description: | + Alias of mhpmevent4.MINH. + type(): | + if (NUM_HPM_COUNTERS > 1) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 1) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent4.SINH + description: | + Alias of mhpmevent4.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 1) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 1) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent4.UINH + description: | + Alias of mhpmevent4.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 1) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 1) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent4.VSINH + description: | + Alias of mhpmevent4.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 1) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 1) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent4.VUINH + description: | + Alias of mhpmevent4.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 1) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 1) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter4`. + alias: mhpmevent4.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 1) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 1) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent5.yaml b/arch/csr/Zihpm/mhpmevent5.yaml new file mode 100644 index 000000000..030de39ff --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent5.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent5: + long_name: Machine Hardware Performance Counter 5 Control + address: 0x325 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter5 overflows. + type(): | + if (NUM_HPM_COUNTERS > 2) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 2) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter5 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 2) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 2) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter5 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 2) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 2) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter5 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 2) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 2) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter5 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 2) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 2) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter5 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 2) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 2) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter5`. + type(): | + if (NUM_HPM_COUNTERS > 2) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 2) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent5h.yaml b/arch/csr/Zihpm/mhpmevent5h.yaml new file mode 100644 index 000000000..40511586b --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent5h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent5h: + long_name: Machine Hardware Performance Counter 5 Control, High half + address: 0x725 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent5`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent5.OF + description: | + Alias of mhpmevent5.OF. + type(): | + if (NUM_HPM_COUNTERS > 2) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 2) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent5.MINH + description: | + Alias of mhpmevent5.MINH. + type(): | + if (NUM_HPM_COUNTERS > 2) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 2) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent5.SINH + description: | + Alias of mhpmevent5.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 2) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 2) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent5.UINH + description: | + Alias of mhpmevent5.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 2) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 2) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent5.VSINH + description: | + Alias of mhpmevent5.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 2) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 2) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent5.VUINH + description: | + Alias of mhpmevent5.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 2) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 2) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter5`. + alias: mhpmevent5.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 2) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 2) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent6.yaml b/arch/csr/Zihpm/mhpmevent6.yaml new file mode 100644 index 000000000..033b57ec8 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent6.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent6: + long_name: Machine Hardware Performance Counter 6 Control + address: 0x326 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter6 overflows. + type(): | + if (NUM_HPM_COUNTERS > 3) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 3) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter6 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 3) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 3) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter6 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 3) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 3) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter6 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 3) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 3) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter6 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 3) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 3) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter6 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 3) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 3) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter6`. + type(): | + if (NUM_HPM_COUNTERS > 3) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 3) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent6h.yaml b/arch/csr/Zihpm/mhpmevent6h.yaml new file mode 100644 index 000000000..02da8d1c9 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent6h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent6h: + long_name: Machine Hardware Performance Counter 6 Control, High half + address: 0x726 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent6`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent6.OF + description: | + Alias of mhpmevent6.OF. + type(): | + if (NUM_HPM_COUNTERS > 3) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 3) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent6.MINH + description: | + Alias of mhpmevent6.MINH. + type(): | + if (NUM_HPM_COUNTERS > 3) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 3) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent6.SINH + description: | + Alias of mhpmevent6.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 3) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 3) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent6.UINH + description: | + Alias of mhpmevent6.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 3) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 3) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent6.VSINH + description: | + Alias of mhpmevent6.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 3) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 3) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent6.VUINH + description: | + Alias of mhpmevent6.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 3) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 3) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter6`. + alias: mhpmevent6.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 3) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 3) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent7.yaml b/arch/csr/Zihpm/mhpmevent7.yaml new file mode 100644 index 000000000..203afbe98 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent7.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent7: + long_name: Machine Hardware Performance Counter 7 Control + address: 0x327 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter7 overflows. + type(): | + if (NUM_HPM_COUNTERS > 4) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 4) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter7 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 4) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 4) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter7 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 4) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 4) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter7 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 4) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 4) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter7 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 4) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 4) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter7 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 4) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 4) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter7`. + type(): | + if (NUM_HPM_COUNTERS > 4) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 4) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent7h.yaml b/arch/csr/Zihpm/mhpmevent7h.yaml new file mode 100644 index 000000000..84bc3de3a --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent7h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent7h: + long_name: Machine Hardware Performance Counter 7 Control, High half + address: 0x727 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent7`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent7.OF + description: | + Alias of mhpmevent7.OF. + type(): | + if (NUM_HPM_COUNTERS > 4) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 4) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent7.MINH + description: | + Alias of mhpmevent7.MINH. + type(): | + if (NUM_HPM_COUNTERS > 4) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 4) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent7.SINH + description: | + Alias of mhpmevent7.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 4) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 4) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent7.UINH + description: | + Alias of mhpmevent7.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 4) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 4) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent7.VSINH + description: | + Alias of mhpmevent7.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 4) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 4) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent7.VUINH + description: | + Alias of mhpmevent7.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 4) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 4) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter7`. + alias: mhpmevent7.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 4) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 4) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent8.yaml b/arch/csr/Zihpm/mhpmevent8.yaml new file mode 100644 index 000000000..470f3ca5f --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent8.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent8: + long_name: Machine Hardware Performance Counter 8 Control + address: 0x328 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter8 overflows. + type(): | + if (NUM_HPM_COUNTERS > 5) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 5) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter8 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 5) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 5) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter8 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 5) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 5) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter8 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 5) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 5) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter8 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 5) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 5) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter8 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 5) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 5) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter8`. + type(): | + if (NUM_HPM_COUNTERS > 5) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 5) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent8h.yaml b/arch/csr/Zihpm/mhpmevent8h.yaml new file mode 100644 index 000000000..49c2685f7 --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent8h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent8h: + long_name: Machine Hardware Performance Counter 8 Control, High half + address: 0x728 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent8`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent8.OF + description: | + Alias of mhpmevent8.OF. + type(): | + if (NUM_HPM_COUNTERS > 5) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 5) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent8.MINH + description: | + Alias of mhpmevent8.MINH. + type(): | + if (NUM_HPM_COUNTERS > 5) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 5) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent8.SINH + description: | + Alias of mhpmevent8.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 5) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 5) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent8.UINH + description: | + Alias of mhpmevent8.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 5) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 5) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent8.VSINH + description: | + Alias of mhpmevent8.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 5) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 5) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent8.VUINH + description: | + Alias of mhpmevent8.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 5) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 5) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter8`. + alias: mhpmevent8.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 5) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 5) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmevent9.yaml b/arch/csr/Zihpm/mhpmevent9.yaml new file mode 100644 index 000000000..60456a8ca --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent9.yaml @@ -0,0 +1,144 @@ + + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventN.layout + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + + +mhpmevent9: + long_name: Machine Hardware Performance Counter 9 Control + address: 0x329 + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter9 overflows. + type(): | + if (NUM_HPM_COUNTERS > 6) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 6) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter9 does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > 6) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 6) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter9 does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > 6) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 6) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter9 does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > 6) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 6) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter9 does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > 6) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 6) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter9 does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > 6) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 6) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter9`. + type(): | + if (NUM_HPM_COUNTERS > 6) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 6) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmevent9h.yaml b/arch/csr/Zihpm/mhpmevent9h.yaml new file mode 100644 index 000000000..00df7045e --- /dev/null +++ b/arch/csr/Zihpm/mhpmevent9h.yaml @@ -0,0 +1,143 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +# WARNING: This file is auto-generated from arch/csr/Zihpm/mhpmeventNh.layout + + + +mhpmevent9h: + long_name: Machine Hardware Performance Counter 9 Control, High half + address: 0x729 + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent9`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent9.OF + description: | + Alias of mhpmevent9.OF. + type(): | + if (NUM_HPM_COUNTERS > 6) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 6) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent9.MINH + description: | + Alias of mhpmevent9.MINH. + type(): | + if (NUM_HPM_COUNTERS > 6) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 6) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent9.SINH + description: | + Alias of mhpmevent9.SINH. + type(): | + if ((NUM_HPM_COUNTERS > 6) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 6) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent9.UINH + description: | + Alias of mhpmevent9.UINH. + type(): | + if ((NUM_HPM_COUNTERS > 6) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 6) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent9.VSINH + description: | + Alias of mhpmevent9.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > 6) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 6) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent9.VUINH + description: | + Alias of mhpmevent9.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > 6) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > 6) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter9`. + alias: mhpmevent9.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > 6) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > 6) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/Zihpm/mhpmeventN.layout b/arch/csr/Zihpm/mhpmeventN.layout new file mode 100644 index 000000000..faa68f10e --- /dev/null +++ b/arch/csr/Zihpm/mhpmeventN.layout @@ -0,0 +1,142 @@ + +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +<%- raise "'hpm_num' must be defined" if hpm_num.nil? -%> + +<%= "mhpmevent#{hpm_num}" %>: + long_name: Machine Hardware Performance Counter <%= hpm_num %> Control + address: <%= "0x" + (0x320 + hpm_num).to_s(16).upcase %> + priv_mode: M + length: 64 + description: | + Programmable hardware performance counter event selector + <%% if ext?(:Sscofpmf) %> and overflow/filtering control<%% end %> + definedBy: I + fields: + OF: + location: 63 + description: | + Overflow status and interrupt disable. + + The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by + software. Since hpmcounter values are unsigned values, overflow is defined as unsigned + overflow of the implemented counter bits. + + The OF bit is sticky; it stays set until explictly cleared by a CSR write. + + A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and + mhpmcounter<%= hpm_num %> overflows. + type(): | + if (NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 62 + description: When set, mhpmcounter<%= hpm_num %> does not increment while the hart in operating in M-mode. + type(): | + if (NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 61 + description: When set, mhpmcounter<%= hpm_num %> does not increment while the hart in operating in (H)S-mode. + type(): | + if ((NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 60 + description: When set, mhpmcounter<%= hpm_num %> does not increment while the hart in operating in U-mode. + type(): | + if ((NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 59 + description: When set, mhpmcounter<%= hpm_num %> does not increment while the hart in operating in VS-mode. + type(): | + if ((NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 58 + description: When set, mhpmcounter<%= hpm_num %> does not increment while the hart in operating in VU-mode. + type(): | + if ((NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 57-0 + description: Event selector for performance counter `mhpmcounter<%= hpm_num %>`. + type(): | + if (NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + write(csr_value): | + if (csr_value.EVENT <= MAX_HPM_EVENT) { + return csr_value.EVENT; + } else { + return UNDEFINED_LEGAL_DETERMINISTIC; + } diff --git a/arch/csr/Zihpm/mhpmeventNh.layout b/arch/csr/Zihpm/mhpmeventNh.layout new file mode 100644 index 000000000..5d72720f7 --- /dev/null +++ b/arch/csr/Zihpm/mhpmeventNh.layout @@ -0,0 +1,141 @@ +# yaml-language-server: $schema=../../../schemas/csr_schema.json + +<%- raise "'hpm_num' must be defined" if hpm_num.nil? -%> + +<%= "mhpmevent#{hpm_num}h" %>: + long_name: Machine Hardware Performance Counter <%= hpm_num %> Control, High half + address: 0x<%= (0x720 + hpm_num).to_s(16).upcase %> + priv_mode: M + length: 32 + base: 32 + description: | + Alias of `mhpmevent<%= hpm_num %>`[63:32]. + + Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper + 32-bits of `mhpmevent#{hpm_num}`. + definedBy: Sscofpmf + fields: + OF: + location: 31 + alias: mhpmevent<%= hpm_num %>.OF + description: | + Alias of mhpmevent<%= hpm_num %>.OF. + type(): | + if (NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) { + return CsrFieldType::RWH; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + MINH: + location: 30 + alias: mhpmevent<%= hpm_num %>.MINH + description: | + Alias of mhpmevent<%= hpm_num %>.MINH. + type(): | + if (NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + SINH: + location: 29 + alias: mhpmevent<%= hpm_num %>.SINH + description: | + Alias of mhpmevent<%= hpm_num %>.SINH. + type(): | + if ((NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) && implemented?(ExtensionName::S) && (CSR[misa].S == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) && implemented?(ExtensionName::S)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + UINH: + location: 28 + alias: mhpmevent<%= hpm_num %>.UINH + description: | + Alias of mhpmevent<%= hpm_num %>.UINH. + type(): | + if ((NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) && implemented?(ExtensionName::U) && (CSR[misa].U == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) && implemented?(ExtensionName::U)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VSINH: + location: 27 + alias: mhpmevent<%= hpm_num %>.VSINH + description: | + Alias of mhpmevent<%= hpm_num %>.VSINH. + type(): | + if ((NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + VUINH: + location: 26 + alias: mhpmevent<%= hpm_num %>.VUINH + description: | + Alias of mhpmevent<%= hpm_num %>.VUINH. + type(): | + if ((NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) && implemented?(ExtensionName::H) && (CSR[misa].H == 1'b1)) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if ((NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) && implemented?(ExtensionName::H)) { + return UNDEFINED_LEGAL; + } else { + return 0; + } + definedBy: Sscofpmf + EVENT: + location: 25-0 + description: High part of event selector for performance counter `mhpmcounter<%= hpm_num %>`. + alias: mhpmevent<%= hpm_num %>.EVENT[57:32] + type(): | + if (NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) { + return CsrFieldType::RW; + } else { + return CsrFieldType::RO; + } + reset_value(): | + if (NUM_HPM_COUNTERS > <%= hpm_num - 3 %>) { + return UNDEFINED_LEGAL; + } else { + return 0; + } diff --git a/arch/csr/cycle.yaml b/arch/csr/cycle.yaml index 27ee63ffa..aa0625b23 100644 --- a/arch/csr/cycle.yaml +++ b/arch/csr/cycle.yaml @@ -10,23 +10,62 @@ cycle: [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] !=== - .2+h![.rotate]#`mcounteren.CY`# .2+h! [.rotate]#`scounteren.CY`# .2+h! [.rotate]#`scounteren.CY`# - 4+^.>h! `time` behavior + .2+h![.rotate]#`mcounteren.CY`# .2+h! [.rotate]#`scounteren.CY`# .2+h! [.rotate]#`hcounteren.CY`# + 4+^.>h! `cycle` behavior .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode - ! 0 ! - ! - ! `Illegal Instruction` ! `Illegal Instruction` ! `Illegal Instruction` ! `Illegal Instruction` - ! 1 ! 0 ! 0 ! read-only ! `Illegal Instruction` ! `Illegal Instruction` ! `Illegal Instruction` - ! 1 ! 1 ! 0 ! read-only ! read-only ! `Illegal Instruction` ! `Illegal Instruction` - ! 1 ! 0 ! 1 ! read-only ! `Illegal Instruction` ! read-only ! `Illegal Instruction` + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U length: 64 - definedBy: I + definedBy: Zicntr fields: COUNT: location: 63-0 alias: mcycle.COUNT description: Alias of `mcycle.COUNT`. type: RO-H - reset_value: UNDEFINED_LEGAL \ No newline at end of file + 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].CY == 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].CY & CSR[scounteren].CY) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].CY == 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].CY == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].CY == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].CY & CSR[scounteren].CY) == 1'b0) && (CSR[mcounteren].CY == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].CY == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + # since the counter may be shared among harts, reads must be handled + # as a builtin function + return read_mcycle(); diff --git a/arch/csr/cycleh.yaml b/arch/csr/cycleh.yaml new file mode 100644 index 000000000..7c307197f --- /dev/null +++ b/arch/csr/cycleh.yaml @@ -0,0 +1,77 @@ +# yaml-language-server: $schema=../../schemas/csr_schema.json + +cycleh: + long_name: High-half cycle counter for RDCYCLE Instruction + address: 0xC80 + base: 32 + description: | + Alias for M-mode CSR `mcycleh`. + + Privilege mode access is controlled with `mcounteren.CY`, `scounteren.CY`, and `hcounteren.CY` as follows: + + [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] + !=== + .2+h![.rotate]#`mcounteren.CY`# .2+h! [.rotate]#`scounteren.CY`# .2+h! [.rotate]#`hcounteren.CY`# + 4+^.>h! `cycle` behavior + .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode + + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` + ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only + !=== + priv_mode: U + length: 32 + definedBy: Zicntr + fields: + COUNT: + location: 31-0 + alias: mcycleh.COUNT + description: Alias of `mcycleh.COUNT`. + type: RO-H + reset_value: UNDEFINED_LEGAL + sw_read(): | + # NOTE: The spec specifically says that reading cycleh when XLEN == 64 always causes + # IllegalInstruction exception even if it would otherwise be changed to a `VirtualInstruction + # exception. We don't have to explicitly check this here because it is already implied by + # the base constraint + + # access is determined by *counteren CSRs + if (mode() == PrivilegeMode::S) { + # S-mode is present -> + # mcounteren determines access in S-mode + if (CSR[mcounteren].CY == 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].CY & CSR[scounteren].CY) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].CY == 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].CY == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].CY == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].CY & CSR[scounteren].CY) == 1'b0) && (CSR[mcounteren].CY == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].CY == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + # since the counter may be shared among harts, reads must be handled + # as a builtin function + return read_mcycle()[63:32]; diff --git a/arch/csr/instret.yaml b/arch/csr/instret.yaml index f22caa015..94d020423 100644 --- a/arch/csr/instret.yaml +++ b/arch/csr/instret.yaml @@ -10,19 +10,19 @@ instret: [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] !=== - .2+h![.rotate]#`mcounteren.IR`# .2+h! [.rotate]#`scounteren.IR`# .2+h! [.rotate]#`scounteren.IR`# - 4+^.>h! `time` behavior + .2+h![.rotate]#`mcounteren.IR`# .2+h! [.rotate]#`scounteren.IR`# .2+h! [.rotate]#`hcounteren.IR`# + 4+^.>h! `instret` behavior .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode - ! 0 ! - ! - ! `Illegal Instruction` ! `Illegal Instruction` ! `Illegal Instruction` ! `Illegal Instruction` - ! 1 ! 0 ! 0 ! read-only ! `Illegal Instruction` ! `Illegal Instruction` ! `Illegal Instruction` - ! 1 ! 1 ! 0 ! read-only ! read-only ! `Illegal Instruction` ! `Illegal Instruction` - ! 1 ! 0 ! 1 ! read-only ! `Illegal Instruction` ! read-only ! `Illegal Instruction` + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U length: 64 - definedBy: I + definedBy: Zicntr fields: COUNT: location: 63-0 @@ -30,3 +30,42 @@ instret: description: Alias of `minstret.COUNT`. type: RO-H reset_value: 0 + 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].IR == 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].IR & CSR[scounteren].IR) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].IR == 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].IR == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].IR == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].IR & CSR[scounteren].IR) == 1'b0) && (CSR[mcounteren].IR == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].IR == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + # since the counter may be shared among harts, reads must be handled + # as a builtin function + return read_mcycle(); \ No newline at end of file diff --git a/arch/csr/instreth.yaml b/arch/csr/instreth.yaml index 7548571c6..ae7d1d5bc 100644 --- a/arch/csr/instreth.yaml +++ b/arch/csr/instreth.yaml @@ -1,29 +1,29 @@ # yaml-language-server: $schema=../../schemas/csr_schema.json instreth: - long_name: Instructions retired counter for RDINSTRET Instruction, High bits + long_name: Instructions retired counter, high bits address: 0xC82 base: 32 description: | - Alias for low bits of M-mode CSR `minstret`[63:32]. + Alias for high bits of M-mode CSR `minstret`[63:32]. Privilege mode access is controlled with `mcounteren.IR`, `scounteren.IR`, and `hcounteren.IR` as follows: [%autowidth,cols="1,1,1,1,1,1,1",separator="!"] !=== - .2+h![.rotate]#`mcounteren.IR`# .2+h! [.rotate]#`scounteren.IR`# .2+h! [.rotate]#`scounteren.IR`# - 4+^.>h! `time` behavior + .2+h![.rotate]#`mcounteren.IR`# .2+h! [.rotate]#`scounteren.IR`# .2+h! [.rotate]#`hcounteren.IR`# + 4+^.>h! `instret` behavior .^h! S-mode .^h! U-mode .^h! VS-mode .^h! VU-mode - ! 0 ! - ! - ! `Illegal Instruction` ! `Illegal Instruction` ! `Illegal Instruction` ! `Illegal Instruction` - ! 1 ! 0 ! 0 ! read-only ! `Illegal Instruction` ! `Illegal Instruction` ! `Illegal Instruction` - ! 1 ! 1 ! 0 ! read-only ! read-only ! `Illegal Instruction` ! `Illegal Instruction` - ! 1 ! 0 ! 1 ! read-only ! `Illegal Instruction` ! read-only ! `Illegal Instruction` + ! 0 ! - ! - ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` ! `IllegalInstruction` + ! 1 ! 0 ! 0 ! read-only ! `IllegalInstruction` ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 1 ! 0 ! read-only ! read-only ! `VirtualInstruction` ! `VirtualInstruction` + ! 1 ! 0 ! 1 ! read-only ! `IllegalInstruction` ! read-only ! `VirtualInstruction` ! 1 ! 1 ! 1 ! read-only ! read-only ! read-only ! read-only !=== priv_mode: U length: 32 - definedBy: I + definedBy: Zicntr fields: COUNT: location: 31-0 @@ -31,3 +31,42 @@ instreth: description: Alias of `minstret.COUNT`[63:32]. 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].IR == 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].IR & CSR[scounteren].IR) == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (CSR[mcounteren].IR == 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].IR == 1'b0 && CSR[mcounteren] == 1'b1) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if (CSR[mcounteren].IR == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } else if (mode() == PrivilegeMode::VU) { + # access in VU mode + if (((CSR[hcounteren].IR & CSR[scounteren].IR) == 1'b0) && (CSR[mcounteren].IR == 1'b1)) { + raise(ExceptionCode::VirtualInstruction, $encoding); + } else if ((CSR[mcounteren].IR == 1'b0) { + raise(ExceptionCode::IllegalInstruction, $encoding); + } + } + + # since the counter may be shared among harts, reads must be handled + # as a builtin function + return read_mcycle(); \ No newline at end of file diff --git a/arch/csr/mcounteren.yaml b/arch/csr/mcounteren.yaml deleted file mode 100644 index 039350dc8..000000000 --- a/arch/csr/mcounteren.yaml +++ /dev/null @@ -1,74 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -mcounteren: - long_name: Machine Counter Enable - address: 0x306 - priv_mode: M - length: 32 - description: | - Delegates control of the hardware performance-monitoring counters - to the next-lowest privileged mode - definedBy: U # actually, defined by RV64, but must implement U-mode for this CSR to exist - fields: - CY: - location: 0 - description: | - When set, the `cycle` CSR (an alias of `mcycle`) is accessible to - <%- if ext?(:S) -%> - S-mode. - <%- else -%> - U-mode. - <%- end -%> - - <%- if ext?(:S) -%> - When `scounteren.CY` is also set, `cycle` is futher accessible to U-mode. - <%- end -%> - type: RW - reset_value: UNDEFINED_LEGAL - TM: - location: 1 - description: | - When set, the `time` CSR (an alias of memory-mapped `mtime`) 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 -%> - type: RW - reset_value: UNDEFINED_LEGAL - IR: - location: 2 - description: | - When set, the `instret` CSR (an alias of memory-mapped `minstret`) is accessible to - <%- if ext?(:S) -%> - S-mode. - <%- else -%> - U-mode. - <%- end -%> - - <%- if ext?(:S) -%> - When `scounteren.IR` is also set, `instret` is futher accessible to U-mode. - <%- end -%> - type: RW - reset_value: UNDEFINED_LEGAL - <%- NUM_HPM_COUNTERS.times do |hpm_num| -%> - HPM<%= hpm_num + 3 %>: - location: <%= 3 + hpm_num %> - description: | - When set, the `hpmcounter<%= 3 + hpm_num %>` CSR (an alias of `mhpmcounter<%= 3 + hpm_num %>`) is accessible to - <%- if ext?(:S) -%> - S-mode. - <%- else -%> - U-mode. - <%- end -%> - - <%- if ext?(:S) -%> - When `scounteren.HPM<%= hpm_num + 3 %>` is also set, `hpmcounter<%= 3 + hpm_num %>` is futher accessible to U-mode. - <%- end -%> - type: RW - reset_value: UNDEFINED_LEGAL - <%- end -%> diff --git a/arch/csr/mcycle.yaml b/arch/csr/mcycle.yaml index 507560cdc..a5165f4cf 100644 --- a/arch/csr/mcycle.yaml +++ b/arch/csr/mcycle.yaml @@ -2,7 +2,7 @@ mcycle: long_name: Machine Cycle Counter - definedBy: I + definedBy: Zicntr address: 0xB00 description: | Counts the number of clock cycles executed by the processor core on which @@ -14,10 +14,6 @@ mcycle: a mechanism to indicate which harts share an `mcycle` CSR. priv_mode: M length: 64 - sw_read(): | - # since the counter may be shared among harts, reads must be handled - # as a special case - return read_mcycle(); fields: COUNT: alias: @@ -27,7 +23,11 @@ mcycle: write(csr_value): | # since writes to this register may not be hart-local, it must be handled # as a special case - return write_mcycle(csr_value.COUNT); + if (xlen() == 32) { + return write_mcycle({read_mcycle()[63:31], csr_value.COUNT[31:0]}); + } else { + return write_mcycle(csr_value.COUNT); + } description: | Cycle counter. @@ -53,3 +53,7 @@ mcycle: <%- end -%> reset_value: UNDEFINED_LEGAL affectedBy: [Zicntr, Smcntrpmf, Smcdeleg, Ssccfg] + sw_read(): | + # since the counter may be shared among harts, reads must be handled + # as a builtin function + return read_mcycle(); diff --git a/arch/csr/mcycleh.yaml b/arch/csr/mcycleh.yaml new file mode 100644 index 000000000..4f93d7486 --- /dev/null +++ b/arch/csr/mcycleh.yaml @@ -0,0 +1,31 @@ +# yaml-language-server: $schema=../../schemas/csr_schema.json + +mcycleh: + long_name: High-half machine Cycle Counter + definedBy: Zicntr + address: 0xB80 + description: | + High-half alias of `mcycle`. + priv_mode: M + length: 32 + base: 32 + fields: + COUNT: + location: 31-0 + type: RW-RH + write(csr_value): | + # since writes to this register may not be hart-local, it must be handled + # as a special case + if (xlen() == 32) { + return write_mcycle({csr_value.COUNT[31:0], read_mcycle()[31:0]}); + } else { + return write_mcycle(csr_value.COUNT); + } + description: | + Alias of upper half of `mcycle.COUNT`. + reset_value: UNDEFINED_LEGAL + affectedBy: [Zicntr, Smcntrpmf, Smcdeleg, Ssccfg] + sw_read(): | + # since the counter may be shared among harts, reads must be handled + # as a builtin function + return read_mcycle()[63:0]; diff --git a/arch/csr/mepc.yaml b/arch/csr/mepc.yaml index 8a52fa4c8..806747c65 100644 --- a/arch/csr/mepc.yaml +++ b/arch/csr/mepc.yaml @@ -36,8 +36,8 @@ mepc: return csr_value.PC & ~64'b1; reset_value: 0 sw_read(): | - if (implemented?(C) && CSR[misa].C == 1'b1) { - return CSR[mepc] & ~64'b3; + if (implemented?(ExtensionName::C) && CSR[misa].C == 1'b1) { + return CSR[mepc] & ~64'b1; } else { return CSR[mepc]; } \ No newline at end of file diff --git a/arch/csr/mhpmcounter10.yaml b/arch/csr/mhpmcounter10.yaml deleted file mode 100644 index f7f9208f2..000000000 --- a/arch/csr/mhpmcounter10.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 10 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter10h.yaml b/arch/csr/mhpmcounter10h.yaml deleted file mode 100644 index 06096ccb8..000000000 --- a/arch/csr/mhpmcounter10h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 10 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter11.yaml b/arch/csr/mhpmcounter11.yaml deleted file mode 100644 index 10100db78..000000000 --- a/arch/csr/mhpmcounter11.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 11 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter11h.yaml b/arch/csr/mhpmcounter11h.yaml deleted file mode 100644 index f7344e4d8..000000000 --- a/arch/csr/mhpmcounter11h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 11 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter12.yaml b/arch/csr/mhpmcounter12.yaml deleted file mode 100644 index ef9092c64..000000000 --- a/arch/csr/mhpmcounter12.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 12 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter12h.yaml b/arch/csr/mhpmcounter12h.yaml deleted file mode 100644 index 10ed23ef9..000000000 --- a/arch/csr/mhpmcounter12h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 12 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter13.yaml b/arch/csr/mhpmcounter13.yaml deleted file mode 100644 index 56830e4e5..000000000 --- a/arch/csr/mhpmcounter13.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 13 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter13h.yaml b/arch/csr/mhpmcounter13h.yaml deleted file mode 100644 index bd5903a96..000000000 --- a/arch/csr/mhpmcounter13h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 13 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter14.yaml b/arch/csr/mhpmcounter14.yaml deleted file mode 100644 index b48bb57a3..000000000 --- a/arch/csr/mhpmcounter14.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 14 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter14h.yaml b/arch/csr/mhpmcounter14h.yaml deleted file mode 100644 index 5f98abc2f..000000000 --- a/arch/csr/mhpmcounter14h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 14 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter15.yaml b/arch/csr/mhpmcounter15.yaml deleted file mode 100644 index ced259307..000000000 --- a/arch/csr/mhpmcounter15.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 15 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter15h.yaml b/arch/csr/mhpmcounter15h.yaml deleted file mode 100644 index 1ce915f78..000000000 --- a/arch/csr/mhpmcounter15h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 15 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter16.yaml b/arch/csr/mhpmcounter16.yaml deleted file mode 100644 index a419dec74..000000000 --- a/arch/csr/mhpmcounter16.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 16 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter16h.yaml b/arch/csr/mhpmcounter16h.yaml deleted file mode 100644 index a52c3e61f..000000000 --- a/arch/csr/mhpmcounter16h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 16 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter17.yaml b/arch/csr/mhpmcounter17.yaml deleted file mode 100644 index 3b3a50a97..000000000 --- a/arch/csr/mhpmcounter17.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 17 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter17h.yaml b/arch/csr/mhpmcounter17h.yaml deleted file mode 100644 index 5b08c91a4..000000000 --- a/arch/csr/mhpmcounter17h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 17 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter18.yaml b/arch/csr/mhpmcounter18.yaml deleted file mode 100644 index 9fcd5dc86..000000000 --- a/arch/csr/mhpmcounter18.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 18 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter18h.yaml b/arch/csr/mhpmcounter18h.yaml deleted file mode 100644 index 8ebd677b7..000000000 --- a/arch/csr/mhpmcounter18h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 18 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter19.yaml b/arch/csr/mhpmcounter19.yaml deleted file mode 100644 index 5697950c1..000000000 --- a/arch/csr/mhpmcounter19.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 19 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter19h.yaml b/arch/csr/mhpmcounter19h.yaml deleted file mode 100644 index 8a679eb00..000000000 --- a/arch/csr/mhpmcounter19h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 19 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter20.yaml b/arch/csr/mhpmcounter20.yaml deleted file mode 100644 index 314d7bb13..000000000 --- a/arch/csr/mhpmcounter20.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 20 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter20h.yaml b/arch/csr/mhpmcounter20h.yaml deleted file mode 100644 index f34d1e566..000000000 --- a/arch/csr/mhpmcounter20h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 20 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter21.yaml b/arch/csr/mhpmcounter21.yaml deleted file mode 100644 index f55d1a739..000000000 --- a/arch/csr/mhpmcounter21.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 21 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter21h.yaml b/arch/csr/mhpmcounter21h.yaml deleted file mode 100644 index 0dca43a2a..000000000 --- a/arch/csr/mhpmcounter21h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 21 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter22.yaml b/arch/csr/mhpmcounter22.yaml deleted file mode 100644 index f9b6698c5..000000000 --- a/arch/csr/mhpmcounter22.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 22 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter22h.yaml b/arch/csr/mhpmcounter22h.yaml deleted file mode 100644 index f8b0f5ec5..000000000 --- a/arch/csr/mhpmcounter22h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 22 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter23.yaml b/arch/csr/mhpmcounter23.yaml deleted file mode 100644 index b3bd95054..000000000 --- a/arch/csr/mhpmcounter23.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 23 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter23h.yaml b/arch/csr/mhpmcounter23h.yaml deleted file mode 100644 index 8f2d558ff..000000000 --- a/arch/csr/mhpmcounter23h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 23 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter24.yaml b/arch/csr/mhpmcounter24.yaml deleted file mode 100644 index ef6016b81..000000000 --- a/arch/csr/mhpmcounter24.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 24 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter24h.yaml b/arch/csr/mhpmcounter24h.yaml deleted file mode 100644 index 5824b1de5..000000000 --- a/arch/csr/mhpmcounter24h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 24 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter25.yaml b/arch/csr/mhpmcounter25.yaml deleted file mode 100644 index 9d993a29f..000000000 --- a/arch/csr/mhpmcounter25.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 25 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter25h.yaml b/arch/csr/mhpmcounter25h.yaml deleted file mode 100644 index 4b121919e..000000000 --- a/arch/csr/mhpmcounter25h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 25 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter26.yaml b/arch/csr/mhpmcounter26.yaml deleted file mode 100644 index 84de79d38..000000000 --- a/arch/csr/mhpmcounter26.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 26 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter26h.yaml b/arch/csr/mhpmcounter26h.yaml deleted file mode 100644 index 10ad37b2a..000000000 --- a/arch/csr/mhpmcounter26h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 26 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter27.yaml b/arch/csr/mhpmcounter27.yaml deleted file mode 100644 index 3e1cbae32..000000000 --- a/arch/csr/mhpmcounter27.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 27 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter27h.yaml b/arch/csr/mhpmcounter27h.yaml deleted file mode 100644 index aca5d92d5..000000000 --- a/arch/csr/mhpmcounter27h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 27 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter28.yaml b/arch/csr/mhpmcounter28.yaml deleted file mode 100644 index 195c8f9e0..000000000 --- a/arch/csr/mhpmcounter28.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 28 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter28h.yaml b/arch/csr/mhpmcounter28h.yaml deleted file mode 100644 index 2bc6d75a6..000000000 --- a/arch/csr/mhpmcounter28h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 28 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter29.yaml b/arch/csr/mhpmcounter29.yaml deleted file mode 100644 index acc3c3511..000000000 --- a/arch/csr/mhpmcounter29.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 29 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter29h.yaml b/arch/csr/mhpmcounter29h.yaml deleted file mode 100644 index 69dd6b9a7..000000000 --- a/arch/csr/mhpmcounter29h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 29 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter3.yaml b/arch/csr/mhpmcounter3.yaml deleted file mode 100644 index 6bc87b06d..000000000 --- a/arch/csr/mhpmcounter3.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 3 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter30.yaml b/arch/csr/mhpmcounter30.yaml deleted file mode 100644 index 876dee849..000000000 --- a/arch/csr/mhpmcounter30.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 30 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter30h.yaml b/arch/csr/mhpmcounter30h.yaml deleted file mode 100644 index 0ee2821f7..000000000 --- a/arch/csr/mhpmcounter30h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 30 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter31.yaml b/arch/csr/mhpmcounter31.yaml deleted file mode 100644 index 03a3d02f0..000000000 --- a/arch/csr/mhpmcounter31.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 31 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter31h.yaml b/arch/csr/mhpmcounter31h.yaml deleted file mode 100644 index f43937724..000000000 --- a/arch/csr/mhpmcounter31h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 31 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter3h.yaml b/arch/csr/mhpmcounter3h.yaml deleted file mode 100644 index 037949a53..000000000 --- a/arch/csr/mhpmcounter3h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 3 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter4.yaml b/arch/csr/mhpmcounter4.yaml deleted file mode 100644 index 1c90c0054..000000000 --- a/arch/csr/mhpmcounter4.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 4 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter4h.yaml b/arch/csr/mhpmcounter4h.yaml deleted file mode 100644 index 7b22a4beb..000000000 --- a/arch/csr/mhpmcounter4h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 4 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter5.yaml b/arch/csr/mhpmcounter5.yaml deleted file mode 100644 index 8c1e54d15..000000000 --- a/arch/csr/mhpmcounter5.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 5 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter5h.yaml b/arch/csr/mhpmcounter5h.yaml deleted file mode 100644 index 502f076da..000000000 --- a/arch/csr/mhpmcounter5h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 5 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter6.yaml b/arch/csr/mhpmcounter6.yaml deleted file mode 100644 index 50c684501..000000000 --- a/arch/csr/mhpmcounter6.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 6 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter6h.yaml b/arch/csr/mhpmcounter6h.yaml deleted file mode 100644 index 6a9741a6a..000000000 --- a/arch/csr/mhpmcounter6h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 6 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter7.yaml b/arch/csr/mhpmcounter7.yaml deleted file mode 100644 index a50fd259b..000000000 --- a/arch/csr/mhpmcounter7.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 7 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter7h.yaml b/arch/csr/mhpmcounter7h.yaml deleted file mode 100644 index d0d1a75a0..000000000 --- a/arch/csr/mhpmcounter7h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 7 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter8.yaml b/arch/csr/mhpmcounter8.yaml deleted file mode 100644 index b865c219d..000000000 --- a/arch/csr/mhpmcounter8.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 8 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter8h.yaml b/arch/csr/mhpmcounter8h.yaml deleted file mode 100644 index c0a3ce80f..000000000 --- a/arch/csr/mhpmcounter8h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 8 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter9.yaml b/arch/csr/mhpmcounter9.yaml deleted file mode 100644 index 414562331..000000000 --- a/arch/csr/mhpmcounter9.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 9 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounter9h.yaml b/arch/csr/mhpmcounter9h.yaml deleted file mode 100644 index cb527911c..000000000 --- a/arch/csr/mhpmcounter9h.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# this single template is used to generate all 29 of the mhpmcounter csrs -# <% hpm_num = 9 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmcounterNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmcounterN.layout b/arch/csr/mhpmcounterN.layout deleted file mode 100644 index e4e24967d..000000000 --- a/arch/csr/mhpmcounterN.layout +++ /dev/null @@ -1,46 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <% raise "'hpm_num' must be defined" if hpm_num.nil? %> - -<%= "mhpmcounter#{hpm_num}" %>: - long_name: Machine Hardware Performance Counter <%= hpm_num %> - address: <%= "0x" + (0xB00 + hpm_num).to_s(16).upcase %> - priv_mode: M - length: 64 - description: Programmable hardware performance counter. - definedBy: I - fields: - COUNT: - location: 63-0 - description: | - <%- if NUM_HPM_COUNTERS > (hpm_num - 3) -%> - Performance counter for event selected in `mhpmevent<%= hpm_num %>.EVENT`. - - Increments every time event occurs unless: - - * `mcountinhibit.HPM<%= hpm_num %>` <%- if ext?(:Smcdeleg) -%>or its alias `scountinhibit.HPM<%= hpm_num %>`<%- end -%> is set - <%- if ext?(:Sscofpmf) -%> - * `mhpmevent<%= hpm_num %>.MINH` is set and the current privilege level is M - <%- if ext?(:S) -%> - * `mhpmevent<%= hpm_num %>.SINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent<%= hpm_num %>..SINH`<%- end -%> is set and the current privilege level is (H)S - <%- end -%> - <%- if ext?(:U) -%> - * `mhpmevent<%= hpm_num %>.UINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent<%= hpm_num %>.SINH`<%- end -%> is set and the current privilege level is U - <%- end -%> - <%- if ext?(:H) -%> - * `mhpmevent<%= hpm_num %>.VSINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent<%= hpm_num %>.SINH`<%- end -%> is set and the current privilege level is VS - * `mhpmevent<%= hpm_num %>.VUINH` <%- if ext?(:Ssccfg) -%>or its alias `hpmevent<%= hpm_num %>.SINH`<%- end -%> is set and the current privilege level is VU - <%- end -%> - <%- end -%> - <%- else -%> - Unimplemented performance counter. Must be read-only 0 (access does not cause trap). - <%- end -%> - - .. - <%- if (NUM_HPM_COUNTERS > (hpm_num - 3)) -%> - type: RW - reset_value: UNDEFINED_LEGAL - <%- else -%> - type: RO - reset_value: 0 - <%- end -%> diff --git a/arch/csr/mhpmcounterNh.layout b/arch/csr/mhpmcounterNh.layout deleted file mode 100644 index 21075f757..000000000 --- a/arch/csr/mhpmcounterNh.layout +++ /dev/null @@ -1,26 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <% raise "'hpm_num' must be defined" if hpm_num.nil? %> - -<%= "mhpmcounter#{hpm_num}h" %>: - long_name: Machine Hardware Performance Counter <%= hpm_num %>, Upper half - address: <%= "0x" + (0xB80 + hpm_num).to_s(16).upcase %> - priv_mode: M - length: 32 - base: 32 - description: | - Upper half of mhpmcounter<%= hpm_num %>. - definedBy: I - fields: - COUNT: - location: 32-0 - alias: mhpmcounter.COUNT<%= hpm_num %>[63:32] - description: | - Upper bits of counter. - <%- if (NUM_HPM_COUNTERS > (hpm_num - 3)) -%> - type: RW - reset_value: UNDEFINED_LEGAL - <%- else -%> - type: RO - reset_value: 0 - <%- end -%> diff --git a/arch/csr/mhpmevent10.yaml b/arch/csr/mhpmevent10.yaml deleted file mode 100644 index e0af60c1c..000000000 --- a/arch/csr/mhpmevent10.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 10 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent10h.yaml b/arch/csr/mhpmevent10h.yaml deleted file mode 100644 index a2420280f..000000000 --- a/arch/csr/mhpmevent10h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 10 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent11.yaml b/arch/csr/mhpmevent11.yaml deleted file mode 100644 index 8aa152cc6..000000000 --- a/arch/csr/mhpmevent11.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 11 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent11h.yaml b/arch/csr/mhpmevent11h.yaml deleted file mode 100644 index 25925553c..000000000 --- a/arch/csr/mhpmevent11h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 11 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent12.yaml b/arch/csr/mhpmevent12.yaml deleted file mode 100644 index e8b66e47b..000000000 --- a/arch/csr/mhpmevent12.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 12 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent12h.yaml b/arch/csr/mhpmevent12h.yaml deleted file mode 100644 index 58a604feb..000000000 --- a/arch/csr/mhpmevent12h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 12 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent13.yaml b/arch/csr/mhpmevent13.yaml deleted file mode 100644 index e721b0e6d..000000000 --- a/arch/csr/mhpmevent13.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 13 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent13h.yaml b/arch/csr/mhpmevent13h.yaml deleted file mode 100644 index d8c3ff82f..000000000 --- a/arch/csr/mhpmevent13h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 13 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent14.yaml b/arch/csr/mhpmevent14.yaml deleted file mode 100644 index 2fa050871..000000000 --- a/arch/csr/mhpmevent14.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 14 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent14h.yaml b/arch/csr/mhpmevent14h.yaml deleted file mode 100644 index 244f18738..000000000 --- a/arch/csr/mhpmevent14h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 14 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent15.yaml b/arch/csr/mhpmevent15.yaml deleted file mode 100644 index 47cf077de..000000000 --- a/arch/csr/mhpmevent15.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 15 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent15h.yaml b/arch/csr/mhpmevent15h.yaml deleted file mode 100644 index 91fc5bba5..000000000 --- a/arch/csr/mhpmevent15h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 15 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent16.yaml b/arch/csr/mhpmevent16.yaml deleted file mode 100644 index 7dd525290..000000000 --- a/arch/csr/mhpmevent16.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 16 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent16h.yaml b/arch/csr/mhpmevent16h.yaml deleted file mode 100644 index 775603898..000000000 --- a/arch/csr/mhpmevent16h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 16 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent17.yaml b/arch/csr/mhpmevent17.yaml deleted file mode 100644 index 1f193e1d6..000000000 --- a/arch/csr/mhpmevent17.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 17 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent17h.yaml b/arch/csr/mhpmevent17h.yaml deleted file mode 100644 index 29231e3e2..000000000 --- a/arch/csr/mhpmevent17h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 17 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent18.yaml b/arch/csr/mhpmevent18.yaml deleted file mode 100644 index 1f6b2aedf..000000000 --- a/arch/csr/mhpmevent18.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 18 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent18h.yaml b/arch/csr/mhpmevent18h.yaml deleted file mode 100644 index f57fee2a8..000000000 --- a/arch/csr/mhpmevent18h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 18 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent19.yaml b/arch/csr/mhpmevent19.yaml deleted file mode 100644 index 1037f756a..000000000 --- a/arch/csr/mhpmevent19.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 19 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent19h.yaml b/arch/csr/mhpmevent19h.yaml deleted file mode 100644 index 789a667e9..000000000 --- a/arch/csr/mhpmevent19h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 19 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent20.yaml b/arch/csr/mhpmevent20.yaml deleted file mode 100644 index 37aeba23b..000000000 --- a/arch/csr/mhpmevent20.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 20 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent20h.yaml b/arch/csr/mhpmevent20h.yaml deleted file mode 100644 index 117605f01..000000000 --- a/arch/csr/mhpmevent20h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 20 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent21.yaml b/arch/csr/mhpmevent21.yaml deleted file mode 100644 index 1d02f671b..000000000 --- a/arch/csr/mhpmevent21.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 21 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent21h.yaml b/arch/csr/mhpmevent21h.yaml deleted file mode 100644 index 61f61a79c..000000000 --- a/arch/csr/mhpmevent21h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 21 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent22.yaml b/arch/csr/mhpmevent22.yaml deleted file mode 100644 index c97d92fce..000000000 --- a/arch/csr/mhpmevent22.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 22 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent22h.yaml b/arch/csr/mhpmevent22h.yaml deleted file mode 100644 index 35b8c688f..000000000 --- a/arch/csr/mhpmevent22h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 22 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent23.yaml b/arch/csr/mhpmevent23.yaml deleted file mode 100644 index 0b910c80e..000000000 --- a/arch/csr/mhpmevent23.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 23 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent23h.yaml b/arch/csr/mhpmevent23h.yaml deleted file mode 100644 index 4806141f7..000000000 --- a/arch/csr/mhpmevent23h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 23 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent24.yaml b/arch/csr/mhpmevent24.yaml deleted file mode 100644 index c1768b9ae..000000000 --- a/arch/csr/mhpmevent24.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 24 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent24h.yaml b/arch/csr/mhpmevent24h.yaml deleted file mode 100644 index fa015600c..000000000 --- a/arch/csr/mhpmevent24h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 24 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent25.yaml b/arch/csr/mhpmevent25.yaml deleted file mode 100644 index a0182638e..000000000 --- a/arch/csr/mhpmevent25.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 25 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent25h.yaml b/arch/csr/mhpmevent25h.yaml deleted file mode 100644 index cb13c7fd0..000000000 --- a/arch/csr/mhpmevent25h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 25 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent26.yaml b/arch/csr/mhpmevent26.yaml deleted file mode 100644 index b1f8e7079..000000000 --- a/arch/csr/mhpmevent26.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 26 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent26h.yaml b/arch/csr/mhpmevent26h.yaml deleted file mode 100644 index bf1144ac7..000000000 --- a/arch/csr/mhpmevent26h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 26 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent27.yaml b/arch/csr/mhpmevent27.yaml deleted file mode 100644 index 3fe6bd9e7..000000000 --- a/arch/csr/mhpmevent27.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 27 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent27h.yaml b/arch/csr/mhpmevent27h.yaml deleted file mode 100644 index 6b1d5dfb3..000000000 --- a/arch/csr/mhpmevent27h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 27 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent28.yaml b/arch/csr/mhpmevent28.yaml deleted file mode 100644 index 8159f66d3..000000000 --- a/arch/csr/mhpmevent28.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 28 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent28h.yaml b/arch/csr/mhpmevent28h.yaml deleted file mode 100644 index b43f10768..000000000 --- a/arch/csr/mhpmevent28h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 28 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent29.yaml b/arch/csr/mhpmevent29.yaml deleted file mode 100644 index 67f215ac7..000000000 --- a/arch/csr/mhpmevent29.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 29 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent29h.yaml b/arch/csr/mhpmevent29h.yaml deleted file mode 100644 index 91cca4376..000000000 --- a/arch/csr/mhpmevent29h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 29 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent3.yaml b/arch/csr/mhpmevent3.yaml deleted file mode 100644 index ea4f1472a..000000000 --- a/arch/csr/mhpmevent3.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 3 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent30.yaml b/arch/csr/mhpmevent30.yaml deleted file mode 100644 index ed9301333..000000000 --- a/arch/csr/mhpmevent30.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 30 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent30h.yaml b/arch/csr/mhpmevent30h.yaml deleted file mode 100644 index c5fbc0aac..000000000 --- a/arch/csr/mhpmevent30h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 30 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent31.yaml b/arch/csr/mhpmevent31.yaml deleted file mode 100644 index 197db702f..000000000 --- a/arch/csr/mhpmevent31.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 31 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent31h.yaml b/arch/csr/mhpmevent31h.yaml deleted file mode 100644 index 22d38ee9d..000000000 --- a/arch/csr/mhpmevent31h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 31 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent3h.yaml b/arch/csr/mhpmevent3h.yaml deleted file mode 100644 index ddd1f7d21..000000000 --- a/arch/csr/mhpmevent3h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 3 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent4.yaml b/arch/csr/mhpmevent4.yaml deleted file mode 100644 index 59e55f9b4..000000000 --- a/arch/csr/mhpmevent4.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 4 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent4h.yaml b/arch/csr/mhpmevent4h.yaml deleted file mode 100644 index 118010cb5..000000000 --- a/arch/csr/mhpmevent4h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 4 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent5.yaml b/arch/csr/mhpmevent5.yaml deleted file mode 100644 index ce0d4c42e..000000000 --- a/arch/csr/mhpmevent5.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 5 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent5h.yaml b/arch/csr/mhpmevent5h.yaml deleted file mode 100644 index b15909ba2..000000000 --- a/arch/csr/mhpmevent5h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 5 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent6.yaml b/arch/csr/mhpmevent6.yaml deleted file mode 100644 index 3df539e61..000000000 --- a/arch/csr/mhpmevent6.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 6 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent6h.yaml b/arch/csr/mhpmevent6h.yaml deleted file mode 100644 index 84277eeb1..000000000 --- a/arch/csr/mhpmevent6h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 6 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent7.yaml b/arch/csr/mhpmevent7.yaml deleted file mode 100644 index a3b86584e..000000000 --- a/arch/csr/mhpmevent7.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 7 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent7h.yaml b/arch/csr/mhpmevent7h.yaml deleted file mode 100644 index a7c9cdef9..000000000 --- a/arch/csr/mhpmevent7h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 7 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent8.yaml b/arch/csr/mhpmevent8.yaml deleted file mode 100644 index b0e2403ec..000000000 --- a/arch/csr/mhpmevent8.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 8 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent8h.yaml b/arch/csr/mhpmevent8h.yaml deleted file mode 100644 index 8eea061bf..000000000 --- a/arch/csr/mhpmevent8h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 8 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent9.yaml b/arch/csr/mhpmevent9.yaml deleted file mode 100644 index 87758e050..000000000 --- a/arch/csr/mhpmevent9.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 9 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmevent9h.yaml b/arch/csr/mhpmevent9h.yaml deleted file mode 100644 index c7eb172fd..000000000 --- a/arch/csr/mhpmevent9h.yaml +++ /dev/null @@ -1,6 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% hpm_num = 9 %> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/mhpmeventNh.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/mhpmeventN.layout b/arch/csr/mhpmeventN.layout deleted file mode 100644 index 6155b89b3..000000000 --- a/arch/csr/mhpmeventN.layout +++ /dev/null @@ -1,74 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% raise "'hpm_num' must be defined" if hpm_num.nil? %> - -<%= "mhpmevent#{hpm_num}" %>: - long_name: Machine Hardware Performance Counter <%= hpm_num %> Control - address: <%= "0x" + (0x320 + hpm_num).to_s(16).upcase %> - priv_mode: M - length: 64 - description: | - Programmable hardware performance counter event selector - <% if ext?(:Sscofpmf) %> and overflow/filtering control<% end %> - definedBy: I - fields: - <%- if NUM_HPM_COUNTERS <= (hpm_num - 3) -%> - UNUSED: - location: 63-0 - description: Event selector is not implemented. Entire CSR reads as 0. - type: RO - reset_value: 0 - <%- else -%> - OF: - location: 63 - description: | - Overflow status and interrupt disable. - - The OF bit is set when the corresponding hpmcounter overflows, and remains set until written by - software. Since hpmcounter values are unsigned values, overflow is defined as unsigned - overflow of the implemented counter bits. - - The OF bit is sticky; it stays set until explictly cleared by a CSR write. - - A Local Counter Overflow Interrupt (LCOFI) is generated when OF is clear and - mhpmcounter<%= hpm_num %> overflows. - type: RW-H - reset_value: 0 - definedBy: Sscofpmf - MINH: - location: 62 - description: When set, mhpmcounter<%= hpm_num %> does not increment while the hart in operating in M-mode. - type: RW - reset_value: 0 - definedBy: Sscofpmf - SINH: - location: 61 - description: When set, mhpmcounter<%= hpm_num %> does not increment while the hart in operating in (H)S-mode. - type: RW - reset_value: 0 - definedBy: [S, Sscofpmf] - UINH: - location: 60 - description: When set, mhpmcounter<%= hpm_num %> does not increment while the hart in operating in U-mode. - type: RW - reset_value: 0 - definedBy: [U, Sscofpmf] - VSINH: - location: 59 - description: When set, mhpmcounter<%= hpm_num %> does not increment while the hart in operating in VS-mode. - type: RW - reset_value: 0 - definedBy: [H, Sscofpmf] - VUINH: - location: 58 - description: When set, mhpmcounter<%= hpm_num %> does not increment while the hart in operating in VU-mode. - type: RW - reset_value: 0 - definedBy: [H, Sscofpmf] - EVENT: - location: <%= hpm_events.size.bit_length - 1 %>-0 - description: Event selector for performance counter `mhpmcounter<%= hpm_num %>`. - type: RW - reset_value: 0 # used when type is RW - <%- end -%> diff --git a/arch/csr/mhpmeventNh.layout b/arch/csr/mhpmeventNh.layout deleted file mode 100644 index 083159b2d..000000000 --- a/arch/csr/mhpmeventNh.layout +++ /dev/null @@ -1,82 +0,0 @@ - -# this single template is used to generate all 29 of the mhpmevent csrs - -# <% raise "'hpm_num' must be defined" if hpm_num.nil? %> - -<%= "mhpmevent#{hpm_num}h" %>: - long_name: Machine Hardware Performance Counter <%= hpm_num %> Control, High half - address: <%= "0x" + (0x720 + hpm_num).to_s(16).upcase %> - priv_mode: M - length: 32 - base: 32 - description: | - Alias of `mhpmevent<%= hpm_num %>`[63:32]. - - Introduced with the `Sscofpmf` extension. Prior to that, there was no way to access the upper - 32-bits of `mhpmevent#{hpm_num}`. - definedBy: Sscofpmf - fields: - <%- if NUM_HPM_COUNTERS <= (hpm_num - 3) -%> - UNUSED: - location: 31-0 - description: Event selector is not implemented. Entire CSR reads as 0. - type: RO - reset_value: 0 - <%- else -%> - OF: - location: 31 - alias: mhpmevent<%= hpm_num %>.OF - description: | - Alias of mhpmevent<%= hpm_num %>.OF. - type: RW-H - reset_value: UNDEFINED_LEGAL - definedBy: Sscofpmf - MINH: - location: 30 - alias: mhpmevent<%= hpm_num %>.MINH - description: | - Alias of mhpmevent<%= hpm_num %>.MINH. - type: RW - reset_value: UNDEFINED_LEGAL - definedBy: Sscofpmf - SINH: - location: 29 - alias: mhpmevent<%= hpm_num %>.SINH - description: | - Alias of mhpmevent<%= hpm_num %>.SINH. - type: RW - reset_value: UNDEFINED_LEGAL - definedBy: [S, Sscofpmf] - UINH: - location: 28 - alias: mhpmevent<%= hpm_num %>.UINH - description: | - Alias of mhpmevent<%= hpm_num %>.UINH. - type: RW - reset_value: 0 - definedBy: [U, Sscofpmf] - VSINH: - location: 27 - alias: mhpmevent<%= hpm_num %>.VSINH - description: | - Alias of mhpmevent<%= hpm_num %>.VSINH. - type: RW - reset_value: UNDEFINED_LEGAL - definedBy: [H, Sscofpmf] - VUINH: - location: 26 - alias: mhpmevent<%= hpm_num %>.VUINH - description: | - Alias of mhpmevent<%= hpm_num %>.VUINH. - type: RW - reset_value: UNDEFINED_LEGAL - definedBy: [H, Sscofpmf] - <%- if hpm_events.size.bit_length >= 32 -%> - EVENT: - location: <%= hpm_events.size.bit_length - 33 %>-0 - description: Event selector for performance counter `mhpmcounter<%= hpm_num %>`. - alias: mhpmevent<%= hpm_num %>.EVENT[<%= hpm_events.size.bit_length - 1 %>:32] - type: RW - reset_value: UNDEFINED_LEGAL - <%- end -%> - <%- end -%> diff --git a/arch/csr/mideleg.yaml b/arch/csr/mideleg.yaml index 6734dc9a3..5371ab041 100644 --- a/arch/csr/mideleg.yaml +++ b/arch/csr/mideleg.yaml @@ -5,11 +5,10 @@ mideleg: address: 0x303 priv_mode: M length: MXLEN - <%- if ext?(:S, "> 1.9.1") -%> - definedBy: S # after 1.9.1, mideleg does not exist whe S-mode is not implemented - <%- else -%> - definedBy: M - <%- end -%> + definedBy: + # after 1.9.1, mideleg does not exist whe S-mode is not implemented + - [S, "> 1.9.1"] + - [M, "< 1.0"] description: | Controls exception delegation from M-mode to HS/S-mode diff --git a/arch/csr/minstret.yaml b/arch/csr/minstret.yaml index 9484d6ed5..dac233929 100644 --- a/arch/csr/minstret.yaml +++ b/arch/csr/minstret.yaml @@ -3,7 +3,12 @@ minstret: long_name: Machine Instructions Retired Counter address: 0xB02 - description: Instructions retired counter + description: | + Counts the number of instructions retired by this hart from some arbitrary start point in the past. + + [NOTE] + Instructions that cause synchronous exceptions, including `ecall` and `ebreak`, are not + considered to retire and hence do not increment the `minstret` CSR. priv_mode: M length: 64 fields: @@ -14,7 +19,7 @@ minstret: Instructions retired counter. <%- if ext?(:Zicntr) -%> - Aliased as `instret.CYCLE`. + Aliased as `instret.COUNT`. <%- end -%> Increments every time an instruction retires unless: @@ -38,4 +43,5 @@ minstret: does not retire and does not cause `minstret.COUNT` to increment. reset_value: UNDEFINED_LEGAL affectedBy: [Zicntr, Smcntrpmf, Smcdeleg, Ssccfg] - definedBy: I \ No newline at end of file + definedBy: Zicntr + \ No newline at end of file diff --git a/arch/csr/minstreth.yaml b/arch/csr/minstreth.yaml index 0fbf6d63c..4e40c9916 100644 --- a/arch/csr/minstreth.yaml +++ b/arch/csr/minstreth.yaml @@ -21,4 +21,8 @@ minstreth: Upper half of `minstret`. reset_value: UNDEFINED_LEGAL affectedBy: [Zicntr, Smcntrpmf, Smcdeleg, Ssccfg] - definedBy: I \ No newline at end of file + write(csr_value): | + CSR[minstret] = {csr_value.COUNT[31:0], CSR[minstret][31:0]; + definedBy: Zicntr + sw_read(): | + return CSR[minstret][63:32]; \ No newline at end of file diff --git a/arch/csr/misa.yaml b/arch/csr/misa.yaml index 6c96ff025..d24e4b640 100644 --- a/arch/csr/misa.yaml +++ b/arch/csr/misa.yaml @@ -137,23 +137,26 @@ misa: location: 19 description: | Indicates support for the `S` (supervisor mode) extension. - type: RO + type(): | + return MUTABLE_MISA_S ? CsrFieldType::RW : CsrFieldType::RO; reset_value(): | return implemented?(ExtensionName::S) ? 1 : 0; U: location: 21 description: | Indicates support for the `U` (user mode) extension. - type: RO + type(): | + return MUTABLE_MISA_U ? CsrFieldType::RW : CsrFieldType::RO; reset_value(): | return implemented?(ExtensionName::U) ? 1 : 0; - # V: - # location: 22 - # description: | - # Indicates support for the `V` (vector) extension. - # type: RO - # reset_value(): | - # return implemented?(ExtensionName::V) ? 1 : 0; + V: + location: 22 + description: | + Indicates support for the `V` (vector) extension. + type: RO + reset_value: 0 # TODO + # reset_value(): | + # return implemented?(ExtensionName::V) ? 1 : 0; sw_read(): | return ( (CSR[misa].MXL << 62) | @@ -163,7 +166,7 @@ misa: (CSR[misa].M << 12) | (CSR[misa].I << 7) | (CSR[misa].H << 6) | - ((CSR[misa].A & CSR[misa].M & CSR[misa].F & CSR[misa].D;) << 5) | # 'G' + ((CSR[misa].A & CSR[misa].M & CSR[misa].F & CSR[misa].D) << 5) | # 'G' (CSR[misa].F << 4) | (CSR[misa].D << 3) | (CSR[misa].C << 2) | diff --git a/arch/csr/pmpaddr0.yaml b/arch/csr/pmpaddr0.yaml deleted file mode 100644 index 5e38f9ed0..000000000 --- a/arch/csr/pmpaddr0.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpaddr_num = 0 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpaddrN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpaddr1.yaml b/arch/csr/pmpaddr1.yaml deleted file mode 100644 index 2cf41204a..000000000 --- a/arch/csr/pmpaddr1.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpaddr_num = 1 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpaddrN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpaddr10.yaml b/arch/csr/pmpaddr10.yaml deleted file mode 100644 index c6d43deb0..000000000 --- a/arch/csr/pmpaddr10.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpaddr_num = 10 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpaddrN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpaddr11.yaml b/arch/csr/pmpaddr11.yaml deleted file mode 100644 index 91f3b79e0..000000000 --- a/arch/csr/pmpaddr11.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpaddr_num = 11 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpaddrN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpaddr12.yaml b/arch/csr/pmpaddr12.yaml deleted file mode 100644 index aac575760..000000000 --- a/arch/csr/pmpaddr12.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpaddr_num = 12 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpaddrN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpaddr13.yaml b/arch/csr/pmpaddr13.yaml deleted file mode 100644 index c6e57f387..000000000 --- a/arch/csr/pmpaddr13.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpaddr_num = 13 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpaddrN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpaddr14.yaml b/arch/csr/pmpaddr14.yaml deleted file mode 100644 index 563b860fc..000000000 --- a/arch/csr/pmpaddr14.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpaddr_num = 14 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpaddrN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpaddr15.yaml b/arch/csr/pmpaddr15.yaml deleted file mode 100644 index 0426af7ef..000000000 --- a/arch/csr/pmpaddr15.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpaddr_num = 15 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpaddrN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpaddr2.yaml b/arch/csr/pmpaddr2.yaml deleted file mode 100644 index cd19dfc83..000000000 --- a/arch/csr/pmpaddr2.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpaddr_num = 2 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpaddrN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpaddr3.yaml b/arch/csr/pmpaddr3.yaml deleted file mode 100644 index 16193fd5d..000000000 --- a/arch/csr/pmpaddr3.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpaddr_num = 3 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpaddrN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpaddr4.yaml b/arch/csr/pmpaddr4.yaml deleted file mode 100644 index 92d05b5e1..000000000 --- a/arch/csr/pmpaddr4.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpaddr_num = 4 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpaddrN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpaddr5.yaml b/arch/csr/pmpaddr5.yaml deleted file mode 100644 index 3d60679e5..000000000 --- a/arch/csr/pmpaddr5.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpaddr_num = 5 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpaddrN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpaddr6.yaml b/arch/csr/pmpaddr6.yaml deleted file mode 100644 index 7bf52f9d8..000000000 --- a/arch/csr/pmpaddr6.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpaddr_num = 6 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpaddrN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpaddr7.yaml b/arch/csr/pmpaddr7.yaml deleted file mode 100644 index 145de8cb7..000000000 --- a/arch/csr/pmpaddr7.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpaddr_num = 7 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpaddrN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpaddr8.yaml b/arch/csr/pmpaddr8.yaml deleted file mode 100644 index 50f7d73ce..000000000 --- a/arch/csr/pmpaddr8.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpaddr_num = 8 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpaddrN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpaddr9.yaml b/arch/csr/pmpaddr9.yaml deleted file mode 100644 index b9b094cf4..000000000 --- a/arch/csr/pmpaddr9.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpaddr_num = 9 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpaddrN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpaddrN.layout b/arch/csr/pmpaddrN.layout deleted file mode 100644 index 17adbdb07..000000000 --- a/arch/csr/pmpaddrN.layout +++ /dev/null @@ -1,51 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- raise "'pmpaddr_num' must be defined" if pmpaddr_num.nil? -%> -<%- - pmpcfg_num = (XLEN==32) ? (pmpaddr_num / 4) : ((pmpaddr_num / 8)*2) --%> - -<%= "pmpaddr#{pmpaddr_num}" %>: - long_name: PMP Address <%= pmpaddr_num %> - address: <%= "0x" + (0x3B0 + pmpaddr_num).to_s(16).upcase %> - priv_mode: M - length: <%= XLEN %> - description: PMP entry address - definedBy: I - <%- if pmpaddr_num < NUM_PMP_ENTRIES -%> - fields: - ADDR: - location: <%= PHYS_ADDR_WIDTH-3 %>-0 - description: | - Bits <%= PHYS_ADDR_WIDTH-1 %>:2 of the address specifier for PMP entry <%= pmpaddr_num %> - (or, if `pmp<%= pmpaddr_num+1 %>cfg.A` == TOR, for PMP entry <%= pmpaddr_num + 1 %>). - type: RW - reset_value: 0 - sw_read(): | - # when the mode is NAPOT and PMP_GRANULARITY >= 16, - # bits (PMP_GRANULARITY-4):0 must read as ones - if ((PMP_GRANULARITY >= 16) && - (CSR[pmpcfg<%= pmpcfg_num %>].pmp<%= pmpaddr_num %>cfg[4] == 1)) { - return CSR[pmpaddr<%= pmpaddr_num %>].ADDR | {PMP_GRANULARITY-3{1'b1}}; - - # when the mode is OFF or TOR and PMP_GRANULARITY >= 8, - # bits (PMP_GRANULARITY-3):0 must read as zeros - } else if ((PMP_GRANULARITY >= 8) && - (CSR[pmpcfg<%= pmpcfg_num %>].pmp<%= pmpaddr_num %>cfg[4] == 0)) { - Bits mask = {PMP_GRANULARITY-2{1'b1}}; - return CSR[pmpaddr<%= pmpaddr_num %>].ADDR & ~mask; - - # no modifications needed - } else { - return CSR[pmpaddr<%= pmpaddr_num %>].ADDR; - } - - <%- else -%> - fields: - ADDR: - location: <%= PHYS_ADDR_WIDTH-3 %>-0 - description: | - Read-only zero (not implemented) - type: RO - reset_value: 0 - <%- end -%> diff --git a/arch/csr/pmpcfg0.yaml b/arch/csr/pmpcfg0.yaml deleted file mode 100644 index b8fbda9fc..000000000 --- a/arch/csr/pmpcfg0.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpcfg_num = 0 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpcfgN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpcfg1.yaml b/arch/csr/pmpcfg1.yaml deleted file mode 100644 index 778c9e941..000000000 --- a/arch/csr/pmpcfg1.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpcfg_num = 1 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpcfgN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpcfg10.yaml b/arch/csr/pmpcfg10.yaml deleted file mode 100644 index 685ca62be..000000000 --- a/arch/csr/pmpcfg10.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpcfg_num = 10 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpcfgN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpcfg11.yaml b/arch/csr/pmpcfg11.yaml deleted file mode 100644 index de8f56a9b..000000000 --- a/arch/csr/pmpcfg11.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpcfg_num = 11 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpcfgN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpcfg12.yaml b/arch/csr/pmpcfg12.yaml deleted file mode 100644 index 42104b40e..000000000 --- a/arch/csr/pmpcfg12.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpcfg_num = 12 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpcfgN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpcfg13.yaml b/arch/csr/pmpcfg13.yaml deleted file mode 100644 index e0eba7742..000000000 --- a/arch/csr/pmpcfg13.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpcfg_num = 13 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpcfgN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpcfg14.yaml b/arch/csr/pmpcfg14.yaml deleted file mode 100644 index 48b188b87..000000000 --- a/arch/csr/pmpcfg14.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpcfg_num = 14 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpcfgN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpcfg15.yaml b/arch/csr/pmpcfg15.yaml deleted file mode 100644 index 5ba0b4745..000000000 --- a/arch/csr/pmpcfg15.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpcfg_num = 15 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpcfgN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpcfg2.yaml b/arch/csr/pmpcfg2.yaml deleted file mode 100644 index adfd1f3be..000000000 --- a/arch/csr/pmpcfg2.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpcfg_num = 2 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpcfgN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpcfg3.yaml b/arch/csr/pmpcfg3.yaml deleted file mode 100644 index ec68c5cdc..000000000 --- a/arch/csr/pmpcfg3.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpcfg_num = 3 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpcfgN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpcfg4.yaml b/arch/csr/pmpcfg4.yaml deleted file mode 100644 index 395d1ae38..000000000 --- a/arch/csr/pmpcfg4.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpcfg_num = 4 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpcfgN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpcfg5.yaml b/arch/csr/pmpcfg5.yaml deleted file mode 100644 index 5cc45353f..000000000 --- a/arch/csr/pmpcfg5.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpcfg_num = 5 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpcfgN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpcfg6.yaml b/arch/csr/pmpcfg6.yaml deleted file mode 100644 index fa72a4d58..000000000 --- a/arch/csr/pmpcfg6.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpcfg_num = 6 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpcfgN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpcfg7.yaml b/arch/csr/pmpcfg7.yaml deleted file mode 100644 index 8694531bc..000000000 --- a/arch/csr/pmpcfg7.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpcfg_num = 7 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpcfgN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpcfg8.yaml b/arch/csr/pmpcfg8.yaml deleted file mode 100644 index 573922aeb..000000000 --- a/arch/csr/pmpcfg8.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpcfg_num = 8 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpcfgN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpcfg9.yaml b/arch/csr/pmpcfg9.yaml deleted file mode 100644 index fb4fa925d..000000000 --- a/arch/csr/pmpcfg9.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- pmpcfg_num = 9 -%> - -<%= ERB.new(File.read("#{File.dirname(__FILE__)}/pmpcfgN.layout"), trim_mode: "-").result(binding) %> diff --git a/arch/csr/pmpcfgN.layout b/arch/csr/pmpcfgN.layout deleted file mode 100644 index 57a532695..000000000 --- a/arch/csr/pmpcfgN.layout +++ /dev/null @@ -1,82 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -# <%- raise "'pmpcfg_num' must be defined" if pmpcfg_num.nil? -%> - -# this single template is used to generate all of the pmpNcfg csrs - -<%- - entries_this_register_32 = [NUM_PMP_ENTRIES - pmpcfg_num*4, 4].min - entries_this_register_64 = [NUM_PMP_ENTRIES - (pmpcfg_num/2)*8, 8].min - entries_this_register = [XLEN == 32 ? entries_this_register_32 : entries_this_register_64, 0].max - - starting_entry_32 = pmpcfg_num*4 - starting_entry_64 = (pmpcfg_num/2)*8 - starting_entry = XLEN == 32 ? starting_entry_32 : starting_entry_64 --%> - -<%= "pmpcfg#{pmpcfg_num}" %>: - <%- if pmpcfg_num.odd? -%> - base: 32 # odd numbered pmpcfg registers do not exist in RV64 - <%- end -%> - long_name: PMP Configuration Register <%= pmpcfg_num %> - address: <%= "0x" + (0x3A0 + pmpcfg_num).to_s(16).upcase %> - priv_mode: M - length: <%= XLEN %> - description: PMP entry configuration - definedBy: I - <%- if entries_this_register <= 0 -%> - fields: {} - <%- else -%> - fields: - <%- entries_this_register.times do |i| -%> - pmp<%= starting_entry + i %>cfg: - location: <%= ((i+1)*8)-1 %>-<%= i*8 %> - description: | - *PMP configuration for entry <%= starting_entry + i %>* - - The bits are as follows: - - [%autowidth] - !=== - ! Name ! Location ! Description - - h! L ! <%= ((i+1)*8)-1 %> ! Locks the entry from further modification. Additionally, when set, PMP checks also apply to M-mode for the entry. - h! - ! <%= ((i+1)*8)-2 %>:<%= ((i+1)*8)-3 %> ! _Reserved_ Writes shall be ignored. - h! A ! <%= ((i+1)*8)-4 %>:<%= ((i+1)*8)-5 %> - a! Address matching mode. One of: - - * *OFF* (0) - Null region (disabled) - * *TOR* (1) - Top of range - <%- if PMP_GRANULARITY < 2 -%> - * *NA4* (2) - Naturally aligned four-byte region - <%- end -%> - * *NAPOT* (3) - Natrually aligned power of two - - <%- if PMP_GRANULARITY >= 2 -%> - Naturally aligned four-byte region, *NA4* (2), is not valid (not needed when the PMP granularity is larger than 4 bytes). - <%- end -%> - - h! X ! <%= ((i)*8)+2 %> ! When clear, instruction fetchs cause an `Access Fault` for the matching region and privilege mode. - h! W ! <%= ((i)*8)+1 %> ! When clear, stores and AMOs cause an `Access Fault` for the matching region and privilege mode. - h! R ! <%= ((i)*8)+0 %> ! When clear, loads cause an `Access Fault` for the matching region and privilege mode. - !=== - - The combination of R = 0, W = 1 is reserved. - type: RW-R - write(csr_value): | - if ((CSR[<%= "pmpcfg#{pmpcfg_num}" %>].pmp<%= starting_entry + i %>cfg & 0x80) == 0) { - # entry is not locked - if (!(((csr_value.pmp<%= starting_entry + i %>cfg & 0x1) == 0) && ((csr_value.pmp<%= starting_entry + i %>cfg & 0x2) == 0x2))) { - # not R = 0, W =1, which is reserved - if ((PMP_GRANULARITY < 2) || - ((csr_value.pmp<%= starting_entry + i %>cfg & 0x18) != 0x10)) { - # NA4 is not allowed when PMP granularity is larger than 4 bytes - return csr_value.pmp<%= starting_entry + i %>cfg; - } - } - } - # fall through: keep old value - return CSR[<%= "pmpcfg#{pmpcfg_num}" %>].pmp<%= starting_entry + i %>cfg; - reset_value: 0 - <%- end -%> - <%- end -%> \ No newline at end of file diff --git a/arch/csr/scause.yaml b/arch/csr/scause.yaml index 26c6f49ee..2efda8313 100644 --- a/arch/csr/scause.yaml +++ b/arch/csr/scause.yaml @@ -6,12 +6,13 @@ scause: long_name: Supervisor Cause address: 0x142 priv_mode: S - length: 64 + length: SXLEN description: Reports the cause of the latest exception. definedBy: S fields: INT: - location: 63 + location_rv32: 31 + location_rv64: 63 description: | Written by hardware when a trap is taken into S-mode. @@ -44,7 +45,8 @@ scause: } reset_value: UNDEFINED_LEGAL CODE: - location: <%= max_code.bit_length - 1 %>-0 + location_rv32: 30-0 + location_rv64: 62-0 description: | Written by hardware when a trap is taken into S-mode. diff --git a/arch/csr/scounteren.yaml b/arch/csr/scounteren.yaml deleted file mode 100644 index ee7002273..000000000 --- a/arch/csr/scounteren.yaml +++ /dev/null @@ -1,92 +0,0 @@ -# yaml-language-server: $schema=../../schemas/csr_schema.json - -scounteren: - long_name: Supervisor Counter Enable - address: 0x106 - priv_mode: M - length: 32 - description: | - Delegates control of the hardware performance-monitoring counters - to U-mode - definedBy: S # actually, defined by RV64, but must implement U-mode for this CSR to exist - fields: - CY: - location: 0 - description: | - When 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 - !=== - type: RW - reset_value: UNDEFINED_LEGAL - TM: - location: 1 - description: | - When set, the `time` CSR (an alias of memory-mapped `mtime`) is accessible to U-mode - <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.TM`)<% end %>. - - This bit is read-only 0 when `mcounteren.TM` is clear. - - Summary: - - !=== - ! `mcounteren.TM` ! `scounteren.TM` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL - IR: - location: 2 - description: | - When 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 - reset_value: UNDEFINED_LEGAL - <%- NUM_HPM_COUNTERS.times do |hpm_num| -%> - HPM<%= hpm_num + 3 %>: - location: <%= 3 + hpm_num %> - description: | - When set, the `hpmcounter<%= 3 + hpm_num %>` CSR (an alias of `mhpmcounter<%= 3 + hpm_num %>`) - is accessible to U-mode - <% if ext?(:H) %>(delegation to VS/VU mode is further handled by `hcounteren.TM`)<% end %>. - - - This bit is read-only 0 when `mcounteren.HPM<%= hpm_num + 3 %>` is clear. - - Summary: - - !=== - ! `mcounteren.HPM<%= hpm_num + 3 %>` ! `scounteren.HPM<%= hpm_num + 3 %>` behavior - - ! 0 ! read-only 0 - ! 1 ! writeable - !=== - - type: RW - reset_value: UNDEFINED_LEGAL - <%- end -%> diff --git a/arch/csr/sepc.yaml b/arch/csr/sepc.yaml index 6bf1deb7a..52dee583d 100644 --- a/arch/csr/sepc.yaml +++ b/arch/csr/sepc.yaml @@ -36,8 +36,8 @@ sepc: return csr_value & ~64'b1; reset_value: UNDEFINED_LEGAL sw_read(): | - if (implemented?(C) && CSR[misa].C == 1'b1) { - return CSR[sepc] & ~64'b3; + if (implemented?(ExtensionName::C) && CSR[misa].C == 1'b1) { + return CSR[sepc] & ~64'b1; } else { return CSR[sepc]; } diff --git a/arch/csr/vscause.yaml b/arch/csr/vscause.yaml index b99617d72..66689c0a2 100644 --- a/arch/csr/vscause.yaml +++ b/arch/csr/vscause.yaml @@ -7,7 +7,7 @@ vscause: address: 0x242 virtual_address: 0x142 priv_mode: VS - length: 64 + length: VSXLEN description: Reports the cause of the latest exception taken in VS-mode. definedBy: H fields: @@ -45,7 +45,8 @@ vscause: } reset_value: UNDEFINED_LEGAL CODE: - location: <%= max_code.bit_length - 1 %>-0 + location_rv32: 30-0 + location_rv64: 62-0 description: | Written by hardware when a trap is taken into VS-mode. diff --git a/arch/csr/vsepc.yaml b/arch/csr/vsepc.yaml index 834a0ca07..1fd95a8fe 100644 --- a/arch/csr/vsepc.yaml +++ b/arch/csr/vsepc.yaml @@ -37,8 +37,8 @@ vsepc: return csr_value & ~64'b1; reset_value: UNDEFINED_LEGAL sw_read(): | - if (implemented?(C) && CSR[misa].C == 1'b1) { - return CSR[sepc] & ~64'b3; + if (implemented?(ExtensionName::C) && CSR[misa].C == 1'b1) { + return CSR[sepc] & ~64'b1; } else { return CSR[sepc]; } diff --git a/arch/isa/globals.isa b/arch/isa/globals.isa index b144b756b..508ccac3b 100644 --- a/arch/isa/globals.isa +++ b/arch/isa/globals.isa @@ -157,6 +157,18 @@ builtin function implemented? { } } +builtin function read_hpm_counter { + returns Bits<64> + arguments Bits<5> N + description { + Returns the value of hpmcounterN. + + N must be between 3..31. + + hpmcounterN must be implemented. + } +} + # floating point register file U32 FLEN = implemented?(ExtensionName::D) ? 7'd64 : 7'd32; Bits f[32] = [0, 0, 0, 0, 0, 0, 0, 0, diff --git a/lib/arch_gen.rb b/backends/arch_gen/lib/arch_gen.rb similarity index 89% rename from lib/arch_gen.rb rename to backends/arch_gen/lib/arch_gen.rb index 5e61b9be2..ffb1f6459 100644 --- a/lib/arch_gen.rb +++ b/backends/arch_gen/lib/arch_gen.rb @@ -8,8 +8,8 @@ require "tilt" require "yaml" -require_relative "validate" -require_relative "arch_def" +require_relative "#{$lib}/validate" +require_relative "#{$lib}/arch_def" $root = Pathname.new(__FILE__).dirname.dirname.realpath if $root.nil? @@ -51,7 +51,6 @@ def initialize(config_name) raise "Config name (#{@params['NAME']}) in params.yaml does not match directory path (#{@name})" end - @opcode_data = YAML.load_file("#{$root}/ext/riscv-opcodes/instr_dict.yaml") @ext_gen_complete = false validate_config @@ -227,6 +226,7 @@ def env @env = Class.new @env.instance_variable_set(:@cfg, @cfg) + @env.instance_variable_set(:@params, @params) @env.instance_variable_set(:@arch_gen, self) # add each parameter, either as a method (lowercase) or constant (uppercase) @@ -259,22 +259,36 @@ def env @env.instance_exec do # method to check if a given extension (with an optional version number) is present # - # @param [String,Symbol] Name of the extension - # @param [String] Version string, as a Gem Requirement (https://guides.rubygems.org/patterns/#pessimistic-version-constraint) - # @return [Boolean] whether or not extension 'ext_name' is implemented in the config - def ext?(ext_name, ext_version = nil) - if ext_version.nil? + # @param ext_name [String,#to_s] Name of the extension + # @param ext_requirement [String, #to_s] Version string, as a Gem Requirement (https://guides.rubygems.org/patterns/#pessimistic-version-constraint) + # @return [Boolean] whether or not extension +ext_name+ meeting +ext_requirement+ is implemented in the config + def ext?(ext_name, ext_requirement = ">= 0") + if ext_requirement.nil? @cfg["extensions"].any? do |e| e[0] == ext_name.to_s end else - requirement = Gem::Requirement.create(ext_version) + requirement = Gem::Requirement.create(ext_requirement.to_s) @cfg["extensions"].any? do |e| e[0] == ext_name.to_s && requirement.satisfied_by?(Gem::Version.new(e[1])) end end end + # @return [Array] List of possible XLENs for any implemented mode + def possible_xlens + possible = [@params["XLEN"]] + possible << 32 if ext?('S') && [32, 3264].include?(@params["SXLEN"]) + possible << 64 if ext?('S') && [32, 3264].include?(@params["SXLEN"]) + possible << 32 if ext?('U') && [32, 3264].include?(@params["UXLEN"]) + possible << 64 if ext?('U') && [32, 3264].include?(@params["UXLEN"]) + possible << 32 if ext?('H') && [32, 3264].include?(@params["VSXLEN"]) + possible << 64 if ext?('H') && [32, 3264].include?(@params["VSXLEN"]) + possible << 32 if ext?('H') && [32, 3264].include?(@params["VUXLEN"]) + possible << 64 if ext?('H') && [32, 3264].include?(@params["VUXLEN"]) + possible.uniq + end + # insert a hyperlink to an object # At this point, we insert a placeholder since it will be up # to the backend to create a specific link @@ -517,42 +531,31 @@ def maybe_add_csr(csr_name, extra_env = {}) merged_path = gen_merged_def(:csr, arch_path, arch_overlay_path) # get the csr data (not including the name key), which is redundant at this point - csr_obj = YAML.load_file(merged_path)[csr_name] - - # filter fields to exclude any definedBy an extension not supported in this config - # csr_obj["fields"].select! do |field_name, field_data| - # field_data["name"] = field_name - # break true if field_data["definedBy"].nil? - # break false if !field_data["base"].nil? && field_data["base"] != @params["XLEN"] - - # field_defined_by = field_data["definedBy"] - # field_defined_by = [field_defined_by] unless field_defined_by.is_a?(Array) + csr_data = YAML.load_file(merged_path)[csr_name] + csr_data["name"] = csr_name + csr_data["fields"].each { |n, f| f["name"] = n } - # field_defined_by.each do |ext_name| - # break true if @cfg["extensions"].any? { |ext| ext[0] == ext_name } - # end - # false - # end - csr_obj["fields"].each { |n, f| f["name"] = n } - - # add the CSR, unless it is from an extension not supported in this config - csr_defined_by = csr_obj["definedBy"] - csr_defined_by = [csr_defined_by] unless csr_defined_by.is_a?(Array) # turn into an array if needed - - # add the name in just for convienence - csr_obj["name"] = csr_name + csr_yaml = YAML.dump({ csr_name => csr_data}) + begin + csr_data = @validator.validate_str(csr_yaml, type: :csr) + rescue Validator::ValidationError => e + warn "Instruction definition in #{merged_path} did not validate" + raise e + end + csr_obj = Csr.new(csr_data[csr_name]) belongs = - # check that the defining extension is implemented in the config - csr_defined_by.any? { |ext_name| !@cfg["extensions"].select { |ext| ext[0] == ext_name }.empty? } && - # and that we have the right base, if the CSR exists in only one - (csr_obj["base"].nil? || csr_obj["base"] == @params["XLEN"]) + csr_obj.exists_in_cfg?( + possible_xlens, + @cfg["extensions"].map { |e| ExtensionVersion.new(e[0], e[1]) } + ) + @implemented_csrs ||= [] @implemented_csrs << csr_name if belongs - gen_csr_path = @gen_dir / "arch" / "csr" / csr_obj["definedBy"] / "#{csr_name}.yaml" + gen_csr_path = @gen_dir / "arch" / "csr" / csr_obj.extension_requirements[0].name / "#{csr_name}.yaml" FileUtils.mkdir_p gen_csr_path.dirname - gen_csr_path.write YAML.dump({ csr_name => csr_obj }) + gen_csr_path.write csr_yaml end private :maybe_add_csr @@ -704,6 +707,26 @@ def interrupt_codes @interrupt_codes end + def possible_xlens + possible_xlens = [@params["XLEN"]] + if @cfg["extensions"].any? { |e| e[0] == "S" } + possible_xlens << 32 if [32, 3264].include?(@params["SXLEN"]) + possible_xlens << 64 if [64, 3264].include?(@params["SXLEN"]) + end + if @cfg["extensions"].any? { |e| e[0] == "U" } + possible_xlens << 32 if [32, 3264].include?(@params["UXLEN"]) + possible_xlens << 64 if [64, 3264].include?(@params["UXLEN"]) + end + if @cfg["extensions"].any? { |e| e[0] == "H" } + possible_xlens << 32 if [32, 3264].include?(@params["VSXLEN"]) + possible_xlens << 32 if [32, 3264].include?(@params["VUXLEN"]) + possible_xlens << 64 if [64, 3264].include?(@params["VSXLEN"]) + possible_xlens << 64 if [64, 3264].include?(@params["VUXLEN"]) + end + possible_xlens + end + private :possible_xlens + # add an instruction to the running list of instructions for this config if it should be included # # @param inst_name [#to_s] instruction name diff --git a/backends/arch_gen/tasks.rake b/backends/arch_gen/tasks.rake new file mode 100644 index 000000000..32dd72f43 --- /dev/null +++ b/backends/arch_gen/tasks.rake @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +# This file contains tasks related to the generation of a configured architecture specification + +require_relative "lib/arch_gen" + +ARCH_GEN_DIR = Pathname.new(__FILE__).dirname + +# stamp to indicate completion of Arch Gen for a given config +rule %r{#{$root}/\.stamps/arch-gen-.*\.stamp} => proc { |tname| + config_name = Pathname.new(tname).basename(".stamp").sub("arch-gen-", "") + arch_files = Dir.glob($root / "arch" / "**" / "*.yaml") + config_files = + Dir.glob($root / "cfgs" / config_name / "arch_overlay" / "**" / "*.yaml") + + [($root / "cfgs" / config_name / "params.yaml").to_s] + [ + "#{$root}/.stamps", + "#{ARCH_GEN_DIR}/lib/arch_gen.rb", + "#{$root}/lib/idl/ast.rb", + "#{ARCH_GEN_DIR}/tasks.rake", + "gen:arch" + ] + arch_files + config_files +} do |t| + config_name = Pathname.new(t.name).basename(".stamp").sub("arch-gen-", "") + + arch_gen = ArchGen.new(config_name) + puts "Generating architecture definition in #{arch_gen.gen_dir.relative_path_from($root)}" + + arch_gen.generate + + puts " Found #{arch_gen.implemented_csrs.size} CSRs" + puts " Found #{arch_gen.implemented_extensions.size} Extensions" + puts " Found #{arch_gen.implemented_instructions.size} Instructions" + + FileUtils.touch t.name +end + +namespace :gen do + desc "Generate the cfg-specific architecture files for config_name" + task :cfg_arch, [:config_name] do |_t, args| + raise "No config '#{args[:config_name]}' found in cfgs/" unless ($root / "cfgs" / args[:config_name]).directory? + + Rake::Task["#{$root}/.stamps/arch-gen-#{args[:config_name]}.stamp"].invoke(args[:config_name]) + end +end diff --git a/tasks/adoc_gen.rake b/backends/cfg_html_doc/adoc_gen.rake similarity index 62% rename from tasks/adoc_gen.rake rename to backends/cfg_html_doc/adoc_gen.rake index 0a4ae25d1..4a3a1eb68 100644 --- a/tasks/adoc_gen.rake +++ b/backends/cfg_html_doc/adoc_gen.rake @@ -1,28 +1,27 @@ # frozen_string_literal: true -require_relative "../lib/arch_def" - +# fill out templates for every csr, inst, ext, and func ["csr", "inst", "ext", "func"].each do |type| rule %r{#{$root}/\.stamps/adoc-gen-#{type}s-.*\.stamp} => proc { |tname| config_name = Pathname.new(tname).basename(".stamp").sub("adoc-gen-#{type}s-", "") [ "#{$root}/.stamps/arch-gen-#{config_name}.stamp", - ($root / "views" / "adoc" / "#{type}.adoc.erb").to_s, - "lib/arch_def.rb", - "lib/idl/passes/gen_adoc.rb", - "tasks/adoc_gen.rake", + "#{CFG_HTML_DOC_DIR}/templates/#{type}.adoc.erb", + "#{$root}/lib/arch_def.rb", + "#{$root}/lib/idl/passes/gen_adoc.rb", + __FILE__, "#{$root}/.stamps" ] } do |t| config_name = Pathname.new(t.name).basename(".stamp").sub("adoc-gen-#{type}s-", "") arch_def = ArchDef.new(config_name) - adoc_template_path = $root / "views" / "adoc" / "#{type}.adoc.erb" + adoc_template_path = CFG_HTML_DOC_DIR / "templates" / "#{type}.adoc.erb" adoc_template = adoc_template_path.read erb = ERB.new(adoc_template, trim_mode: "-") erb.filename = adoc_template_path.to_s - dir_path = $root / "gen" / config_name / "adoc" / "#{type}s" + dir_path = $root / "gen" / "cfg_html_doc" / config_name / "adoc" / "#{type}s" FileUtils.mkdir_p dir_path case type @@ -55,33 +54,6 @@ require_relative "../lib/arch_def" end end -# rule %r{#{$root}/\.stamps/adoc-gen-insts-.*\.stamp} => proc { |tname| -# config_name = Pathname.new(tname).basename(".stamp").sub("adoc-gen-insts-", "") -# [ -# "#{$root}/.stamps/arch-gen-#{config_name}.stamp", -# "lib/arch_def.rb", -# "tasks/adoc_gen.rake" -# ] -# } do |t| -# config_name = Pathname.new(t.name).basename(".stamp").sub("adoc-gen-insts-", "") - -# arch_def = ArchDef.new(config_name) -# inst_adoc_template_path = $root / "views" / "adoc" / "inst.adoc.erb" -# inst_adoc_template = inst_adoc_template_path.read -# erb = ERB.new(inst_adoc_template, trim_mode: "-") -# erb.filename = inst_adoc_template_path.to_s - -# dir_path = $root / "gen" / config_name / "adoc" / "insts" -# FileUtils.mkdir_p dir_path - -# arch_def.instructions.each do |inst| -# path = dir_path / "#{inst.name}.adoc" -# File.write(path, erb.result(binding)) -# end - -# FileUtils.touch(t.name) -# end - namespace :gen do desc "Generate Asciidoc source for config into gen/CONFIG_NAME/adoc" task :adoc, [:config_name] do |_t, args| diff --git a/tasks/html_gen.rake b/backends/cfg_html_doc/html_gen.rake similarity index 65% rename from tasks/html_gen.rake rename to backends/cfg_html_doc/html_gen.rake index e12d1413c..d7f0ff732 100644 --- a/tasks/html_gen.rake +++ b/backends/cfg_html_doc/html_gen.rake @@ -36,35 +36,35 @@ module AntoraUtils end ["csr", "inst", "ext", "func"].each do |type| - rule %r{#{$root}/gen/.*/antora/modules/#{type}s/pages/.*\.adoc} => proc { |tname| - config_name = Pathname.new(tname).relative_path_from("#{$root}/gen").to_s.split("/")[0] + rule %r{#{$root}/gen/cfg_html_doc/.*/antora/modules/#{type}s/pages/.*\.adoc} => proc { |tname| + config_name = Pathname.new(tname).relative_path_from("#{$root}/gen/cfg_html_doc").to_s.split("/")[0] [ "#{$root}/\.stamps/adoc-gen-#{type}s-#{config_name}\.stamp", __FILE__ ] } do |t| - config_name = Pathname.new(t.name).relative_path_from("#{$root}/gen").to_s.split("/")[0] - rest = Pathname.new(t.name).relative_path_from("#{$root}/gen/#{config_name}/antora/modules/#{type}s/pages") + config_name = Pathname.new(t.name).relative_path_from("#{$root}/gen/cfg_html_doc").to_s.split("/")[0] + rest = Pathname.new(t.name).relative_path_from("#{$root}/gen/cfg_html_doc/#{config_name}/antora/modules/#{type}s/pages") FileUtils.mkdir_p File.dirname(t.name) - src = $root / "gen" / config_name / "adoc" / "#{type}s"/ rest + src = $root / "gen" / "cfg_html_doc" / config_name / "adoc" / "#{type}s" / rest File.write t.name, AntoraUtils.resolve_links(src) end end -rule %r{#{$root}/gen/.*/antora/modules/nav.adoc} => proc { |tname| - config_name = Pathname.new(tname).relative_path_from("#{$root}/gen").to_s.split("/")[0] - Dir.glob("#{$root}/gen/#{config_name}/antora/modules/csrs/**/*.adoc") + - Dir.glob("#{$root}/gen/#{config_name}/antora/modules/insts/**/*.adoc") + - Dir.glob("#{$root}/gen/#{config_name}/antora/modules/exts/**/*.adoc") + +rule %r{#{$root}/gen/cfg_html_doc/.*/antora/modules/nav.adoc} => proc { |tname| + config_name = Pathname.new(tname).relative_path_from("#{$root}/gen/cfg_html_doc").to_s.split("/")[0] + Dir.glob("#{$root}/gen/cfg_html_doc/#{config_name}/antora/modules/csrs/**/*.adoc") + + Dir.glob("#{$root}/gen/cfg_html_doc/#{config_name}/antora/modules/insts/**/*.adoc") + + Dir.glob("#{$root}/gen/cfg_html_doc/#{config_name}/antora/modules/exts/**/*.adoc") + [ - "#{$root}/views/adoc/toc.adoc.erb", + "#{CFG_HTML_DOC_DIR}/templates/toc.adoc.erb", "#{$root}/.stamps/arch-gen-#{config_name}.stamp", __FILE__ ] } do |t| - config_name = Pathname.new(t.name).relative_path_from("#{$root}/gen").to_s.split("/")[0] + config_name = Pathname.new(t.name).relative_path_from("#{$root}/gen/cfg_html_doc").to_s.split("/")[0] - toc_path = $root / "views" / "adoc" / "toc.adoc.erb" + toc_path = CFG_HTML_DOC_DIR / "templates" / "toc.adoc.erb" erb = ERB.new(toc_path.read, trim_mode: "-") erb.filename = toc_path.to_s @@ -72,17 +72,17 @@ rule %r{#{$root}/gen/.*/antora/modules/nav.adoc} => proc { |tname| File.write t.name, AntoraUtils.resolve_links(erb.result(binding)) end -rule %r{#{$root}/gen/.*/antora/modules/ROOT/pages/config.adoc} => proc { |tname| - config_name = Pathname.new(tname).relative_path_from("#{$root}/gen").to_s.split("/")[0] +rule %r{#{$root}/gen/cfg_html_doc/.*/antora/modules/ROOT/pages/config.adoc} => proc { |tname| + config_name = Pathname.new(tname).relative_path_from("#{$root}/gen/cfg_html_doc").to_s.split("/")[0] [ - "#{$root}/views/adoc/config.adoc.erb", + "#{CFG_HTML_DOC_DIR}/templates/config.adoc.erb", "#{$root}/.stamps/arch-gen-#{config_name}.stamp", __FILE__ ] } do |t| - config_name = Pathname.new(t.name).relative_path_from("#{$root}/gen").to_s.split("/")[0] + config_name = Pathname.new(t.name).relative_path_from("#{$root}/gen/cfg_html_doc").to_s.split("/")[0] - config_path = $root / "views" / "adoc" / "config.adoc.erb" + config_path = CFG_HTML_DOC_DIR / "templates" / "config.adoc.erb" erb = ERB.new(config_path.read, trim_mode: "-") erb.filename = config_path.to_s @@ -91,14 +91,14 @@ rule %r{#{$root}/gen/.*/antora/modules/ROOT/pages/config.adoc} => proc { |tname| File.write t.name, AntoraUtils.resolve_links(erb.result(binding)) end -rule %r{#{$root}/gen/.*/antora/antora.yml} => proc { |tname| - config_name = Pathname.new(tname).relative_path_from("#{$root}/gen").to_s.split("/")[0] +rule %r{#{$root}/gen/cfg_html_doc/.*/antora/antora.yml} => proc { |tname| + config_name = Pathname.new(tname).relative_path_from("#{$root}/gen/cfg_html_doc").to_s.split("/")[0] [ - "#{$root}/gen/#{config_name}/antora/modules/nav.adoc", + "#{$root}/gen/cfg_html_doc/#{config_name}/antora/modules/nav.adoc", __FILE__ ] } do |t| - config_name = Pathname.new(t.name).relative_path_from("#{$root}/gen").to_s.split("/")[0] + config_name = Pathname.new(t.name).relative_path_from("#{$root}/gen/cfg_html_doc").to_s.split("/")[0] File.write t.name, <<~ANTORA_YML name: #{config_name} version: ~ @@ -107,14 +107,14 @@ rule %r{#{$root}/gen/.*/antora/antora.yml} => proc { |tname| ANTORA_YML end -rule %r{#{$root}/gen/.*/antora/playbook.yaml} => proc { |tname| - config_name = Pathname.new(tname).relative_path_from("#{$root}/gen").to_s.split("/")[0] +rule %r{#{$root}/gen/cfg_html_doc/.*/antora/playbook.yaml} => proc { |tname| + config_name = Pathname.new(tname).relative_path_from("#{$root}/gen/cfg_html_doc").to_s.split("/")[0] [ - "#{$root}/gen/#{config_name}/antora/antora.yml", + "#{$root}/gen/cfg_html_doc/#{config_name}/antora/antora.yml", __FILE__ ] } do |t| - config_name = Pathname.new(t.name).relative_path_from("#{$root}/gen").to_s.split("/")[0] + config_name = Pathname.new(t.name).relative_path_from("#{$root}/gen/cfg_html_doc").to_s.split("/")[0] File.write t.name, <<~PLAYBOOK site: @@ -122,7 +122,7 @@ rule %r{#{$root}/gen/.*/antora/playbook.yaml} => proc { |tname| content: sources: - url: #{$root} - start_path: gen/#{config_name}/antora + start_path: gen/cfg_html_doc/#{config_name}/antora antora: extensions: - '@antora/lunr-extension' @@ -156,9 +156,9 @@ end rule %r{#{$root}/\.stamps/html-gen-prose-.*\.stamp} => FileList[$root / "arch" / "prose" / "**" / "*"] do |t| config_name = Pathname.new(t.name).basename(".stamp").sub("html-gen-prose-", "") - FileUtils.rm_rf $root / "gen" / config_name / "antora" / "modules" / "prose" - FileUtils.mkdir_p $root / "gen" / config_name / "antora" / "modules" / "prose" - FileUtils.cp_r $root / "arch" / "prose", $root / "gen" / config_name / "antora" / "modules" / "prose" / "pages" + FileUtils.rm_rf $root / "gen" / "cfg_html_doc" / config_name / "antora" / "modules" / "prose" + FileUtils.mkdir_p $root / "gen" / "cfg_html_doc" / config_name / "antora" / "modules" / "prose" + FileUtils.cp_r $root / "arch" / "prose", $root / "gen" / "cfg_html_doc" / config_name / "antora" / "modules" / "prose" / "pages" Rake::Task["#{$root}/.stamps"].invoke @@ -180,18 +180,18 @@ rule %r{#{$root}/\.stamps/html-gen-.*\.stamp} => proc { |tname| config_name = Pathname.new(t.name).basename(".stamp").sub("html-gen-", "") ["csr", "inst", "ext", "func"].each do |type| - Dir.glob("#{$root}/gen/#{config_name}/adoc/#{type}s/**/*.adoc") do |f| - rest = Pathname.new(f).relative_path_from("#{$root}/gen/#{config_name}/adoc/#{type}s") + Dir.glob("#{$root}/gen/cfg_html_doc/#{config_name}/adoc/#{type}s/**/*.adoc") do |f| + rest = Pathname.new(f).relative_path_from("#{$root}/gen/cfg_html_doc/#{config_name}/adoc/#{type}s") dest_path = - $root / "gen" / config_name / "antora" / "modules" / "#{type}s" / "pages" / rest + $root / "gen" / "cfg_html_doc" / config_name / "antora" / "modules" / "#{type}s" / "pages" / rest Rake::Task[dest_path.to_s].invoke end end - Rake::Task[$root / "gen" / config_name / "antora" / "modules" / "nav.adoc"].invoke - Rake::Task[$root / "gen" / config_name / "antora" / "modules" / "ROOT" / "pages" / "config.adoc"].invoke - playbook_path = $root / "gen" / config_name / "antora" / "playbook.yaml" + Rake::Task[$root / "gen" / "cfg_html_doc" / config_name / "antora" / "modules" / "nav.adoc"].invoke + Rake::Task[$root / "gen" / "cfg_html_doc" / config_name / "antora" / "modules" / "ROOT" / "pages" / "config.adoc"].invoke + playbook_path = $root / "gen" / "cfg_html_doc" / config_name / "antora" / "playbook.yaml" Rake::Task[playbook_path].invoke sh [ @@ -199,29 +199,29 @@ rule %r{#{$root}/\.stamps/html-gen-.*\.stamp} => proc { |tname| "--stacktrace", "generate", "--cache-dir=#{$root}/.home/.antora", - "--to-dir=#{$root}/gen/#{config_name}/html", + "--to-dir=#{$root}/gen/cfg_html_doc/#{config_name}/html", "--log-level=all", "--fetch", playbook_path ].join(" ") end -namespace :gen do - desc <<~DESC - Generate HTML documentation for config(s). + namespace :gen do + desc <<~DESC + Generate HTML documentation for config(s). - Multiple configs may be specified as a comman-separated list. - Note, the list cannot contain spaces. - DESC - task :html, [:config_name] => "gen:adoc" do |_t, args| - configs = [args[:config_name]] - configs += args.extras unless args.extras.empty? + Multiple configs may be specified as a comman-separated list. + Note, the list cannot contain spaces. + DESC + task :html, [:config_name] => "gen:adoc" do |_t, args| + configs = [args[:config_name]] + configs += args.extras unless args.extras.empty? - configs.each do |config| - Rake::Task[($root / ".stamps" / "html-gen-#{config}.stamp")].invoke + configs.each do |config| + Rake::Task[($root / ".stamps" / "html-gen-#{config}.stamp")].invoke + end + end end - end -end namespace :serve do desc <<~DESC @@ -235,7 +235,7 @@ namespace :serve do Rake::Task["gen:html"].invoke(args[:config_name]) args.with_defaults(port: 8000) - html_dir = $root / "gen" / args[:config_name] / "html" + html_dir = $root / "gen" / "cfg_html_doc" / args[:config_name] / "html" Dir.chdir(html_dir) do require "webrick" diff --git a/backends/cfg_html_doc/tasks.rake b/backends/cfg_html_doc/tasks.rake new file mode 100644 index 000000000..3f31ece26 --- /dev/null +++ b/backends/cfg_html_doc/tasks.rake @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +require_relative "#{$lib}/arch_def" + +CFG_HTML_DOC_DIR = Pathname.new(__FILE__).dirname + +load "#{CFG_HTML_DOC_DIR}/adoc_gen.rake" +load "#{CFG_HTML_DOC_DIR}/html_gen.rake" diff --git a/views/adoc/config.adoc.erb b/backends/cfg_html_doc/templates/config.adoc.erb similarity index 100% rename from views/adoc/config.adoc.erb rename to backends/cfg_html_doc/templates/config.adoc.erb diff --git a/views/adoc/csr.adoc.erb b/backends/cfg_html_doc/templates/csr.adoc.erb similarity index 74% rename from views/adoc/csr.adoc.erb rename to backends/cfg_html_doc/templates/csr.adoc.erb index b6a17f509..6e3d7fbc8 100644 --- a/views/adoc/csr.adoc.erb +++ b/backends/cfg_html_doc/templates/csr.adoc.erb @@ -12,21 +12,21 @@ 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? -%> -h| Length | <%= csr.length_pretty %> +<%- if csr.dynamic_length?(arch_def) -%> +h| Length | <%= csr.length_pretty(arch_def) %> <%- else -%> -h| Length | <%= csr.length %>-bit +h| Length | <%= csr.length_pretty(arch_def) %>-bit <%- end -%> h| Privilege Mode | <%= csr.priv_mode %> |=== == Format -<%- unless csr.dynamic_length? || csr.fields.any? { |f| f.dynamic_location? } -%> +<%- 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(csr.arch_def.config_params["XLEN"]) %> +<%= JSON.dump csr.wavedrom_desc(arch_def, arch_def.config_params["XLEN"]) %> .... <%- else -%> <%# CSR has a dynamic length, or a field has a dynamic location, @@ -37,13 +37,13 @@ This CSR format changes dynamically. .<%= csr.name %> Format when <%= csr.length_cond32 %> [wavedrom, ,svg,subs='attributes',width="100%"] .... -<%= JSON.dump csr.wavedrom_desc(32) %> +<%= 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(64) %> +<%= JSON.dump csr.wavedrom_desc(arch_def, 64) %> .... @@ -51,18 +51,18 @@ This CSR format changes dynamically. == Fields -<%- if csr.fields.empty? -%> +<%- if csr.implemented_fields(arch_def).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 -%> [%autowidth,float="center",align="center",cols="^,<,<,<,<",options="header",role="stretch"] |==== |Name | Location | Type | Reset Value | Description -<%- csr.implemented_fields.each do |field| -%> +<%- csr.implemented_fields(arch_def).each do |field| -%> m| anchor:<%=csr.name%>-<%=field.name%>-def[] <%= field.name %> -| <%= field.location_pretty %> -| <%= field.type %> -| <%= field.reset_value %> +| <%= field.location_pretty(arch_def) %> +| <%= field.type(arch_def) %> +| <%= field.reset_value(arch_def) %> a| <%= arch_def.find_replace_links(field.description) %> <%- end -%> |==== @@ -95,7 +95,7 @@ This CSR may return a value that is different from what is stored in hardware. [subs="specialchars,macros"] ---- -<%= csr.sw_read_source %> +<%# csr.sw_read_ast(arch_def).prune(arch_def.sym_table.deep_clone).gen_adoc %> ---- <%- end -%> diff --git a/views/adoc/ext.adoc.erb b/backends/cfg_html_doc/templates/ext.adoc.erb similarity index 100% rename from views/adoc/ext.adoc.erb rename to backends/cfg_html_doc/templates/ext.adoc.erb diff --git a/views/adoc/func.adoc.erb b/backends/cfg_html_doc/templates/func.adoc.erb similarity index 100% rename from views/adoc/func.adoc.erb rename to backends/cfg_html_doc/templates/func.adoc.erb diff --git a/views/adoc/inst.adoc.erb b/backends/cfg_html_doc/templates/inst.adoc.erb similarity index 100% rename from views/adoc/inst.adoc.erb rename to backends/cfg_html_doc/templates/inst.adoc.erb diff --git a/views/adoc/toc.adoc.erb b/backends/cfg_html_doc/templates/toc.adoc.erb similarity index 100% rename from views/adoc/toc.adoc.erb rename to backends/cfg_html_doc/templates/toc.adoc.erb diff --git a/tasks/ext_pdf_gen.rake b/backends/ext_pdf_doc/tasks.rake similarity index 77% rename from tasks/ext_pdf_gen.rake rename to backends/ext_pdf_doc/tasks.rake index 7210aa26f..595e2c4e7 100644 --- a/tasks/ext_pdf_gen.rake +++ b/backends/ext_pdf_doc/tasks.rake @@ -5,7 +5,7 @@ require "pathname" require "asciidoctor-pdf" require "asciidoctor-diagram" -require_relative "../lib/idl/passes/gen_adoc" +require_relative "#{$lib}/idl/passes/gen_adoc" # Utilities for generating an Antora site out of an architecture def module AsciidocUtils @@ -46,33 +46,33 @@ module AsciidocUtils end end -rule %r{#{$root}/gen/.*/pdf/.*_extension\.pdf} => proc { |tname| - config_name = Pathname.new(tname).relative_path_from($root / "gen").to_s.split("/")[0] +rule %r{#{$root}/gen/ext_pdf_doc/.*/pdf/.*_extension\.pdf} => proc { |tname| + config_name = Pathname.new(tname).relative_path_from($root / "gen" / "ext_pdf_doc").to_s.split("/")[0] ext_name = Pathname.new(tname).basename(".pdf").to_s.split("_")[0..-2].join("_") [ - "#{$root}/gen/#{config_name}/adoc/#{ext_name}_extension.adoc" + "#{$root}/gen/ext_pdf_doc/#{config_name}/adoc/#{ext_name}_extension.adoc" ] } do |t| - config_name = Pathname.new(t.name).relative_path_from($root / "gen").to_s.split("/")[0] + config_name = Pathname.new(t.name).relative_path_from($root / "gen" / "ext_pdf_doc").to_s.split("/")[0] ext_name = Pathname.new(t.name).basename(".pdf").to_s.split("_")[0..-2].join("_") - adoc_file = "#{$root}/gen/#{config_name}/adoc/#{ext_name}_extension.adoc" + adoc_file = "#{$root}/gen/ext_pdf_doc/#{config_name}/adoc/#{ext_name}_extension.adoc" FileUtils.mkdir_p File.dirname(t.name) File.write t.name, Asciidoctor.convert_file(adoc_file, backend: "pdf", safe: :safe) end -rule %r{#{$root}/gen/.*/adoc/.*_extension\.adoc} => proc { |tname| - config_name = Pathname.new(tname).relative_path_from($root / "gen").to_s.split("/")[0] +rule %r{#{$root}/gen/ext_pdf_doc/.*/adoc/.*_extension\.adoc} => proc { |tname| + config_name = Pathname.new(tname).relative_path_from($root / "gen" / "ext_pdf_doc").to_s.split("/")[0] [ "#{$root}/.stamps/arch-gen-#{config_name}.stamp", - ($root / "views" / "adoc" / "ext_pdf.adoc.erb").to_s, + (EXT_PDF_DOC_DIR / "templates" / "ext_pdf.adoc.erb").to_s, __FILE__ ] } do |t| - config_name = Pathname.new(t.name).relative_path_from("#{$root}/gen").to_s.split("/")[0] + config_name = Pathname.new(t.name).relative_path_from("#{$root}/gen/ext_pdf_doc").to_s.split("/")[0] ext_name = Pathname.new(t.name).basename(".pdf").to_s.split("_")[0..-2].join("_") - template_path = $root / "views" / "adoc" / "ext_pdf.adoc.erb" + template_path = EXT_PDF_DOC_DIR / "templates" / "ext_pdf.adoc.erb" erb = ERB.new(template_path.read, trim_mode: "-") erb.filename = template_path.to_s @@ -82,6 +82,7 @@ rule %r{#{$root}/gen/.*/adoc/.*_extension\.adoc} => proc { |tname| File.write t.name, AsciidocUtils.resolve_links(erb.result(binding)) end + namespace :gen do desc <<~DESC Generate PDF documentation for :extension using configuration :config_name @@ -90,6 +91,6 @@ namespace :gen do config = args[:config_name] extension = args[:extension] - Rake::Task[$root / "gen" / config.to_s / "pdf" / "#{extension}_extension.pdf"].invoke + Rake::Task[$root / "gen" / "ext_pdf_doc" / config.to_s / "pdf" / "#{extension}_extension.pdf"].invoke end end diff --git a/views/adoc/ext_pdf.adoc.erb b/backends/ext_pdf_doc/templates/ext_pdf.adoc.erb similarity index 100% rename from views/adoc/ext_pdf.adoc.erb rename to backends/ext_pdf_doc/templates/ext_pdf.adoc.erb diff --git a/cfgs/config_validation.rb b/cfgs/config_validation.rb index 2af4f1061..40d428d3f 100644 --- a/cfgs/config_validation.rb +++ b/cfgs/config_validation.rb @@ -51,6 +51,18 @@ # 32 stands for ILEN below. Update this if/when instructions become longer than 32 assert(MTVAL_WIDTH >= [XLEN, 32].min) if REPORT_ENCODING_IN_MTVAL_ON_ILLEGAL_INSTRUCTION +assert(COUNTENABLE_EN[0] == false) unless ext?(:Zicntr) +assert(COUNTENABLE_EN[2] == false) unless ext?(:Zicntr) +(3..31).each do |hpm_num| + assert(COUNTENABLE_EN[hpm_num] == false) unless ext?(:Zihpm) && (NUM_HPM_COUNTERS > (hpm_num - 3)) +end + +assert(COUNTINHIBIT_EN[0] == false) unless ext?(:Zicntr) +assert(COUNTINHIBIT_EN[2] == false) unless ext?(:Zicntr) +(3..31).each do |hpm_num| + assert(COUNTINHIBIT_EN[hpm_num] == false) unless ext?(:Zihpm) && (NUM_HPM_COUNTERS > (hpm_num - 3)) +end + # check for conditionally required params require_param :MUTABLE_MISA_A if ext?(:A) require_param :MUTABLE_MISA_B if ext?(:B) diff --git a/cfgs/generic_rv64/params.yaml b/cfgs/generic_rv64/params.yaml index 5f9ef8b58..aa678fe51 100644 --- a/cfgs/generic_rv64/params.yaml +++ b/cfgs/generic_rv64/params.yaml @@ -39,35 +39,75 @@ params: - true # CY - false # empty - true # IR - - true # HPME3 - - true # HPME4 - - true # HPME5 - - true # HPME6 - - true # HPME7 - - true # HPME8 - - true # HPME9 - - true # HPME10 - - false # HPME11 - - false # HPME12 - - false # HPME13 - - false # HPME14 - - false # HPME15 - - false # HPME16 - - false # HPME17 - - false # HPME18 - - false # HPME19 - - false # HPME20 - - false # HPME21 - - false # HPME22 - - false # HPME23 - - false # HPME24 - - false # HPME25 - - false # HPME26 - - false # HPME27 - - false # HPME28 - - false # HPME29 - - false # HPME30 - - false # HPME31 + - 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 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: + - true # CY + - false # empty + - 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 # when true, writing an illegal value to a WLRL CSR field raises an Illegal Instruction exception # when false, writing an illegal value to a WLRL CSR field is ignored diff --git a/do b/do index 36a09719e..fead35697 100755 --- a/do +++ b/do @@ -3,10 +3,5 @@ ROOT=$(dirname $(realpath $BASH_SOURCE[0])) source $ROOT/bin/setup -# ROOT=$(dirname $(realpath $BASH_SOURCE[0])) -# export PATH=/pkg/qct/software/ruby/2.7.2/bin:/pkg/qct/software/llvm/15.0.5/bin:${PATH} -# if [ ! -d "${ROOT}/.gems" ]; then -# bundle install -# fi - -$BUNDLE exec --gemfile $ROOT/Gemfile rake -f $ROOT/tasks/top.rake $@ +# really long way of invoking rake, but renamed to 'do' +$BUNDLE exec --gemfile $ROOT/Gemfile ruby -r rake -e "Rake.application.init('do');Rake.application.load_rakefile;Rake.application.top_level" -- $@ diff --git a/lib/arch_def.rb b/lib/arch_def.rb index 5a60fa018..987fc5bc1 100644 --- a/lib/arch_def.rb +++ b/lib/arch_def.rb @@ -34,6 +34,8 @@ # is warranted, e.g., the CSR Field 'alias' returns a CsrFieldAlias object # instead of a simple string class ArchDefObject + attr_reader :data + # @param data [Hash] Hash with fields to be added def initialize(data) raise "Bad data" unless data.is_a?(Hash) @@ -51,6 +53,10 @@ def inspect # @return [Array] List of keys added by this ArchDefObject def keys = @data.keys + + # @param k (see Hash#key?) + # @return (see Hash#key?) + def key?(k) = @data.key?(k) # adds accessor functions for any properties in the data def method_missing(method_name, *args, &block) @@ -68,6 +74,69 @@ def method_missing(method_name, *args, &block) def respond_to_missing?(method_name, include_private = false) @data.key?(method_name.to_s) || super end + + # @overload defined_by?(ext_name, ext_version) + # @param ext_name [#to_s] An extension name + # @param ext_version [#to_s] A specific extension version + # @return [Boolean] Whether or not the instruction is defined by extesion `ext`, version `version` + # @overload defined_by?(ext_version) + # @param ext_version [ExtensionVersion] An extension version + # @return [Boolean] Whether or not the instruction is defined by ext_version + def defined_by?(*args) + if args.size == 1 + raise ArgumentError, "Parameter must be an ExtensionVersion" unless args[0].is_a?(ExtensionVersion) + + extension_requirements.any? do |r| + r.satisfied_by?(args[0]) + end + elsif args.size == 2 + raise ArgumentError, "First parameter must be an extension name" unless args[0].respond_to?(:to_s) + raise ArgumentError, "Second parameter must be an extension version" unless args[0].respond_to?(:to_s) + + extension_requirements.any? do |r| + r.satisfied_by?(args[0].to_s, args[1].to_s) + end + end + end + + def to_extension_requirement(obj) + if obj.is_a?(String) + ExtensionRequirement.new(obj, ">= 0") + else + ExtensionRequirement.new(*obj) + end + end + private :to_extension_requirement + + def extension_requirement?(obj) + obj.is_a?(String) && obj =~ /^([A-WY])|([SXZ][a-z]+)$/ || + obj.is_a?(Array) && obj[0] =~ /^([A-WY])|([SXZ][a-z]+)$/ + end + private :extension_requirement? + + # @return [Array] Extension requirements for the instruction. If *any* requirement is met, the instruction is defined + def extension_requirements + return @extension_requirements unless @extension_requirements.nil? + + @extension_requirements = [] + if @data["definedBy"].is_a?(Array) + # could be either a single extension with requirement, or a list of requirements + if extension_requirement?(@data["definedBy"][0]) + @extension_requirements << to_extension_requirement(@data["definedBy"][0]) + else + # this is a list + @data["definedBy"].each do |r| + @extension_requirements << to_extension_requirement(r) + end + end + else + @extension_requirements << to_extension_requirement(@data["definedBy"]) + end + + raise "empty requirements" if @extension_requirements.empty? + + @extension_requirements + end end # A CSR field object @@ -88,11 +157,15 @@ def initialize(parent_csr, field_data) @parent = parent_csr end - # @return [ArchDef] The owning ArchDef - def arch_def - @parent.arch_def + # @param possible_xlens [Array] List of xlens that be used in any implemented mode + # @param extensions [Array] List of extensions implemented + # @return [Boolean] whether or not the instruction is implemented given the supplies config options + def exists_in_cfg?(possible_xlens, extensions) + parent.exists_in_cfg?(possible_xlens, extensions) && + (@data["definedBy"].nil? || extensions.any? { |e| defined_by?(e) } ) end + # @param arch_def [ArchDef] A config # @return [String] # The type of the field. One of: # 'RO' => Read-only @@ -101,7 +174,7 @@ def arch_def # 'RW-R' => Read-write, with a restricted set of legal values # 'RW-H' => Read-write, with a hardware update # 'RW-RH' => Read-write, with a hardware update and a restricted set of legal values - def type + def type(arch_def) return @type unless @type.nil? @type = @@ -113,8 +186,8 @@ def type raise "type() is nil for #{csr.name}.#{name} #{@data}?" if idl.nil? expected_return_type = - Idl::Type.new(:enum_ref, enum_class: csr.sym_table.get("CsrFieldType")) - sym_table = csr.sym_table + Idl::Type.new(:enum_ref, enum_class: arch_def.sym_table.get("CsrFieldType")) + sym_table = arch_def.sym_table ast = arch_def.idl_compiler.compile_func_body( idl, @@ -124,6 +197,7 @@ def type parent: "#{csr.name}.#{name}" ) + sym_table = sym_table.deep_clone(clone_values: true) sym_table.push # for consistency with template functions begin @@ -188,17 +262,22 @@ def has_custom_write? # @return [Csr] Parent CSR for this field alias csr parent + # @param arch_def [ArchDef] A configuration # @return [Boolean] Whether or not the location of the field changes dynamically - # (e.g., based on mstatus.SXL) - def dynamic_location? - return false if @data.key?("location") - - csr.dynamic_length? + # (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) + end + end + false end + # @param arch_def [ArchDef] A config # @return [Idl::AstNode] Abstract syntax tree of the reset_value function # @raise StandardError if there is no reset_value function (i.e., the reset value is static) - def reset_value_func + def reset_value_func(arch_def) raise "Not an IDL value" unless @data.key?("reset_value()") return @reset_value_func unless @reset_value_func.nil? @@ -206,7 +285,7 @@ def reset_value_func @reset_value_func = arch_def.idl_compiler.compile_func_body( @data["reset_value()"], return_type: Idl::Type.new(:bits, width: 64), - symtab: csr.sym_table, + symtab: arch_def.sym_table, name: "reset_value", parent: "CSR[#{parent.name}].#{name}", input_file: "CSR[#{parent.name}].#{name}", @@ -214,12 +293,14 @@ def reset_value_func ) end + # @param arch_def [ArchDef] A config # @return [Integer] The reset value of this field # @return [String] The string 'UNDEFINED_LEGAL' if, for this config, there is no defined reset value - def reset_value + def reset_value(arch_def) return @reset_value unless @reset_value.nil? - symtab = arch_def.sym_table + symtab = arch_def.sym_table.deep_clone(clone_values: true) + raise "not at global scope" unless symtab.levels == 1 symtab.push # for consistency with template functions @@ -228,16 +309,17 @@ def reset_value if @data.key?("reset_value") @data["reset_value"] else - reset_value_func.return_value(arch_def.sym_table) + reset_value_func(arch_def).return_value(symtab) end ensure symtab.pop end end + # @param arch_def [ArchDef] A config. May be nil if the locaiton is not configturation-dependent # @param effective_xlen [Integer] The effective xlen, needed since some fields change location with XLEN. If the field location is not determined by XLEN, then this parameter can be nil # @return [Range] the location within the CSR as a range (single bit fields will be a range of size 1) - def location(effective_xlen = nil) + def location(arch_def, effective_xlen = nil) key = if @data.key?("location") "location" @@ -250,8 +332,8 @@ def location(effective_xlen = nil) raise "Missing location for #{csr.name}.#{name} (#{key})?" unless @data.key?(key) if @data[key].is_a?(Integer) - if @data[key] > csr.length(effective_xlen || @data["base"]) - raise "Location (#{@data[key]}) is past the csr length (#{csr.length(effective_xlen)}) in #{csr.name}.#{name}" + if @data[key] > csr.length(arch_def, effective_xlen || @data["base"]) + raise "Location (#{@data[key]}) is past the csr length (#{csr.length(arch_def, effective_xlen)}) in #{csr.name}.#{name}" end @data[key]..@data[key] @@ -259,8 +341,8 @@ def location(effective_xlen = nil) e, s = @data[key].split("-").map(&:to_i) raise "Invalid location" if s > e - if e > csr.length(effective_xlen) - raise "Location (#{@data[key]}) is past the csr length (#{csr.length(effective_xlen)}) in #{csr.name}.#{name}" + if e > csr.length(arch_def, effective_xlen) + raise "Location (#{@data[key]}) is past the csr length (#{csr.length(arch_def, effective_xlen)}) in #{csr.name}.#{name}" end s..e @@ -276,20 +358,21 @@ def base32_only? = @data.key?("base") && @data["base"] == 32 # @return [Boolean] Whether or not this field exists for any XLEN def defined_in_all_bases? = @data["base"].nil? + # @param arch_def [ArchDef] A config. May be nil if the width of the field is not configuration-dependent # @param effective_xlen [Integer] The effective xlen, needed since some fields change location with XLEN. If the field location is not determined by XLEN, then this parameter can be nil # @return [Integer] Number of bits in the field - def width(effective_xlen) - location(effective_xlen).size + def width(arch_def, effective_xlen) + location(arch_def, effective_xlen).size end # @return [String] Pretty-printed location string - def location_pretty + def location_pretty(arch_def) derangeify = proc { |loc| return loc.min.to_s if loc.size == 1 "#{loc.max}:#{loc.min}" } - if dynamic_location? + if dynamic_location?(arch_def) condition = case csr.priv_mode when "S" @@ -301,11 +384,11 @@ def location_pretty end <<~LOC - #{derangeify.call(location(32))} when #{condition.sub('%%', '0')} - #{derangeify.call(location(64))} when #{condition.sub('%%', '1')} + #{derangeify.call(location(arch_def, 32))} when #{condition.sub('%%', '0')} + #{derangeify.call(location(arch_def, 64))} when #{condition.sub('%%', '1')} LOC else - derangeify.call(location(csr.arch_def.config_params["XLEN"])) + derangeify.call(location(arch_def, arch_def.config_params["XLEN"])) end end @@ -347,25 +430,11 @@ def type_desc # CSR definition class Csr < ArchDefObject - # @return [ArchDef] The owning ArchDef - attr_reader :arch_def - - # @return [Idl::SymbolTable] The symbol table holding global names - attr_reader :sym_table - - # @param csr_data [Hash] Hash of data from the specification - # @param sym_table [Idl::SymbolTable] The symbol table holding global names - # @param arch_def [ArchDef] The architecture definition - def initialize(csr_data, sym_table, arch_def) - super(csr_data) - - @arch_def = arch_def - @sym_table = sym_table - end + # @param arch_def [ArchDef] A configuration # @return [Boolean] Whether or not the length of the CSR depends on a runtime value # (e.g., mstatus.SXL) - def dynamic_length? + def dynamic_length?(arch_def) return false if @data["length"].is_a?(Integer) case @data["length"] @@ -381,9 +450,10 @@ def dynamic_length? !@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) # @param effective_xlen [Integer] The effective xlen, needed since some fields change location with XLEN. If the field location is not determined by XLEN, then this parameter can be nil # @return [Integer] Length, in bits, of the CSR - def length(effective_xlen = nil) + def length(arch_def, effective_xlen = nil) case @data["length"] when "MXLEN" arch_def.config_params["XLEN"] @@ -415,6 +485,39 @@ def length(effective_xlen = nil) end end + # @return [Integer] The largest length of this CSR in any valid mode/xlen for the config + def max_length(arch_def) + case @data["length"] + when "MXLEN" + arch_def.config_params["XLEN"] + when "SXLEN" + if arch_def.config_params["SXLEN"] == 3264 + raise ArgumentError, "effective_xlen is required when length is dynamic (#{name})" if effective_xlen.nil? + + 64 + 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.config_params["SXLEN"].nil? + + arch_def.config_params["SXLEN"] + end + when "VSXLEN" + if arch_def.config_params["VSXLEN"] == 3264 + raise ArgumentError, "effective_xlen is required when length is dynamic (#{name})" if effective_xlen.nil? + + 64 + else + raise "CSR #{name} is not implemented" if arch_def.config_params["VSXLEN"].nil? + + arch_def.config_params["VSXLEN"] + end + when Integer + @data["length"] + else + raise "Unexpected length field for #{csr.name}" + end + end + # @return [String] IDL condition of when the effective xlen is 32 def length_cond32 case @data["length"] @@ -439,9 +542,10 @@ def length_cond64 end end + # @param arch_def [ArchDef] A configuration # @return [String] Pretty-printed length string - def length_pretty - if dynamic_length? + def length_pretty(arch_def) + if dynamic_length?(arch_def) cond = case @data["length"] when "SXLEN" @@ -453,11 +557,27 @@ def length_pretty end <<~LENGTH - #{length(32)} when #{cond.sub('%%', '0')} - #{length(64)} when #{cond.sub('%%', '1')} + #{length(arch_def, 32)} when #{cond.sub('%%', '0')} + #{length(arch_def, 64)} when #{cond.sub('%%', '1')} LENGTH else - "#{length}-bit" + "#{length(arch_def)}-bit" + end + end + + # list of modes that can potentially access the field + def modes_with_access + case @data["priv_mode"] + when "M" + ["M"] + when "S" + ["M", "S", "VS"] + when "U" + ["M", "S", "U", "VS", "VU"] + when "VS" + ["M", "S", "VS"] + else + raise "unexpected priv mode" end end @@ -468,44 +588,25 @@ def description_html Asciidoctor.convert description end - # @return [Array] All fields for this CSR, regardless of whether or not they are implemented - def fields - return @fields unless @fields.nil? - - @fields = [] - @data["fields"].each_value do |field_data| - @fields << CsrField.new(self, field_data) - end - @fields - end - + # @param arch_Def [ArchDef] A configuration # @return [Array] All implemented fields for this CSR at the given effective XLEN, sorted by location (smallest location first) # Excluded any fields that are defined by unimplemented extensions or a base that is not effective_xlen - def implemented_fields_for(effective_xlen) + def implemented_fields_for(arch_def, effective_xlen) @implemented_fields_for ||= {} - return @implemented_fields_for[effective_xlen] unless @implemented_fields_for[effective_xlen].nil? + key = [arch_def.name, effective_xlen].hash - @implemented_fields_for[effective_xlen] = [] - @data["fields"].each_value do |field_data| - next if field_data.key?("base") && (field_data["base"] != effective_xlen) + return @implemented_fields_for[key] unless @implemented_fields_for[key].nil? - defined_by = [] - defined_by << field_data["definedBy"] if field_data.key?("definedBy") && field_data["definedBy"].is_a?(String) - defined_by += field_data["definedBy"] if field_data.key?("definedBy") && field_data["definedBy"].is_a?(Array) - if !field_data.key?("definedBy") || (defined_by.any? { |ext_name| arch_def.ext?(ext_name) }) - @implemented_fields_for[effective_xlen] << CsrField.new(self, field_data) + @implemented_fields_for[key] = + implemented_fields(arch_def).select do |f| + !f.key?("base") || f.base == effective_xlen end - end - @implemented_fields_for[effective_xlen].sort! do |a, b| - a.location(effective_xlen).max <=> b.location(effective_xlen).max - end - - @implemented_fields_for[effective_xlen] end + # @param arch_def [ArchDef] A configuration # @return [Array] All implemented fields for this CSR # Excluded any fields that are defined by unimplemented extensions - def implemented_fields + def implemented_fields(arch_def) return @implemented_fields unless @implemented_fields.nil? implemented_bases = @@ -513,24 +614,21 @@ def implemented_fields arch_def.config_params["UXLEN"] == 3264 || arch_def.config_params["VSXLEN"] == 3264 || arch_def.config_params["VUXLEN"] == 3264 - [32,64] + [32, 64] else [arch_def.config_params["XLEN"]] end - @implemented_fields = [] - @data["fields"].each_value do |field_data| - next if field_data.key?("base") && implemented_bases.none?(field_data["base"]) - - defined_by = [] - defined_by << field_data["definedBy"] if field_data.key?("definedBy") && field_data["definedBy"].is_a?(String) - defined_by += field_data["definedBy"] if field_data.key?("definedBy") && field_data["definedBy"].is_a?(Array) - if !field_data.key?("definedBy") || (defined_by.any? { |ext_name| arch_def.ext?(ext_name) }) - @implemented_fields << CsrField.new(self, field_data) - end + @implemented_fields = fields.select do |f| + f.exists_in_cfg?(implemented_bases, arch_def.implemented_extensions) end + end - @implemented_fields + # @return [Array] All known fields of this CSR + def fields + return @fields unless @fields.nil? + + @fields = @data["fields"].map { |_field_name, field_data| CsrField.new(self, field_data) } end # @return [Hash] Hash of fields, indexed by field name @@ -557,14 +655,27 @@ def field(field_name) # @return [Boolean] true if the CSR has a custom sw_read function def has_custom_sw_read? - @data.key?("sw_read") && !sw_read.empty? + @data.key?("sw_read()") && !@data["sw_read()"].empty? end - # def sw_read_source - # return "" unless has_custom_sw_read? + def sw_read_ast(arch_def) + return @sw_read_ast unless @sw_read_ast.nil? + return nil if @data["sw_read()"].nil? + + # now, parse the function + + @sw_read_ast = arch_def.idl_compiler.compile_func_body( + @data["sw_read()"], + return_type: Idl::Type.new(:bits, width: 128), # big int to hold special return values + symtab: arch_def.sym_table, + name: "CSR[#{name}].sw_read()", + input_file: "CSR #{name}" + ) - # sw_read_ast.gen_adoc.gsub("((", '\((') - # end + raise "unexpected #{@sw_read_ast.class}" unless @sw_read_ast.is_a?(Idl::FunctionBodyAst) + + @sw_read_ast + end # @example Result for an I-type instruction # {reg: [ @@ -575,285 +686,40 @@ def has_custom_sw_read? # {bits: 12, name: 'imm12', attr: [''], type: 6} # ]} # + # @param arch_def [ArchDef] A configuration # @param effective_xlen [Integer,nil] Effective XLEN to use when CSR length is dynamic - # @return [String] A JSON representation of the WaveDrom drawing for the CSR - def wavedrom_desc(effective_xlen) + # @return [Hash] A representation of the WaveDrom drawing for the CSR (should be turned into JSON for wavedrom) + def wavedrom_desc(arch_def, effective_xlen) desc = { "reg" => [] } last_idx = -1 - implemented_fields_for(effective_xlen).each do |field| + implemented_fields_for(arch_def, effective_xlen).each do |field| - if field.location(effective_xlen).min != last_idx + 1 + if field.location(arch_def, effective_xlen).min != last_idx + 1 # have some reserved space - desc["reg"] << { "bits" => (field.location(effective_xlen).min - last_idx - 1), type: 1 } + desc["reg"] << { "bits" => (field.location(arch_def, effective_xlen).min - last_idx - 1), type: 1 } end - desc["reg"] << { "bits" => field.location(effective_xlen).size, "name" => field.name, type: 2 } - last_idx = field.location(effective_xlen).max + desc["reg"] << { "bits" => field.location(arch_def, effective_xlen).size, "name" => field.name, type: 2 } + last_idx = field.location(arch_def, effective_xlen).max end - if !implemented_fields_for(effective_xlen).empty? && (fields.last.location(effective_xlen).max != (length(effective_xlen) - 1)) + if !implemented_fields_for(arch_def, effective_xlen).empty? && (fields.last.location(arch_def, effective_xlen).max != (length(arch_def, effective_xlen) - 1)) # reserved space at the end - desc["reg"] << { "bits" => (length(effective_xlen) - 1 - last_idx), type: 1 } + desc["reg"] << { "bits" => (length(arch_def, effective_xlen) - 1 - last_idx), type: 1 } # desc['reg'] << { 'bits' => 1, type: 1 } end - desc["config"] = { "bits" => length(effective_xlen) } - desc["config"]["lanes"] = length(effective_xlen) / 16 + desc["config"] = { "bits" => length(arch_def, effective_xlen) } + desc["config"]["lanes"] = length(arch_def, effective_xlen) / 16 desc end -end -# really ugly way to generate fields out of riscv-opcodes -# hopefully this goes away soon -module RiscvOpcodes - VARIABLE_FIELDS = { - "rd" => { - bits: (7..11) - }, - "rd_p" => { - bits: (2..4), - lshift: 2, - display: "rd'", - decode_variable: "rd" - }, - "rd_n0" => { - bits: (7..11), - display: "rd != 0", - decode_variable: "rd" - }, - "rd_n2" => { - bits: (7..11), - display: "rd != {0,2}", - decode_variable: "rd" - }, - "rs1" => { - bits: (15..19) - }, - "rs1_p" => { - bits: (7..9), - lshift: 2, - display: "rs1'", - decode_variable: "rs1" - }, - "c_rs1_n0" => { - bits: (7..11), - display: "rs1 != 0", - decode_variable: "rs1" - }, - - "rs2" => { - bits: (20..24) - }, - "c_rs2" => { - bits: (2..6), - display: "rs2" - }, - "rs2_p" => { - bits: (2..4), - lshift: 2, - display: "rs2'", - decode_variable: "rs2" - }, - "c_rs2_n0" => { - bits: (2..6), - display: "rs2 != 0", - decode_variable: "rs2" - }, - "rd_rs1" => { - bits: (7..11), - display: "rs1/rd != 0", - decode_variable: ["rd", "rs1"] - }, - "rd_rs1_p" => { - bits: (7..9), - lshift: 2, - display: "rd'/rs1'", - decode_variable: ["rd", "rs1"] - }, - "rd_rs1_n0" => { - bits: (7..11), - display: "rd/rs1 != 0", - decode_variable: ["rd", "rs1"] - }, - "rs1_n0" => { - bits: (7..11), - display: "rs1 != 0", - decode_variable: "rs1" - }, - "shamtd" => { - bits: 20..25, - display: "shamt", - decode_variable: "shamt" - }, - "shamtw" => { - bits: 20..24, - display: "shamt", - decode_variable: "shamt" - }, - "csr" => { - bits: 20..31 - }, - "zimm" => { - bits: 15..19 - }, - "imm12" => { - bits: (20..31), - sext: true, - display: "imm[11:0]", - decode_variable: "imm" - }, - "imm20" => { - bits: (12..31), - lshift: 12, - sext: true, - display: "imm[31:20]", - decode_variable: "imm" - }, - "jimm20" => { - bits: [31, (12..19), 20, (21..30)], - group_by: 12..31, - lshift: 1, - sext: true, - display: "imm[20|10:1|11|19:12]", - decode_variable: "imm" - }, - ["bimm12hi", "bimm12lo"] => { - bits: [31, 7, (25..30), (8..11)], - group_by: [(25..31), (7..11)], - sext: true, - lshift: 1, - display: ["imm[12|10:5]", "imm[4:1|11]"], - decode_variable: "imm" - }, - ["imm12hi", "imm12lo"] => { - bits: [(25..31), (7..11)], - group_by: [(25..31), (7..11)], - sext: true, - display: ["imm[11:5]", "imm[4:0]"], - decode_variable: "imm" - }, - "pred" => { - bits: (24..27) - }, - "succ" => { - bits: (20..23) - }, - "fm" => { - bits: (28..31) - }, - - "c_nzuimm10" => { - bits: [(7..10), (11..12), 5, 6], - group_by: 5..12, - lshift: 2, - display: "nzuimm[5:4|9:6|2|3]", - decode_variable: "imm" - }, - ["c_uimm8lo", "c_uimm8hi"] => { - bits: [(5..6), (10..12)], - group_by: [(5..6), (10..12)], - lshift: 3, - display: ["uimm[7:6]", "uimm[5:3]"], - decode_variable: "imm" - }, - ["c_uimm7lo", "c_uimm7hi"] => { - bits: [5, (10..12), 6], - group_by: [(10..12), (5..6)], - lshift: 2, - display: ["uimm[5:3]", "uimm[2|6]"], - decode_variable: "imm" - }, - ["c_nzimm6hi", "c_nzimm6lo"] => { - bits: [12, (2..6)], - group_by: [12, (2..6)], - sext: true, - display: ["nzimm[5]", "nzimm[4:0]"], - decode_variable: "imm" - }, - ["c_nzuimm6hi", "c_nzuimm6lo"] => { - bits: [12, (2..6)], - group_by: [12, (2..6)], - display: ["nzuimm[5]", "nzuimm[4:0]"], - decode_variable: "imm" - }, - ["c_imm6hi", "c_imm6lo"] => { - bits: [12, (2..6)], - group_by: [12, (2..6)], - sext: true, - display: ["nzimm[5]", "nzimm[4:0]"], - decode_variable: "imm" - }, - ["c_nzimm10hi", "c_nzimm10lo"] => { - bits: [12, (3..4), 5, 2, 6], - group_by: [12, (2..6)], - lshift: 4, - sext: true, - display: ["nzimm[9]", "nzimm[4|6|8:7|5]"], - decode_variable: "imm" - }, - ["c_nzimm18hi", "c_nzimm18lo"] => { - bits: [12, (2..6)], - group_by: [12, (2..6)], - lshift: 12, - sext: true, - display: ["nzimm[17]", "nzimm[16:12]"], - decode_variable: "imm" - }, - "c_imm12" => { - bits: [12, 8, (9..10), 6, 7, 2, 11, (3..5)], - group_by: 2..12, - lshift: 1, - sext: true, - display: "imm[11|4|9:8|10|6|7|3:1|5]", - decode_variable: "imm" - }, - ["c_bimm9hi", "c_bimm9lo"] => { - bits: [12, (5..6), 2, (10..11), (3..4)], - group_by: [(10..12), (2..6)], - lshift: 1, - sext: true, - display: ["imm[8|4:3]", "imm[7:6|2:1|5]"], - decode_variable: "imm" - }, - ["c_uimm8sphi", "c_uimm8splo"] => { - bits: [(2..3), 12, (4..6)], - group_by: [12, (2..6)], - lshift: 2, - display: ["uimm5", "uimm[4:2|7:6]"], - decode_variable: "imm" - }, - "cuimm8sp_s" => { - bits: [(7..8), (9..12)], - group_by: (7..12), - lshift: 2, - display: "uimm[5:2|7:6]", - decode_variable: "imm" - }, - ["c_uimm9sphi", "c_uimm9splo"] => { - bits: [(2..3), 12, (4..6)], - group_by: [12, (2..6)], - lshift: 3, - display: ["uimm[5]", "uimm[4:3|8:6]"], - decode_variable: "imm" - }, - "c_uimm8sp_s" => { - bits: [(7..8), (9..12)], - group_by: 7..12, - lshift: 2, - display: "uimm[5:2|7:6]", - decode_variable: "imm" - }, - "c_uimm9sp_s" => { - bits: [(7..9), (10..12)], - group_by: 7..12, - lshift: 3, - display: "uimm[5:3|8:6]", - decode_variable: "imm" - }, - "rm" => { - bits: (12..14) - } - - }.freeze + # @param possible_xlens [Array] List of xlens that be used in any implemented mode + # @param extensions [Array] List of extensions implemented + # @return [Boolean] whether or not the instruction is implemented given the supplies config options + def exists_in_cfg?(possible_xlens, extensions) + (@data["base"].nil? || (possible_xlens.include? @data["base"])) && + extensions.any? { |e| defined_by?(e) } + end end # model of a specific instruction in a specific base (RV32/RV64) @@ -1061,21 +927,6 @@ def rv64? !@data.key?("base") || base == 64 end - def extension_requirement?(obj) - obj.is_a?(String) && obj =~ /^([A-WY])|([SXZ][a-z]+)$/ || - obj.is_a?(Array) && obj[0] =~ /^([A-WY])|([SXZ][a-z]+)$/ - end - private :extension_requirement? - - def to_extension_requirement(obj) - if obj.is_a?(String) - ExtensionRequirement.new(obj, ">= 0") - else - ExtensionRequirement.new(*obj) - end - end - private :to_extension_requirement - # @return [Array] Extension requirements for the instruction. If *any* requirement is met, the instruction is defined def extension_requirements return @extension_requirements unless @extension_requirements.nil? @@ -1124,30 +975,6 @@ def extension_exclusions @extension_exclusions end - # @overload defined_by?(ext_name, ext_version) - # @param ext_name [#to_s] An extension name - # @param ext_version [#to_s] A specific extension version - # @return [Boolean] Whether or not the instruction is defined by extesion `ext`, version `version` - # @overload defined_by?(ext_version) - # @param ext_version [ExtensionVersion] An extension version - # @return [Boolean] Whether or not the instruction is defined by ext_version - def defined_by?(*args) - if args.size == 1 - raise ArgumentError, "Parameter must be an ExtensionVersion" unless args[0].is_a?(ExtensionVersion) - - extension_requirements.any? do |r| - r.satisfied_by?(args[0]) - end - elsif args.size == 2 - raise ArgumentError, "First parameter must be an extension name" unless args[0].respond_to?(:to_s) - raise ArgumentError, "Second parameter must be an extension version" unless args[0].respond_to?(:to_s) - - extension_requirements.any? do |r| - r.satisfied_by?(args[0].to_s, args[1].to_s) - end - end - end - # @overload excluded_by?(ext_name, ext_version) # @param ext_name [#to_s] An extension name # @param ext_version [#to_s] A specific extension version @@ -1176,7 +1003,7 @@ def excluded_by?(*args) # @param extensions [Array] List of extensions implemented # @return [Boolean] whether or not the instruction is implemented given the supplies config options def exists_in_cfg?(possible_xlens, extensions) - (@data["base"].nil? || (possible_xlens.include?(@data["base"]))) && + (@data["base"].nil? || (possible_xlens.include? @data["base"])) && extensions.any? { |e| defined_by?(e) } && extensions.none? { |e| excluded_by?(e) } end @@ -1366,14 +1193,37 @@ def initialize(config_name) $root / "arch" / "isa" / "globals.isa", @sym_table ) + + @sym_table.deep_freeze end + def inspect = "ArchDef##{name}" + # @return [Boolean] true if this configuration can execute in multiple xlen environments # (i.e., that in some mode the effective xlen can be either 32 or 64, depending on CSR values) def multi_xlen? ["SXLEN", "UXLEN", "VSXLEN", "VUXLEN"].any? { |key| @config_params[key] == 3264 } end + # @param mode [String] One of ['M', 'S', 'U', 'VS', 'VU'] + # @return [Boolean] whether or not XLEN can change in the mode + def multi_xlen_in_mode?(mode) + case mode + when "M" + false + when "S" + @config_params["SXLEN"] == 3264 + when "U" + @config_params["UXLEN"] == 3264 + when "VS" + @config_params["VSXLEN"] == 3264 + when "VU" + @config_params["VUXLEN"] == 3264 + else + raise ArgumentError, "Bad mode" + end + end + # @return [Array] List of all extensions, with specific versions, that are implemented def implemented_extensions return @implemented_extensions unless @implemented_extensions.nil? @@ -1449,9 +1299,7 @@ def data def implemented_csrs return @implemented_csrs unless @implemented_csrs.nil? - @implemented_csrs = @arch_def["csrs"].select{ |csr_name, _csr_data| @arch_def["implemented_csrs"].include?(csr_name)}.map do |_csr_name, csr_data| - Csr.new(csr_data, @sym_table, self) - end + @implemented_csrs = csrs.select { |c| @arch_def["implemented_csrs"].include?(c.name) } end # @return [Array] List of all CSRs defined by RISC-V, whether or not they are implemented @@ -1459,7 +1307,7 @@ def csrs return @csrs unless @csrs.nil? @csrs = @arch_def["csrs"].map do |_csr_name, csr_data| - Csr.new(csr_data, @sym_table, self) + Csr.new(csr_data) end end @@ -1529,8 +1377,6 @@ def instruction_hash def implemented_instructions return @implemented_instructions unless @implemented_instructions.nil? - opcode_data = YAML.load_file("#{$root}/ext/riscv-opcodes/instr_dict.yaml") - @implemented_instructions = @arch_def["implemented_instructions"].map do |inst_name| instruction_hash[inst_name] end diff --git a/lib/idl.rb b/lib/idl.rb index c8e28bb41..f81859a3f 100644 --- a/lib/idl.rb +++ b/lib/idl.rb @@ -84,9 +84,7 @@ def compile_func_body(body, return_type: nil, symtab: SymbolTable.new, name: nil @parser.set_input_file(input_file, input_line) cloned_symtab = symtab.deep_clone - while cloned_symtab.levels != 1 - cloned_symtab.pop - end + raise "supplied symbol table is not at gloabl scope" unless cloned_symtab.levels == 1 m = @parser.parse(body, root: :function_body) if m.nil? diff --git a/lib/idl/ast.rb b/lib/idl/ast.rb index a06b5cca3..75127745d 100644 --- a/lib/idl/ast.rb +++ b/lib/idl/ast.rb @@ -303,6 +303,8 @@ def to_idl = raise NotImplementedError, "#{self.class.name} must implement to_id # reopen AstNode, and add functions class AstNode < Treetop::Runtime::SyntaxNode include AstNodeFuncs + + def inspect = self.class.name.to_s end # interface for nodes that can be executed, but don't have a value (e.g., statements) @@ -1185,11 +1187,11 @@ def type(symtab) Type.new(:bits, width: var.type(symtab).range(field_name.text_value).size) when :csr if field(symtab).defined_in_all_bases? - Type.new(:bits, width: [field(symtab).location(32).size, field(symtab).location(64).size].max) + Type.new(:bits, width: [field(symtab).location(symtab.archdef, 32).size, field(symtab).location(symtab.archdef, 64).size].max) elsif field(symtab).base64_only? - Type.new(:bits, width: field(symtab).location(64).size) + Type.new(:bits, width: field(symtab).location(symtab.archdef, 64).size) elsif field(symtab).base32_only? - Type.new(:bits, width: field(symtab).location(32).size) + Type.new(:bits, width: field(symtab).location(symtab.archdef, 32).size) else internal_error "Unexpected base for field" end @@ -1213,7 +1215,7 @@ def type_check(symtab) fields = var.type(symtab).csr.fields.select { |f| f.name == field_name.text_value } type_error "#{field_name.text_value} is not a field of CSR #{rval.type(symtab).csr.name}" unless fields.size == 1 - type_error "Cannot write to read-only CSR field" if ["RO", "RO-H"].any?(field(symtab).type) + type_error "Cannot write to read-only CSR field" if ["RO", "RO-H"].any?(field(symtab).type(symtab.archdef)) else type_error "Field assignment on type that is not a bitfield or csr (#{var.type(symtab)})" end @@ -1630,8 +1632,8 @@ def type(symtab) when :enum_ref Type.new(:bits, width: etype.enum_class.width) when :csr - type_error "Cannot $bits cast CSR #{etype.csr.name} because its length is dynamic" if etype.csr.dynamic_length? - Type.new(:bits, width: etype.csr.length) + type_error "Cannot $bits cast CSR #{etype.csr.name} because its length is dynamic" if etype.csr.dynamic_length?(symtab.archdef) + Type.new(:bits, width: etype.csr.length(symtab.archdef)) end end @@ -4122,7 +4124,7 @@ def csr_name(symtab) end def field_def(symtab) - csr_def(symtab).implemented_fields.find { |f| f.name == csr_field_name.text_value } + csr_def(symtab).implemented_fields(symtab.archdef).find { |f| f.name == csr_field_name.text_value } end def field_name(symtab) @@ -4142,11 +4144,11 @@ def to_idl def type(symtab) fd = field_def(symtab) if fd.defined_in_all_bases? - Type.new(:bits, width: [fd.width(32), fd.width(64)].max) + Type.new(:bits, width: [fd.width(symtab.archdef, 32), fd.width(symtab.archdef, 64)].max) elsif fd.base64_only? - Type.new(:bits, width: fd.width(64)) + Type.new(:bits, width: fd.width(symtab.archdef, 64)) elsif fd.base32_only? - Type.new(:bits, width: fd.width(32)) + Type.new(:bits, width: fd.width(symtab.archdef, 32)) else internal_error "unexpected field base" end @@ -4154,8 +4156,8 @@ def type(symtab) # @!macro value def value(symtab) - value_error "'#{csr_name(symtab)}.#{field_name(symtab)}' is not RO" unless field_def(symtab).type == "RO" - field_def(symtab).reset_value + value_error "'#{csr_name(symtab)}.#{field_name(symtab)}' is not RO" unless field_def(symtab).type(symtab.archdef) == "RO" + field_def(symtab).reset_value(symtab.archdef) end end @@ -4172,7 +4174,7 @@ def type(symtab) # treat this as a generic Type.new(:bits, width: archdef.config_params["XLEN"]) else - CsrType.new(cd) + CsrType.new(cd, archdef) end end @@ -4235,7 +4237,7 @@ def value(symtab) cd = csr_def(symtab) value_error "CSR number not knowable" if cd.nil? value_error "CSR is not implemented" unless symtab.archdef.implemented_csrs.any? { |icsr| icsr.name == cd.name } - cd.fields.each { |f| value_error "#{csr_name(symtab)}.#{f.name} not RO" unless f.type == "RO" } + cd.fields.each { |f| value_error "#{csr_name(symtab)}.#{f.name} not RO" unless f.type(symtab.archdef) == "RO" } csr_def(symtab).fields.reduce(0) { |val, f| val | (f.value << f.location.begin) } end @@ -4351,7 +4353,7 @@ def csr_def(symtab) # @!macro type def type(symtab) - CsrType.new(csr_def(symtab)) + CsrType.new(csr_def(symtab), symtab.archdef) end def name(symtab) diff --git a/lib/idl/symbol_table.rb b/lib/idl/symbol_table.rb index f91bdddce..9a60fdc08 100644 --- a/lib/idl/symbol_table.rb +++ b/lib/idl/symbol_table.rb @@ -145,6 +145,16 @@ def initialize(arch_def) add!('ExtensionName', EnumerationType.new('ExtensionName', arch_def.extensions.map(&:name), Array.new(arch_def.extensions.size) { |i| i + 1 })) end + # do a deep freeze to protect the sym table and all its entries from modification + def deep_freeze + @scopes.each do |k, v| + k.freeze + v.freeze + end + @scopes.freeze + freeze + end + # pushes a new scope def push # puts "push #{caller[0]}" diff --git a/lib/idl/type.rb b/lib/idl/type.rb index 87d7dce7f..8d1972f7a 100644 --- a/lib/idl/type.rb +++ b/lib/idl/type.rb @@ -94,15 +94,9 @@ def initialize(kind, qualifiers: [], width: nil, sub_type: nil, name: nil, tuple raise 'CSR type must have a csr argument' if csr.nil? @csr = csr + raise "CSR types must have a width" if width.nil? - raise 'CSR types get width from csr argument; width should not be specified' unless width.nil? || width == csr.length - - @width = - if csr.dynamic_length? - nil - else - csr.length - end + @width = width end end @@ -226,7 +220,7 @@ def convertable_to?(type) return false end when :csr - return (type.kind == :csr && type.csr.name == @csr.name) || type.convertable_to?(Type.new(:bits, width: @csr.length)) + return (type.kind == :csr && type.csr.name == @csr.name) || type.convertable_to?(Type.new(:bits, width:)) when :bitfield if (type.kind == :bitfield && name == type.name) return true @@ -419,8 +413,8 @@ def clone class CsrType < Type attr_reader :csr - def initialize(csr, qualifiers: []) - super(:csr, name: csr.name, csr: csr, qualifiers: qualifiers) + def initialize(csr, arch_def, qualifiers: []) + super(:csr, name: csr.name, csr: csr, width: csr.max_length(arch_def), qualifiers: qualifiers) end def fields diff --git a/lib/validate.rb b/lib/validate.rb index c821f092a..9d2f4bb30 100644 --- a/lib/validate.rb +++ b/lib/validate.rb @@ -139,13 +139,14 @@ def validate(path, type: nil) when %r{.*arch/arch_def\.yaml$} type = :arch when %r{.*arch/inst/.*/.*\.yaml$} - type = :instruction - when %r{.*arch/ext/.*/.*\.yaml$} + type = :inst + when %r{.*arch/ext/.*\.yaml$} type = :ext - when %r{.*arch/csr/.*/.*\.yaml$} + when %r{.*arch/csr/.*\.yaml$} type = :csr else - raise "Cannot determine type from YAML path '#{path}'" + warn "Cannot determine type from YAML path '#{path}'; skipping" + return end end begin diff --git a/schemas/config_schema.json b/schemas/config_schema.json index 9374a40dd..39e7a2012 100644 --- a/schemas/config_schema.json +++ b/schemas/config_schema.json @@ -157,6 +157,24 @@ "minItems": 32, "maxItems": 32 }, + "COUNTENABLE_EN": { + "type": "array", + "description": "Indicates which counters can be delegate from mcounteren\n\n Formatted as a one-hot enable vector so that, for example, COUNTENABLE_EN[0] is for CY and COUNTENABLE_EN[3] is for HPM3", + "items": [ + { + "type": "boolean" + }, + { + "const": false, + "$comment": "There is no counter at index 1" + } + ], + "additionalItems": { + "type": "boolean" + }, + "minItems": 32, + "maxItems": 32 + }, "TRAP_ON_ILLEGAL_WLRL": { "type": "boolean", "default": true, diff --git a/schemas/csr_schema.json b/schemas/csr_schema.json index 5b5be2907..072aeb8e3 100644 --- a/schemas/csr_schema.json +++ b/schemas/csr_schema.json @@ -97,16 +97,12 @@ "definedBy": { "oneOf": [ { - "type": "string", - "pattern": "^([A-WY]|([SXZ][a-z]+))$", - "description": "An extension name" + "$ref": "schema_defs.json#/$defs/extension_requirement" }, { "type": "array", "items": { - "type": "string", - "pattern": "^([A-WY]|([SXZ][a-z]+))$", - "description": "An extension name" + "$ref": "schema_defs.json#/$defs/extension_requirement" } } ], @@ -207,8 +203,18 @@ "description": "A full Asciidoc description of the CSR, indended to be used as documentation." }, "definedBy": { - "$ref": "schema_defs.json#/$defs/extension_name", - "description": "The extension that defines this CSR." + "oneOf": [ + { + "$ref": "schema_defs.json#/$defs/extension_requirement" + }, + { + "type": "array", + "items": { + "$ref": "schema_defs.json#/$defs/extension_requirement" + } + } + ], + "description": "Extension(s) that define the CSR" }, "address": { "type": "integer", diff --git a/tasks/arch_gen.rake b/tasks/arch_gen.rake deleted file mode 100644 index eb9c84ea9..000000000 --- a/tasks/arch_gen.rake +++ /dev/null @@ -1,100 +0,0 @@ -# frozen_string_literal: true - -# This file contains tasks related to the generation of a configured architecture specification - -require_relative File.join("..", "lib", "arch_gen.rb") - -# checkout riscv-opcodes submodule, if needed -file "ext/riscv-opcodes/parse.py" do - "git submodule update --init ext/riscv-opcodes" -end - -# setup python venv, needed to use pip with Ubuntu's python install -file "ext/riscv-opcodes/.venv/bin/pip" => "ext/riscv-opcodes/parse.py" do - Dir.chdir "#{$root}/ext/riscv-opcodes" do - sh "python3 -m venv #{$root}/ext/riscv-opcodes/.venv" - end -end - -# run pip to install riscv-opcodes python dependencies -file "ext/riscv-opcodes/.venv/lib/python3.12/site-packages/yaml/__init__.py" => "ext/riscv-opcodes/.venv/bin/pip" do - Dir.chdir "#{$root}/ext/riscv-opcodes" do - sh "#{$root}/ext/riscv-opcodes/.venv/bin/pip install -r requirements.txt" - end -end - -# generate the instruction dictionary from riscv-opcodes -file "ext/riscv-opcodes/instr_dict.yaml" => "ext/riscv-opcodes/.venv/lib/python3.12/site-packages/yaml/__init__.py" do - Dir.chdir "#{$root}/ext/riscv-opcodes" do - sh "#{$root}/ext/riscv-opcodes/.venv/bin/python parse.py 'rv*'" - end -end - -# stamp to indicate completion of Arch Gen for a given config -rule %r{#{$root}/\.stamps/arch-gen-.*\.stamp} => proc { |tname| - config_name = Pathname.new(tname).basename(".stamp").sub("arch-gen-", "") - arch_files = Dir.glob($root / "arch" / "**" / "*.yaml") - config_files = - Dir.glob($root / "cfgs" / config_name / "arch_overlay" / "**" / "*.yaml") + - [$root / "cfgs" / config_name / "params.yaml"] - [ - "#{$root}/.stamps", - "#{$root}/lib/arch_gen.rb", - "#{$root}/lib/idl/ast.rb", - "#{$root}/tasks/arch_gen.rake", - "ext/riscv-opcodes/instr_dict.yaml" - ] + arch_files + config_files -} do |t| - config_name = Pathname.new(t.name).basename(".stamp").sub("arch-gen-", "") - - arch_gen = ArchGen.new(config_name) - puts "Generating architecture definition in #{arch_gen.gen_dir.relative_path_from($root)}" - - arch_gen.generate - - puts " Found #{arch_gen.implemented_csrs.size} CSRs" - puts " Found #{arch_gen.implemented_extensions.size} Extensions" - puts " Found #{arch_gen.implemented_instructions.size} Instructions" - - FileUtils.touch t.name -end - -namespace :gen do - desc "Generate the architecture files for config_name" - task :arch, [:config_name] do |_t, args| - raise "No config '#{args[:config_name]}' found in cfgs/" unless ($root / "cfgs" / args[:config_name]).directory? - - Rake::Task["#{$root}/.stamps/arch-gen-#{args[:config_name]}.stamp"].invoke(args[:config_name]) - end -end - -file ".venv/bin/pip" do - Dir.chdir $root do - sh "python3 -m venv #{$root}/.venv" - end -end - -file ".venv/lib/python3.12/site-packages/json_schema_for_humans/__init__.py" => ".venv/bin/pip" do - sh "#{$root}/.venv/bin/pip install json-schema-for-humans" -end - -file "docs/schema/arch_schema.md" => Rake::FileList[ - ".venv/lib/python3.12/site-packages/json_schema_for_humans/__init__.py", - "arch/**/*.json", - "arch/*.json" -] do |t| - sh ".venv/bin/generate-schema-doc --config template_name=md arch/*.json,arch/**/*.json #{File.dirname(t.name)}" -end - -file "docs/schema/arch_schema.html" => Rake::FileList[ - ".venv/lib/python3.12/site-packages/json_schema_for_humans/__init__.py", - "arch/**/*.json", - "arch/*.json" -] do |t| - sh ".venv/bin/generate-schema-doc --config template_name=js arch/*.json,arch/**/*.json #{File.dirname(t.name)}" -end - -namespace :doc do - desc "Generate documentation for the architecture spec format" - task arch_format: ["docs/schema/arch_schema.md", "docs/schema/arch_schema.html"] -end diff --git a/tasks/top.rake b/tasks/top.rake deleted file mode 100644 index f206f8f3c..000000000 --- a/tasks/top.rake +++ /dev/null @@ -1,69 +0,0 @@ -# frozen_string_literal: true - -$root = Pathname.new(__FILE__).dirname.dirname.realpath -$lib = $root / "lib" - -require "yard" -require "minitest/test_task" - -require_relative $root / "lib" / "validate" - -directory "#{$root}/.stamps" - -load "#{$root}/tasks/arch_gen.rake" -load "#{$root}/tasks/adoc_gen.rake" -load "#{$root}/tasks/html_gen.rake" -load "#{$root}/tasks/ext_pdf_gen.rake" - -namespace :gen do - task :html -end - -desc "Validate the arch docs" -task :validate do - validator = Validator.new - Dir.glob("#{$root}/arch/**/*.yaml") do |f| - validator.validate(f) - end -end - -directory "#{$root}/.stamps" - -file "#{$root}/.stamps/dev_gems" => "#{$root}/.stamps" do - Dir.chdir($root) do - sh "bundle config set --local with development" - sh "bundle install" - FileUtils.touch "#{$root}/.stamps/dev_gems" - end -end - -namespace :gen do - desc "Generate documentation for the generator tool" - task tool_doc: "#{$root}/.stamps/dev_gems" do - Dir.chdir($root) do - sh "bundle exec yard doc" - end - end -end - -namespace :serve do - desc <<~DESC - Start an HTML server to view the generated HTML documentation for the tool - - The default port is 8000, though it can be overridden with an argument - DESC - task :ruby_doc, [:port] => "gen:tool_doc" do |_t, args| - args.with_defaults(port: 8000) - - puts <<~MSG - Server will come up on http://#{`hostname`.strip}:#{args[:port]}. - It will regenerate the documentation on every access - - MSG - sh "yard server -p #{args[:port]} --reload" - end -end - -Minitest::TestTask.create :idl_test do |t| - t.test_globs = ["#{$root}/lib/idl/tests/test_*.rb"] -end