udb 0.1.13 → 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. checksums.yaml +4 -4
  2. data/.data/cfgs/example_rv64_with_overlay.yaml +15 -18
  3. data/.data/cfgs/qc_iu.yaml +5 -1
  4. data/.data/cfgs/rv32-riscv-tests.yaml +4 -1
  5. data/.data/cfgs/rv32-vector.yaml +4 -1
  6. data/.data/cfgs/rv64-riscv-tests.yaml +4 -1
  7. data/.data/cfgs/rv64-vector.yaml +4 -1
  8. data/.data/spec/custom/isa/qc_iu/ext/Xqccmi.yaml +107 -36
  9. data/.data/spec/custom/isa/qc_iu/inst/Xqccmi/qc.cm.ilut.yaml +52 -69
  10. data/.data/spec/custom/isa/qc_iu/isa/globals.isa +27 -5
  11. data/.data/spec/schemas/config_schema.json +1 -1
  12. data/.data/spec/schemas/mmr_schema.json +3 -3
  13. data/.data/spec/schemas/schema_defs.json +5 -0
  14. data/.data/spec/std/isa/csr/H/henvcfg.yaml +25 -0
  15. data/.data/spec/std/isa/csr/I/pmpaddr0.yaml +6 -4
  16. data/.data/spec/std/isa/csr/I/pmpaddr1.yaml +6 -4
  17. data/.data/spec/std/isa/csr/I/pmpaddr10.yaml +6 -4
  18. data/.data/spec/std/isa/csr/I/pmpaddr11.yaml +6 -4
  19. data/.data/spec/std/isa/csr/I/pmpaddr12.yaml +6 -4
  20. data/.data/spec/std/isa/csr/I/pmpaddr13.yaml +6 -4
  21. data/.data/spec/std/isa/csr/I/pmpaddr14.yaml +6 -4
  22. data/.data/spec/std/isa/csr/I/pmpaddr15.yaml +6 -4
  23. data/.data/spec/std/isa/csr/I/pmpaddr16.yaml +6 -4
  24. data/.data/spec/std/isa/csr/I/pmpaddr17.yaml +6 -4
  25. data/.data/spec/std/isa/csr/I/pmpaddr18.yaml +6 -4
  26. data/.data/spec/std/isa/csr/I/pmpaddr19.yaml +6 -4
  27. data/.data/spec/std/isa/csr/I/pmpaddr2.yaml +6 -4
  28. data/.data/spec/std/isa/csr/I/pmpaddr20.yaml +6 -4
  29. data/.data/spec/std/isa/csr/I/pmpaddr21.yaml +6 -4
  30. data/.data/spec/std/isa/csr/I/pmpaddr22.yaml +6 -4
  31. data/.data/spec/std/isa/csr/I/pmpaddr23.yaml +6 -4
  32. data/.data/spec/std/isa/csr/I/pmpaddr24.yaml +6 -4
  33. data/.data/spec/std/isa/csr/I/pmpaddr25.yaml +6 -4
  34. data/.data/spec/std/isa/csr/I/pmpaddr26.yaml +6 -4
  35. data/.data/spec/std/isa/csr/I/pmpaddr27.yaml +6 -4
  36. data/.data/spec/std/isa/csr/I/pmpaddr28.yaml +6 -4
  37. data/.data/spec/std/isa/csr/I/pmpaddr29.yaml +6 -4
  38. data/.data/spec/std/isa/csr/I/pmpaddr3.yaml +6 -4
  39. data/.data/spec/std/isa/csr/I/pmpaddr30.yaml +6 -4
  40. data/.data/spec/std/isa/csr/I/pmpaddr31.yaml +6 -4
  41. data/.data/spec/std/isa/csr/I/pmpaddr32.yaml +6 -4
  42. data/.data/spec/std/isa/csr/I/pmpaddr33.yaml +6 -4
  43. data/.data/spec/std/isa/csr/I/pmpaddr34.yaml +6 -4
  44. data/.data/spec/std/isa/csr/I/pmpaddr35.yaml +6 -4
  45. data/.data/spec/std/isa/csr/I/pmpaddr36.yaml +6 -4
  46. data/.data/spec/std/isa/csr/I/pmpaddr37.yaml +6 -4
  47. data/.data/spec/std/isa/csr/I/pmpaddr38.yaml +6 -4
  48. data/.data/spec/std/isa/csr/I/pmpaddr39.yaml +6 -4
  49. data/.data/spec/std/isa/csr/I/pmpaddr4.yaml +6 -4
  50. data/.data/spec/std/isa/csr/I/pmpaddr40.yaml +6 -4
  51. data/.data/spec/std/isa/csr/I/pmpaddr41.yaml +6 -4
  52. data/.data/spec/std/isa/csr/I/pmpaddr42.yaml +6 -4
  53. data/.data/spec/std/isa/csr/I/pmpaddr43.yaml +6 -4
  54. data/.data/spec/std/isa/csr/I/pmpaddr44.yaml +6 -4
  55. data/.data/spec/std/isa/csr/I/pmpaddr45.yaml +6 -4
  56. data/.data/spec/std/isa/csr/I/pmpaddr46.yaml +6 -4
  57. data/.data/spec/std/isa/csr/I/pmpaddr47.yaml +6 -4
  58. data/.data/spec/std/isa/csr/I/pmpaddr48.yaml +6 -4
  59. data/.data/spec/std/isa/csr/I/pmpaddr49.yaml +6 -4
  60. data/.data/spec/std/isa/csr/I/pmpaddr5.yaml +6 -4
  61. data/.data/spec/std/isa/csr/I/pmpaddr50.yaml +6 -4
  62. data/.data/spec/std/isa/csr/I/pmpaddr51.yaml +6 -4
  63. data/.data/spec/std/isa/csr/I/pmpaddr52.yaml +6 -4
  64. data/.data/spec/std/isa/csr/I/pmpaddr53.yaml +6 -4
  65. data/.data/spec/std/isa/csr/I/pmpaddr54.yaml +6 -4
  66. data/.data/spec/std/isa/csr/I/pmpaddr55.yaml +6 -4
  67. data/.data/spec/std/isa/csr/I/pmpaddr56.yaml +6 -4
  68. data/.data/spec/std/isa/csr/I/pmpaddr57.yaml +6 -4
  69. data/.data/spec/std/isa/csr/I/pmpaddr58.yaml +6 -4
  70. data/.data/spec/std/isa/csr/I/pmpaddr59.yaml +6 -4
  71. data/.data/spec/std/isa/csr/I/pmpaddr6.yaml +6 -4
  72. data/.data/spec/std/isa/csr/I/pmpaddr60.yaml +6 -4
  73. data/.data/spec/std/isa/csr/I/pmpaddr61.yaml +6 -4
  74. data/.data/spec/std/isa/csr/I/pmpaddr62.yaml +6 -4
  75. data/.data/spec/std/isa/csr/I/pmpaddr63.yaml +6 -4
  76. data/.data/spec/std/isa/csr/I/pmpaddr7.yaml +6 -4
  77. data/.data/spec/std/isa/csr/I/pmpaddr8.yaml +6 -4
  78. data/.data/spec/std/isa/csr/I/pmpaddr9.yaml +6 -4
  79. data/.data/spec/std/isa/csr/I/pmpaddrN.layout +6 -4
  80. data/.data/spec/std/isa/csr/I/pmpcfg0.yaml +120 -144
  81. data/.data/spec/std/isa/csr/I/pmpcfg1.yaml +60 -72
  82. data/.data/spec/std/isa/csr/I/pmpcfg10.yaml +120 -144
  83. data/.data/spec/std/isa/csr/I/pmpcfg11.yaml +60 -72
  84. data/.data/spec/std/isa/csr/I/pmpcfg12.yaml +120 -144
  85. data/.data/spec/std/isa/csr/I/pmpcfg13.yaml +60 -72
  86. data/.data/spec/std/isa/csr/I/pmpcfg14.yaml +120 -144
  87. data/.data/spec/std/isa/csr/I/pmpcfg15.yaml +60 -72
  88. data/.data/spec/std/isa/csr/I/pmpcfg2.yaml +120 -144
  89. data/.data/spec/std/isa/csr/I/pmpcfg3.yaml +60 -72
  90. data/.data/spec/std/isa/csr/I/pmpcfg4.yaml +120 -144
  91. data/.data/spec/std/isa/csr/I/pmpcfg5.yaml +60 -72
  92. data/.data/spec/std/isa/csr/I/pmpcfg6.yaml +120 -144
  93. data/.data/spec/std/isa/csr/I/pmpcfg7.yaml +60 -72
  94. data/.data/spec/std/isa/csr/I/pmpcfg8.yaml +120 -144
  95. data/.data/spec/std/isa/csr/I/pmpcfg9.yaml +60 -72
  96. data/.data/spec/std/isa/csr/I/pmpcfgN.layout +15 -18
  97. data/.data/spec/std/isa/csr/jvt.yaml +1 -0
  98. data/.data/spec/std/isa/csr/menvcfg.yaml +20 -0
  99. data/.data/spec/std/isa/csr/mstatus.yaml +8 -6
  100. data/.data/spec/std/isa/csr/senvcfg.yaml +26 -0
  101. data/.data/spec/std/isa/inst/B/andn.yaml +10 -12
  102. data/.data/spec/std/isa/inst/B/clmul.yaml +9 -11
  103. data/.data/spec/std/isa/inst/B/clmulh.yaml +9 -11
  104. data/.data/spec/std/isa/inst/B/orn.yaml +9 -11
  105. data/.data/spec/std/isa/inst/B/rev8.yaml +1 -1
  106. data/.data/spec/std/isa/inst/B/rol.yaml +9 -11
  107. data/.data/spec/std/isa/inst/B/rolw.yaml +9 -11
  108. data/.data/spec/std/isa/inst/B/ror.yaml +9 -11
  109. data/.data/spec/std/isa/inst/B/rorw.yaml +9 -11
  110. data/.data/spec/std/isa/inst/B/xnor.yaml +9 -11
  111. data/.data/spec/std/isa/inst/C/c.ldsp.yaml +3 -3
  112. data/.data/spec/std/isa/inst/I/addi.yaml +1 -0
  113. data/.data/spec/std/isa/inst/I/addiw.yaml +1 -0
  114. data/.data/spec/std/isa/inst/I/andi.yaml +1 -0
  115. data/.data/spec/std/isa/inst/I/auipc.yaml +1 -0
  116. data/.data/spec/std/isa/inst/I/lb.yaml +1 -0
  117. data/.data/spec/std/isa/inst/I/lbu.yaml +1 -0
  118. data/.data/spec/std/isa/inst/I/ld.yaml +2 -0
  119. data/.data/spec/std/isa/inst/I/lh.yaml +1 -0
  120. data/.data/spec/std/isa/inst/I/lhu.yaml +1 -0
  121. data/.data/spec/std/isa/inst/I/lui.yaml +1 -0
  122. data/.data/spec/std/isa/inst/I/lw.yaml +1 -0
  123. data/.data/spec/std/isa/inst/I/lwu.yaml +1 -0
  124. data/.data/spec/std/isa/inst/I/ori.yaml +1 -0
  125. data/.data/spec/std/isa/inst/I/sb.yaml +1 -0
  126. data/.data/spec/std/isa/inst/I/sd.yaml +1 -0
  127. data/.data/spec/std/isa/inst/I/sh.yaml +1 -0
  128. data/.data/spec/std/isa/inst/I/slti.yaml +1 -0
  129. data/.data/spec/std/isa/inst/I/sltiu.yaml +1 -0
  130. data/.data/spec/std/isa/inst/I/sw.yaml +1 -0
  131. data/.data/spec/std/isa/inst/I/xori.yaml +1 -0
  132. data/.data/spec/std/isa/inst/V/vadc.vim.yaml +1 -0
  133. data/.data/spec/std/isa/inst/V/vadd.vi.yaml +1 -0
  134. data/.data/spec/std/isa/inst/V/vand.vi.yaml +1 -0
  135. data/.data/spec/std/isa/inst/V/vle8.v.yaml +1 -0
  136. data/.data/spec/std/isa/inst/V/vmadc.vi.yaml +1 -0
  137. data/.data/spec/std/isa/inst/V/vmadc.vim.yaml +1 -0
  138. data/.data/spec/std/isa/inst/V/vmerge.vim.yaml +1 -0
  139. data/.data/spec/std/isa/inst/V/vmseq.vi.yaml +1 -0
  140. data/.data/spec/std/isa/inst/V/vmsgt.vi.yaml +1 -0
  141. data/.data/spec/std/isa/inst/V/vmsgtu.vi.yaml +1 -0
  142. data/.data/spec/std/isa/inst/V/vmsle.vi.yaml +1 -0
  143. data/.data/spec/std/isa/inst/V/vmsleu.vi.yaml +1 -0
  144. data/.data/spec/std/isa/inst/V/vmsne.vi.yaml +1 -0
  145. data/.data/spec/std/isa/inst/V/vor.vi.yaml +1 -0
  146. data/.data/spec/std/isa/inst/V/vrsub.vi.yaml +1 -0
  147. data/.data/spec/std/isa/inst/V/vsadd.vi.yaml +1 -0
  148. data/.data/spec/std/isa/inst/V/vsaddu.vi.yaml +1 -0
  149. data/.data/spec/std/isa/inst/V/vse8.v.yaml +1 -0
  150. data/.data/spec/std/isa/inst/Zawrs/wrs.nto.yaml +4 -2
  151. data/.data/spec/std/isa/inst/Zba/add.uw.yaml +9 -11
  152. data/.data/spec/std/isa/inst/Zbb/orc.b.yaml +1 -1
  153. data/.data/spec/std/isa/inst/Zbkb/brev8.yaml +3 -3
  154. data/.data/spec/std/isa/inst/Zbkb/unzip.yaml +2 -2
  155. data/.data/spec/std/isa/inst/Zbkb/zip.yaml +2 -2
  156. data/.data/spec/std/isa/inst/Zbkx/xperm4.yaml +2 -2
  157. data/.data/spec/std/isa/inst/Zbkx/xperm8.yaml +2 -2
  158. data/.data/spec/std/isa/inst/Zicbop/prefetch.i.yaml +2 -0
  159. data/.data/spec/std/isa/inst/Zicbop/prefetch.r.yaml +2 -0
  160. data/.data/spec/std/isa/inst/Zicbop/prefetch.w.yaml +2 -0
  161. data/.data/spec/std/isa/inst/Zks/sm3p0.yaml +1 -1
  162. data/.data/spec/std/isa/inst/Zks/sm3p1.yaml +1 -1
  163. data/.data/spec/std/isa/inst/Zks/sm4ed.yaml +1 -1
  164. data/.data/spec/std/isa/inst/Zks/sm4ks.yaml +1 -1
  165. data/.data/spec/std/isa/isa/builtin_functions.idl +1 -0
  166. data/.data/spec/std/isa/isa/globals.isa +27 -7
  167. data/.data/spec/std/isa/isa/interrupts.idl +1 -0
  168. data/.data/spec/std/isa/param/HSTATEEN_CONTEXT_TYPE.yaml +1 -0
  169. data/.data/spec/std/isa/param/MSTATEEN_CONTEXT_TYPE.yaml +1 -0
  170. data/.data/spec/std/isa/param/MTVEC_BASE_ALIGNMENT_DIRECT.yaml +1 -0
  171. data/.data/spec/std/isa/param/MTVEC_BASE_ALIGNMENT_VECTORED.yaml +1 -0
  172. data/.data/spec/std/isa/param/NUM_PMP_ENTRIES.yaml +11 -22
  173. data/.data/spec/std/isa/param/NUM_USABLE_PMP_ENTRIES.yaml +35 -0
  174. data/.data/spec/std/isa/param/PMP_NA4_SUPPORTED.yaml +23 -0
  175. data/.data/spec/std/isa/param/PMP_NAPOT_SUPPORTED.yaml +19 -0
  176. data/.data/spec/std/isa/param/{MSTATUS_TVM_IMPLEMENTED.yaml → PMP_TOR_SUPPORTED.yaml} +6 -6
  177. data/.data/spec/std/isa/param/PRECISE_SYNCHRONOUS_EXCEPTIONS.yaml +1 -0
  178. data/.data/spec/std/isa/param/TRAP_ON_EBREAK.yaml +1 -0
  179. data/.data/spec/std/isa/param/TRAP_ON_ECALL_FROM_M.yaml +1 -0
  180. data/.data/spec/std/isa/param/TRAP_ON_SFENCE_VMA_WHEN_SATP_MODE_IS_READ_ONLY.yaml +1 -0
  181. data/.data/spec/std/isa/param/ZAWRS_NTO_IS_NOP.yaml +19 -0
  182. data/lib/udb/ESPRESSO_VERSION +1 -1
  183. data/lib/udb/config.rb +14 -2
  184. data/lib/udb/doc_link.rb +3 -4
  185. data/lib/udb/obj/instruction.rb +1 -1
  186. data/lib/udb/obj/non_isa_specification.rb +22 -100
  187. data/lib/udb/version.rb +1 -1
  188. data/lib/udb/z3.rb +2 -2
  189. metadata +7 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a3c1ac46d7a7612704172bcdd8ec9a5d2fe55936b5c2aa8341a684cc5aa61909
4
- data.tar.gz: 76b89f28a9e70ac5376bf815c7fc21e28bc56bf3e685be958e58d0bb18b45328
3
+ metadata.gz: '033857ac50551c786b5857f54a78a91f6a2c3d8c46554eb0dae62cbc489b9ab4'
4
+ data.tar.gz: dce0e09b88581e3cc6dc13de86d7e5a72c8c2377e66aca53994d6a0c239ec3a2
5
5
  SHA512:
6
- metadata.gz: a56d1927a8649d58a0af62af8a473c1a998db9180425855c99c0bc6565125109750ba593891e5ec691708da2e3598148953b8094a13d82abae0391c82cb018bb
7
- data.tar.gz: d4fc5b635b10dcaece666c73052f154fc5b5eb24ef8e29e0ae5d1b25bf69e7698e3ae992b5b71a42540d6c4876355257c5d0eb63641daf9680e96d0c5cd528db
6
+ metadata.gz: 5b0efc566225e863a99ba9c1818a47ef57590bdd7d8e5f37a3937b6c7fb7b94bfe409d96a9e0c886fcb74e2eac312bc3023ebe72e55128043f578acf6a576dca
7
+ data.tar.gz: fe01c90f6363a506d6191b2a6ac5f39acb91ca241a00a83951b83e2af680895cb56b140d826f0010bb00f21e723794b03415f543afe41c54fe701d942ed2e444
@@ -358,23 +358,21 @@ params:
358
358
  # this address is reported in the mconfigptr CSR
359
359
  CONFIG_PTR_ADDRESS: 0x1000
360
360
 
361
- # number of implemented PMP entries. Can be any value between 0-64, inclusive.
362
- #
363
- # the number of implemented PMP registers must be 0, 16, or 64.
364
- #
365
- # Therefore, whether or not a pmpaddrN or pmpcfgN register exists depends on
366
- # NUM_PMP_ENTRIES as follows:
367
- # |===
368
- # | NUM_PMP_ENTRIES | pmpaddr<0-15> / pmpcfg<0-3> | pmpaddr<16-63> / pmpcfg<4-15>
369
- # | 0 | N | N
370
- # | 1-16 | Y | N
371
- # | 17-64 | Y | Y
372
- # |===
373
- # ** pmpcfgN for an odd N never exist when XLEN == 64
374
- #
375
- # when NUM_PMP_ENTRIES is not exactly 0, 16, or 64, some extant pmp registers,
376
- # and associated pmpNcfg, will be read-only zero (but will not cause an exception).
377
- NUM_PMP_ENTRIES: 14
361
+ # number of implemented PMP entries, some may be read-only zero.
362
+ # Must be 0, 16, or 64.
363
+ NUM_PMP_ENTRIES: 16
364
+
365
+ # number of implemented PMP entries that are actually usable (writable).
366
+ # Must be between 0 and NUM_PMP_ENTRIES, inclusive. Entries at and above this
367
+ # index are implemented as read-only zero (they exist but cannot be
368
+ # configured). Here, 16 entries are implemented but only 14 are usable.
369
+ NUM_USABLE_PMP_ENTRIES: 14
370
+
371
+ # Which PMP address matching modes are supported.
372
+ # NA4 must be false unless PMP_GRANULARITY == 2 (4-byte granularity).
373
+ PMP_TOR_SUPPORTED: true
374
+ PMP_NA4_SUPPORTED: false
375
+ PMP_NAPOT_SUPPORTED: true
378
376
 
379
377
  # log2 of the smallest supported PMP region
380
378
  # generally, for systems with an MMU, should not be smaller than 12,
@@ -596,7 +594,6 @@ params:
596
594
  MTVEC_BASE_ALIGNMENT_DIRECT: 4
597
595
  MTVEC_BASE_ALIGNMENT_VECTORED: 4
598
596
  MSTATUS_FS_LEGAL_VALUES: [0, 1, 2, 3]
599
- MSTATUS_TVM_IMPLEMENTED: true
600
597
  HW_MSTATUS_FS_DIRTY_UPDATE: precise
601
598
  MSTATUS_VS_LEGAL_VALUES: [0, 1, 2, 3]
602
599
  HW_MSTATUS_VS_DIRTY_UPDATE: precise
@@ -23,7 +23,7 @@ implemented_extensions:
23
23
  - { name: Zihpm, version: "= 2.0" }
24
24
  - { name: Xqccmp, version: "= 0.3" }
25
25
  - { name: Xqccmt, version: "= 0.1.0" }
26
- - { name: Xqccmi, version: "= 0.1.0" }
26
+ - { name: Xqccmi, version: "= 0.2.0" }
27
27
  - { name: Xqci, version: "= 0.13" }
28
28
  - { name: Xqcia, version: "= 0.7.0" }
29
29
  - { name: Xqciac, version: "= 0.3.0" }
@@ -176,6 +176,10 @@ params:
176
176
  MTVAL_WIDTH: 32
177
177
  PMP_GRANULARITY: 12
178
178
  NUM_PMP_ENTRIES: 16
179
+ NUM_USABLE_PMP_ENTRIES: 16
180
+ PMP_TOR_SUPPORTED: true
181
+ PMP_NA4_SUPPORTED: false
182
+ PMP_NAPOT_SUPPORTED: true
179
183
  PMA_GRANULARITY: 12
180
184
  M_MODE_ENDIANNESS: little
181
185
  MISA_CSR_IMPLEMENTED: true
@@ -194,8 +194,11 @@ params:
194
194
  TRAP_ON_ECALL_FROM_S: true
195
195
  MSTATUS_VS_LEGAL_VALUES: [0]
196
196
  MSTATUS_FS_LEGAL_VALUES: [3, 2, 1, 0]
197
- MSTATUS_TVM_IMPLEMENTED: false
198
197
  NUM_PMP_ENTRIES: 16
198
+ NUM_USABLE_PMP_ENTRIES: 16
199
+ PMP_TOR_SUPPORTED: true
200
+ PMP_NA4_SUPPORTED: false
201
+ PMP_NAPOT_SUPPORTED: true
199
202
  PMP_GRANULARITY: 12
200
203
  MUTABLE_MISA_U: false
201
204
  U_MODE_ENDIANNESS: little
@@ -208,8 +208,11 @@ params:
208
208
  MSTATUS_VS_LEGAL_VALUES: [0, 1, 2, 3]
209
209
  HW_MSTATUS_FS_DIRTY_UPDATE: precise
210
210
  MSTATUS_FS_LEGAL_VALUES: [0, 3]
211
- MSTATUS_TVM_IMPLEMENTED: false
212
211
  NUM_PMP_ENTRIES: 16
212
+ NUM_USABLE_PMP_ENTRIES: 16
213
+ PMP_TOR_SUPPORTED: true
214
+ PMP_NA4_SUPPORTED: false
215
+ PMP_NAPOT_SUPPORTED: true
213
216
  PMP_GRANULARITY: 12
214
217
  MUTABLE_MISA_U: false
215
218
  U_MODE_ENDIANNESS: little
@@ -193,8 +193,11 @@ params:
193
193
  TRAP_ON_ECALL_FROM_U: true
194
194
  MSTATUS_VS_LEGAL_VALUES: [0]
195
195
  MSTATUS_FS_LEGAL_VALUES: [3, 2, 1, 0]
196
- MSTATUS_TVM_IMPLEMENTED: false
197
196
  NUM_PMP_ENTRIES: 16
197
+ NUM_USABLE_PMP_ENTRIES: 16
198
+ PMP_TOR_SUPPORTED: true
199
+ PMP_NA4_SUPPORTED: false
200
+ PMP_NAPOT_SUPPORTED: true
198
201
  PMP_GRANULARITY: 12
199
202
  MUTABLE_MISA_U: false
200
203
  U_MODE_ENDIANNESS: little
@@ -205,8 +205,11 @@ params:
205
205
  TRAP_ON_ECALL_FROM_U: true
206
206
  MSTATUS_VS_LEGAL_VALUES: [0, 1, 2, 3]
207
207
  MSTATUS_FS_LEGAL_VALUES: [0, 1, 2, 3]
208
- MSTATUS_TVM_IMPLEMENTED: false
209
208
  NUM_PMP_ENTRIES: 16
209
+ NUM_USABLE_PMP_ENTRIES: 16
210
+ PMP_TOR_SUPPORTED: true
211
+ PMP_NA4_SUPPORTED: false
212
+ PMP_NAPOT_SUPPORTED: true
210
213
  PMP_GRANULARITY: 12
211
214
  MUTABLE_MISA_U: false
212
215
  U_MODE_ENDIANNESS: little
@@ -24,9 +24,8 @@ description: |
24
24
 
25
25
  `qc.cm.ilut` is a 16-bit instruction that takes an 11-bit immediate index
26
26
  (range 0..2047) into the ILUT. The ILUT base address is held in the `qc.itba`
27
- CSR (address 0x800). The hardware computes the byte offset of the addressed
28
- entry from the base address, fetches the entry, parses the packed instructions
29
- within it, and executes them in order.
27
+ CSR (address 0x800). The instruction architecturally behaves as the
28
+ sub-instruction(s) stored at the addressed ILUT entry, executed in order.
30
29
 
31
30
  ILUT memory is treated as instruction memory. It requires execute (X)
32
31
  permission and does NOT require read (R) permission. A `fence.i` instruction
@@ -80,9 +79,9 @@ description: |
80
79
 
81
80
  === Dual-Instruction Packing
82
81
 
83
- Each ILUT entry may contain one or two instructions packed together. The
84
- hardware determines instruction sizes by parsing bits[1:0] of each
85
- sub-instruction after fetching the full entry.
82
+ Each ILUT entry may contain one or two instructions packed together.
83
+ Instruction sizes are determined by the standard RISC-V instruction-length
84
+ encoding (bits[1:0] of each sub-instruction).
86
85
 
87
86
  ==== 32-bit Entry Valid Combinations
88
87
 
@@ -110,53 +109,82 @@ description: |
110
109
 
111
110
  Unused bits in any entry MUST be padded with `c.nop` (16'h0001). Instruction
112
111
  combinations that do not fit within the entry size cause an illegal instruction
113
- exception. Hardware determines instruction sizes by parsing bits[1:0] of each
114
- sub-instruction after fetching the full entry.
112
+ exception. Instruction sizes are determined by the standard RISC-V
113
+ instruction-length encoding (bits[1:0] of each sub-instruction).
115
114
 
116
115
  === Instruction Restrictions
117
116
 
118
- PC-relative instructions are NOT permitted in the ILUT. This includes:
117
+ Any instruction that references PC as an input or output is NOT permitted
118
+ in the ILUT. If any such instruction is present in the entry, an
119
+ IllegalInstruction exception is raised before any sub-instruction in the
120
+ entry takes architectural effect.
119
121
 
120
- * `auipc`
121
- * All branch instructions (beq, bne, blt, bge, bltu, bgeu, c.beqz, c.bnez, etc.)
122
- * All jump instructions (jal, jalr, c.j, c.jal, c.jr, c.jalr, etc.)
122
+ Forbidden instructions fall into three categories:
123
123
 
124
- If a PC-relative instruction is fetched from the ILUT, an illegal instruction
125
- exception is raised. 16-bit compressed instructions (bits[1:0] != 2'b11) are
126
- otherwise valid in ILUT entries.
124
+ * *PC-relative instructions* (read PC as input):
125
+ ** `auipc`
126
+ ** All branch instructions (`beq`, `bne`, `blt`, `bge`, `bltu`, `bgeu`,
127
+ `c.beqz`, `c.bnez`, etc.)
128
+ ** PC-relative jump instructions (`jal`, `c.j`, `c.jal`)
129
+
130
+ * *Register-indirect jumps* (write PC as output):
131
+ ** `jalr`
132
+ ** `c.jr`
133
+ ** `c.jalr`
134
+
135
+ * *Return instructions* (write PC as output):
136
+ ** `cm.popret`
137
+ ** `cm.popretz`
138
+ ** `qc.cm.popret`
139
+ ** `qc.cm.popretz`
140
+
141
+ The following push/pop instructions are explicitly *allowed* in ILUT entries
142
+ because they do not reference PC:
143
+ `cm.push`, `cm.pop`, `qc.cm.push`, `qc.cm.pushfp`, `qc.cm.pop`.
144
+
145
+ 16-bit compressed instructions (bits[1:0] != 2'b11) are otherwise valid
146
+ in ILUT entries.
127
147
 
128
148
  === Execution Model
129
149
 
130
- Logically, the PC points to the `qc.cm.ilut` instruction throughout the
131
- execution of all instructions contained within the fetched entry. The
132
- instructions within an entry execute as if they were a single atomic unit from
133
- the perspective of interrupt handling:
150
+ The PC points to the `qc.cm.ilut` instruction throughout the execution of all
151
+ sub-instructions contained within the fetched ILUT entry. Sub-instructions
152
+ execute sequentially and independently:
134
153
 
135
- * Interrupts cannot be taken between two instructions of the same entry once
136
- the first instruction has committed.
137
- * If the first instruction has not yet committed when an interrupt arrives, the
138
- interrupt is taken with mepc set to the PC of `qc.cm.ilut`.
139
- * If the first instruction has already committed when an interrupt arrives, the
140
- interrupt is serviced after the second instruction commits, with mepc pointing
141
- to the next instruction after `qc.cm.ilut`.
154
+ * The architectural state changes produced by the first sub-instruction are
155
+ visible to the second sub-instruction and to any subsequent trap handler.
156
+ * Each sub-instruction can trap independently; traps are taken precisely at the
157
+ sub-instruction that caused them, not deferred.
158
+ * After the final sub-instruction completes, the PC advances past `qc.cm.ilut`
159
+ normally.
142
160
 
143
161
  === Exception Handling
144
162
 
145
- On any exception caused by an instruction fetched from the ILUT:
163
+ On any trap (exception, interrupt, NMI, or double-trap) occurring during the
164
+ execution of a sub-instruction fetched from the ILUT:
146
165
 
147
166
  * mepc (or mnepc for a double-trap) is set to the PC of `qc.cm.ilut`.
148
- * Bit 0 of mepc/mnepc is set to 0 if the first instruction in the entry caused
149
- the exception.
150
- * Bit 0 of mepc/mnepc is set to 1 if the second instruction in the entry caused
151
- the exception.
167
+ * Bit 0 of mepc/mnepc encodes which sub-instruction was executing when the trap
168
+ occurred:
169
+ ** Bit 0 = 0: the trap occurred during the first (or only) sub-instruction.
170
+ ** Bit 0 = 1: the trap occurred during the second sub-instruction (the
171
+ architectural effects of the first sub-instruction are already visible).
152
172
 
153
- Bit 0 of mepc/mnepc is writable to 0 only; software cannot set it to 1.
154
- Return-from-trap instructions (`mret`, `mnret`, `qc.c.mret`, `qc.c.mnret`,
155
- `qc.c.mileaveret`) leave bit 0 of mepc/mnepc unchanged when returning.
173
+ On trap return (`mret`, `qc.c.mret`, `qc.c.mnret`, `qc.c.mileaveret`), $pc is
174
+ restored directly from mepc/mnepc including bit 0:
175
+
176
+ * If bit 0 = 0: `qc.cm.ilut` re-executes from the beginning, running both
177
+ sub-instructions.
178
+ * If bit 0 = 1: `qc.cm.ilut` skips the first sub-instruction and executes only
179
+ the second.
180
+
181
+ Bit 0 of mepc/mnepc is readable and writable in this architecture.
182
+ Software may explicitly set bit 0 to 1 to force resumption from the second
183
+ sub-instruction.
156
184
 
157
185
  NOTE: This is an architectural exception to the standard RISC-V requirement
158
- that *epc bit 0 is always zero. The non-zero bit 0 encodes which instruction
159
- within the ILUT entry caused the exception, enabling precise exception restart.
186
+ that *epc bit 0 is always zero. The non-zero bit 0 encodes which sub-instruction
187
+ within the ILUT entry was interrupted, enabling precise trap restart.
160
188
 
161
189
  === Encoding
162
190
 
@@ -217,3 +245,46 @@ versions:
217
245
  - not:
218
246
  extension:
219
247
  name: Zcd
248
+ - version: "0.2.0"
249
+ state: development
250
+ contributors:
251
+ - name: Albert Yosher
252
+ company: Qualcomm Technologies, Inc.
253
+ email: ayosher@qti.qualcomm.com
254
+ - name: Derek Hower
255
+ company: Qualcomm Technologies, Inc.
256
+ email: dhower@qti.qualcomm.com
257
+ - name: Gil Zukerman
258
+ company: Qualcomm Technologies, Inc.
259
+ email: gzukerma@qti.qualcomm.com
260
+ changes:
261
+ - >-
262
+ Precise trap semantics: each sub-instruction in an ILUT entry can now trap
263
+ independently. Traps are taken immediately at the faulting sub-instruction
264
+ rather than being deferred.
265
+ - >-
266
+ Resume mechanism: bit 0 of mepc/mnepc encodes which sub-instruction caused
267
+ the trap. On trap return, qc.cm.ilut re-enters with PC bit 0 reflecting this
268
+ value; if set, the first sub-instruction is skipped and only the second is
269
+ re-executed.
270
+ - >-
271
+ mepc/mnepc bit 0 is readable and writable in this architecture.
272
+ Software may set bit 0 to 1 to force resumption from the second sub-instruction.
273
+ - >-
274
+ Expanded ILUT instruction restrictions to all PC-referencing instructions:
275
+ added register-indirect jumps (jalr, c.jr, c.jalr) and return instructions
276
+ (cm.popret, cm.popretz, qc.cm.popret, qc.cm.popretz) to the forbidden list.
277
+ - >-
278
+ Spec language audit: removed all implementation-implying language; descriptions
279
+ now define architectural behavior only.
280
+ requirements:
281
+ allOf:
282
+ - extension:
283
+ name: Zca
284
+ version: ">= 1.0.0"
285
+ - extension:
286
+ name: Zicsr
287
+ version: ">= 2.0.0"
288
+ - not:
289
+ extension:
290
+ name: Zcd
@@ -24,13 +24,24 @@ description: |
24
24
  If bits remain after the first instruction and the next 16 bits are not
25
25
  `c.nop` (16'h0001), a second instruction is present and is also executed.
26
26
 
27
- PC-relative instructions (`auipc`, branches, and jumps) are not permitted
28
- inside ILUT entries. Hardware detects such instructions during decode and
29
- raises an IllegalInstruction exception.
30
-
31
- On an exception caused by the second instruction, hardware sets bit 0 of
32
- `mepc` to indicate that the fault originated from the second instruction
33
- within the entry.
27
+ Any instruction that references PC as an input or output is not permitted
28
+ inside ILUT entries. This includes: PC-relative instructions (`auipc`,
29
+ branches, `jal`, `c.j`, `c.jal`, `c.beqz`, `c.bnez`); register-indirect
30
+ jumps that write PC (`jalr`, `c.jr`, `c.jalr`); and return instructions
31
+ that write PC (`cm.popret`, `cm.popretz`, `qc.cm.popret`, `qc.cm.popretz`).
32
+ If any such instruction is present in the entry, an IllegalInstruction
33
+ exception is raised before any sub-instruction in the entry takes
34
+ architectural effect.
35
+
36
+ When a trap (exception, interrupt, NMI, or double-trap) occurs during
37
+ execution of a `qc.cm.ilut` entry, `mepc`/`mnepc` is set to the PC of
38
+ `qc.cm.ilut` with bit 0 encoding which sub-instruction caused the trap:
39
+ bit 0 = 0 means the trap came from the first (or only) instruction;
40
+ bit 0 = 1 means the trap came from the second instruction (the architectural
41
+ effects of the first sub-instruction are already visible). When `qc.cm.ilut` is re-entered with PC bit 0 = 1,
42
+ it skips the first instruction and executes only the second. This applies
43
+ uniformly to all trap types including exceptions, interrupts, NMIs, and
44
+ double-traps.
34
45
 
35
46
  See the Xqccmi extension description for full details on entry layout,
36
47
  dual-instruction packing, exception handling, and restrictions.
@@ -49,10 +60,10 @@ access:
49
60
  vs: always
50
61
  vu: always
51
62
  operation(): |
52
- # Read the double-entry count (N = number of 64-bit double entries)
53
- XReg N = {21'b0, CSR[qc.itdec].dec};
63
+ XReg real_pc = $pc & ~32'b1;
64
+ Boolean resuming_second = ($pc[0:0] == 1'b1);
54
65
 
55
- # Compute the byte address of the ILUT entry
66
+ XReg N = {21'b0, CSR[qc.itdec].dec};
56
67
  XReg base_addr = CSR[qc.itba].base << 6;
57
68
  XReg entry_addr;
58
69
  Boolean is_double;
@@ -65,89 +76,61 @@ operation(): |
65
76
  is_double = false;
66
77
  }
67
78
 
68
- # Translate the entry address (instruction fetch)
69
79
  TranslationResult result;
70
80
  if (CSR[misa].S == 1) {
71
81
  result = translate(entry_addr, MemoryOperation::Fetch, mode(), $encoding);
72
82
  } else {
73
83
  result.paddr = entry_addr;
74
84
  }
75
-
76
- # Access check for instruction fetch
77
85
  access_check(result.paddr, is_double ? 8 : 4, $pc, MemoryOperation::Fetch, ExceptionCode::InstructionAccessFault, mode());
78
86
 
79
- # Read the entry from physical memory.
80
- # For a 32-bit entry, read 32 bits. For a 64-bit double entry, read two
81
- # consecutive 32-bit words (entry_lo = bits[31:0], entry_hi = bits[63:32]).
82
87
  XReg entry_lo = read_physical_memory(32, result.paddr);
83
- XReg entry_hi = 32'b0;
84
- if (is_double) {
85
- entry_hi = read_physical_memory(32, result.paddr + 4);
86
- }
87
-
88
- # Determine the size of the first instruction using RISC-V length encoding:
89
- # bits[1:0] != 2'b11 -> 16-bit instruction
90
- # bits[1:0] == 2'b11 and bits[4:2] != 3'b111 -> 32-bit instruction
91
- # bits[1:0] == 2'b11 and bits[4:2] == 3'b111 -> 48-bit instruction
92
- Boolean has_second_inst = false; # true if this entry contains a second packed instruction
88
+ XReg entry_hi = is_double ? read_physical_memory(32, result.paddr + 4) : 32'b0;
93
89
 
90
+ Boolean has_second_inst = false; # true if entry contains a second packed instruction
94
91
  if (entry_lo[1:0] != 2'b11) {
95
- # 16-bit first instruction; second instruction is in entry_lo[31:16]
96
- Bits<16> second_lo = entry_lo[31:16];
97
- if (second_lo != 16'h0001) {
98
- has_second_inst = true;
99
- }
92
+ if (entry_lo[31:16] != 16'h0001) { has_second_inst = true; }
100
93
  } else if (entry_lo[4:2] != 3'b111) {
101
- # 32-bit first instruction
102
- if (is_double) {
103
- # Second instruction starts at entry_hi[15:0]
104
- Bits<16> second_lo = entry_hi[15:0];
105
- if (second_lo != 16'h0001) {
106
- has_second_inst = true;
107
- }
108
- }
109
- # No room for a second instruction in a 32-bit entry after a 32-bit first
94
+ if (is_double && entry_hi[15:0] != 16'h0001) { has_second_inst = true; }
110
95
  } else {
111
- # 48-bit first instruction
112
- if (!is_double) {
113
- # 48-bit instruction does not fit in a 32-bit entry
114
- executing_second_inst = false;
115
- raise_ilut(ExceptionCode::IllegalInstruction, $encoding);
116
- }
117
- # No room for a second instruction after a 48-bit first in a 64-bit entry
96
+ if (!is_double) { raise_ilut(ExceptionCode::IllegalInstruction, $encoding); }
118
97
  }
119
98
 
120
- # PC-relative instruction check:
121
- # Hardware detects auipc, branches, and jump instructions during decode
122
- # and raises an IllegalInstruction exception before any instruction executes.
123
- # mepc bit 0 reflects which slot contained the forbidden instruction.
124
- if (is_pc_relative_inst?(entry_lo)) {
99
+ if (is_pc_referencing_inst?(entry_lo)) {
125
100
  executing_second_inst = false;
126
101
  raise_ilut(ExceptionCode::IllegalInstruction, $encoding);
127
102
  }
128
103
  if (has_second_inst) {
129
- Bits<32> second_inst;
130
- if (entry_lo[1:0] != 2'b11) {
131
- second_inst = {16'b0, entry_lo[31:16]};
132
- } else {
133
- second_inst = {16'b0, entry_hi[15:0]};
134
- }
135
- if (is_pc_relative_inst?(second_inst)) {
104
+ Bits<32> second_inst = (entry_lo[1:0] != 2'b11) ? {16'b0, entry_lo[31:16]} : {16'b0, entry_hi[15:0]};
105
+ if (is_pc_referencing_inst?(second_inst)) {
136
106
  executing_second_inst = true;
137
107
  raise_ilut(ExceptionCode::IllegalInstruction, $encoding);
138
108
  }
139
109
  }
140
110
 
141
- # Execute the first instruction from the ILUT entry.
142
- # IDL cannot express dynamic instruction dispatch; actual execution is implementation-defined.
143
- # Any exception raised must call raise_ilut() with executing_second_inst = false (mepc bit 0 = 0).
144
- executing_second_inst = false;
145
- unpredictable("TO-DO: execute first ILUT instruction");
111
+ # Execute first instruction (skip if resuming after second-slot trap)
112
+ if (!resuming_second) {
113
+ if (implemented?(ExtensionName::Smrnmi) && CSR[mnstatus].NMIE == 1'b0) {
114
+ CSR[mnepc].PC = real_pc;
115
+ } else {
116
+ CSR[mepc].PC = real_pc;
117
+ }
118
+ execute_instruction(entry_lo);
119
+ }
146
120
 
147
- # Execute the second instruction from the ILUT entry, if present.
148
- # Any exception raised must call raise_ilut() with executing_second_inst = true (mepc bit 0 = 1).
121
+ # Execute second instruction if present
149
122
  if (has_second_inst) {
150
- executing_second_inst = true;
151
- unpredictable("TO-DO: execute second ILUT instruction");
152
- executing_second_inst = false;
123
+ Bits<32> second_inst = (entry_lo[1:0] != 2'b11) ? {16'b0, entry_lo[31:16]} : {16'b0, entry_hi[15:0]};
124
+ if (implemented?(ExtensionName::Smrnmi) && CSR[mnstatus].NMIE == 1'b0) {
125
+ CSR[mnepc].PC = real_pc | 32'b1;
126
+ } else {
127
+ CSR[mepc].PC = real_pc | 32'b1;
128
+ }
129
+ execute_instruction(second_inst);
130
+ # Restore mepc/mnepc bit 0 to 0 after successful completion
131
+ if (implemented?(ExtensionName::Smrnmi) && CSR[mnstatus].NMIE == 1'b0) {
132
+ CSR[mnepc].PC = real_pc;
133
+ } else {
134
+ CSR[mepc].PC = real_pc;
135
+ }
153
136
  }
@@ -103,14 +103,15 @@ function raise_ilut {
103
103
  }
104
104
  }
105
105
 
106
- function is_pc_relative_inst? {
106
+ function is_pc_referencing_inst? {
107
107
  returns Boolean
108
108
  arguments Bits<32> inst
109
109
  description {
110
- Returns true if +inst+ is a PC-relative instruction (auipc, branch, jump, or
111
- compressed PC-relative jump (jal/c.j/c.jal), or compressed branch) that is
112
- forbidden inside an ILUT entry. Register-indirect jumps (jalr, c.jr, c.jalr)
113
- are NOT PC-relative and are permitted inside ILUT entries.
110
+ Returns true if +inst+ references PC as an input or output, making it
111
+ forbidden inside an ILUT entry. This covers three categories:
112
+ (1) PC-relative instructions: auipc, branches, jal, c.j, c.jal, c.beqz, c.bnez;
113
+ (2) register-indirect jumps that write PC: jalr, c.jr, c.jalr;
114
+ (3) return instructions that write PC: cm.popret, cm.popretz, qc.cm.popret, qc.cm.popretz.
114
115
  For 16-bit compressed instructions, only the lower 16 bits of +inst+ are examined.
115
116
  For 48-bit Xqci instructions, only the lower 32 bits are passed here (the upper
116
117
  16 bits are in a separate word and are not needed for this check).
@@ -135,6 +136,22 @@ function is_pc_relative_inst? {
135
136
  if (cinst[15:13] == 3'b111 && cinst[1:0] == 2'b01) {
136
137
  return true;
137
138
  }
139
+ # c.jr: bits[15:12]=1000, bits[6:2]!=00000, bits[1:0]=10 (register jump, writes PC)
140
+ if (cinst[15:12] == 4'b1000 && cinst[6:2] != 5'b00000 && cinst[1:0] == 2'b10) {
141
+ return true;
142
+ }
143
+ # c.jalr: bits[15:12]=1001, bits[6:2]!=00000, bits[1:0]=10 (register jump-and-link, writes PC)
144
+ if (cinst[15:12] == 4'b1001 && cinst[6:2] != 5'b00000 && cinst[1:0] == 2'b10) {
145
+ return true;
146
+ }
147
+ # cm.popret / qc.cm.popret: bits[15:8]=10111110, bits[1:0]=10 (pops stack and returns, writes PC)
148
+ if (cinst[15:8] == 8'b10111110 && cinst[1:0] == 2'b10) {
149
+ return true;
150
+ }
151
+ # cm.popretz / qc.cm.popretz: bits[15:8]=10111100, bits[1:0]=10 (pops stack, zeroes a0, returns, writes PC)
152
+ if (cinst[15:8] == 8'b10111100 && cinst[1:0] == 2'b10) {
153
+ return true;
154
+ }
138
155
  return false;
139
156
  } else {
140
157
  # 32-bit (or 48-bit) instruction: check opcode field bits[6:0]
@@ -147,6 +164,11 @@ function is_pc_relative_inst? {
147
164
  if (opcode == 7'b1101111) {
148
165
  return true;
149
166
  }
167
+ # jalr: register-indirect jump, writes PC
168
+ # (grouped with PC-referencing instructions, not PC-relative)
169
+ if (opcode == 7'b1100111) {
170
+ return true;
171
+ }
150
172
  # branches
151
173
  if (opcode == 7'b1100011) {
152
174
  return true;
@@ -75,7 +75,7 @@
75
75
  "description": "Extension name"
76
76
  },
77
77
  "version": {
78
- "$ref": "schema_defs.json#/$defs/extension_version"
78
+ "$ref": "schema_defs.json#/$defs/implemented_extension_version"
79
79
  }
80
80
  }
81
81
  },
@@ -35,11 +35,11 @@
35
35
  "description": "One line description for the MMR"
36
36
  },
37
37
  "description": {
38
- "$ref": "schema_defs.json#/definitions/spec_text",
38
+ "$ref": "schema_defs.json#/$defs/spec_text",
39
39
  "description": "Function of the register"
40
40
  },
41
41
  "definedBy": {
42
- "$ref": "schema_defs.json#/definitions/condition",
42
+ "$ref": "schema_defs.json#/$defs/condition",
43
43
  "description": "Extension(s) that define the MMR"
44
44
  },
45
45
  "physical_address": {
@@ -59,7 +59,7 @@
59
59
  "type": "object",
60
60
  "patternProperties": {
61
61
  "^[a-zA-Z].*$": {
62
- "$ref": "csr_schema.json#/definitions/csr_field"
62
+ "$ref": "csr_schema.json#/$defs/csr_field"
63
63
  }
64
64
  },
65
65
  "description": "fields of this MMR",
@@ -231,6 +231,11 @@
231
231
  "$ref": "#/$defs/rvi_version",
232
232
  "description": "Exact version in `MAJOR[.MINOR[.PATCH]]` format (e.g., `2.1.0`, `2.1`, `2`)"
233
233
  },
234
+ "implemented_extension_version": {
235
+ "type": "string",
236
+ "description": "Exact implemented extension version, either bare or prefixed with `=` (e.g., `2.1.0`, `2.1`, `= 2.1`)",
237
+ "pattern": "^(=\\s*)?[0-9]+(\\.[0-9]+(\\.[0-9]+(-pre)?)?)?$"
238
+ },
234
239
  "requirement_string": {
235
240
  "type": "string",
236
241
  "description": "Version requirement string (e.g., `>= 2.0`, `~> 1.5`, `= 2.1`). The `~>` operator is a pessimistic version constraint: `~> X.Y` means `>= X.Y` and `< (X+1).0`; `~> X.Y.Z` means `>= X.Y.Z` and `< X.(Y+1).0`.",
@@ -289,6 +289,27 @@ fields:
289
289
  return 0;
290
290
  }
291
291
  return csr_value.SSE;
292
+ LPE:
293
+ location: 2
294
+ description: |
295
+ *Landing Pad Enable*
296
+
297
+ When the LPE field is set to 1, the Zicfilp extension is enabled in
298
+ VS-mode. When the LPE field is 0, the Zicfilp extension is not enabled
299
+ in VS-mode and the following rules apply to VS-mode:
300
+
301
+ * The hart does not update the `ELP` state; it remains as `NO_LP_EXPECTED`.
302
+ * The `LPAD` instruction operates as a no-op.
303
+ definedBy:
304
+ extension:
305
+ name: Zicfilp
306
+ type: RW
307
+ reset_value: UNDEFINED_LEGAL
308
+ sw_write(csr_value): |
309
+ if (CSR[menvcfg].LPE == 0){
310
+ return 0;
311
+ }
312
+ return csr_value.LPE;
292
313
  FIOM:
293
314
  location: 0
294
315
  description: |
@@ -336,4 +357,8 @@ sw_read(): |
336
357
  # henvcfg.SSE must read-as-zero
337
358
  value = value & ~(1 `<< 3);
338
359
  }
360
+ if (implemented?(ExtensionName::Zicfilp) && CSR[menvcfg].LPE == 0) {
361
+ # henvcfg.LPE must read-as-zero
362
+ value = value & ~(1 `<< 2);
363
+ }
339
364
  return value;