diff --git a/CHANGELOG.md b/CHANGELOG.md index c3c7076d0..c1a8a9aef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12 | Date (*dd.mm.yyyy*) | Version | Comment | |:-------------------:|:-------:|:--------| +| 23.08.2023 | 1.8.8.3 | :test_tube: add experimental `Smcntrpmf` ISA extension (counter privilege mode filtering; spec. is frozen but not yet ratified); remove unused `menvcfg` CSRs; [#676](https://github.com/stnolting/neorv32/pull/676) | | 19.08.2023 | 1.8.8.2 | :warning: constrain `mtval` CSR; add support for `mtinst` CSR (trap instruction); [#674](https://github.com/stnolting/neorv32/pull/674) | | 19.08.2023 | 1.8.8.1 | :test_tube: update RTE to support easy emulation of instructions; add example program to showcase how to emulate unaligned memory accesses; [#673](https://github.com/stnolting/neorv32/pull/673) | | 18.08.2023 | [**:rocket:1.8.8**](https://github.com/stnolting/neorv32/releases/tag/v1.8.8) | **New release** | diff --git a/README.md b/README.md index 2327d2351..1864def58 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,7 @@ see the [_open-source architecture ID list_](https://github.com/riscv/riscv-isa- [[`Zmmul`](https://stnolting.github.io/neorv32/#_zmmul_isa_extension)] [[`Zxcfu`](https://stnolting.github.io/neorv32/#_zxcfu_isa_extension)] [[`PMP`](https://stnolting.github.io/neorv32/#_pmp_isa_extension)] +[[`Smcntrpmf`](https://stnolting.github.io/neorv32/#_smcntrpmf_isa_extension)] [[`Sdext`](https://stnolting.github.io/neorv32/#_sdext_isa_extension)] [[`Sdtrig`](https://stnolting.github.io/neorv32/#_sdtrig_isa_extension)] * compatible to subsets of the RISC-V diff --git a/docs/datasheet/cpu.adoc b/docs/datasheet/cpu.adoc index 0a6f4f0a5..749ea5cb5 100644 --- a/docs/datasheet/cpu.adoc +++ b/docs/datasheet/cpu.adoc @@ -693,11 +693,11 @@ behave like regular C functions but that evaluate to a single custom instruction ==== `PMP` ISA Extension -The NEORV32 physical memory protection (PMP) provides an elementary memory protection mechanism that can be used -to constrain read, write and execute rights of arbitrary memory regions. The NEORV32 PMP is partly compatible -to the RISC-V Privileged Architecture Specifications. In general, the PMP can **grant permissions to user mode**, -which by default has none, and can **revoke permissions from M-mode**, which by default has full permissions. -The PMP is configured via the <<_machine_physical_memory_protection_csrs>>. +The NEORV32 physical memory protection (PMP, also known as `Smpmp` ISA extension) provides an elementary memory +protection mechanism that can be used to constrain read, write and execute rights of arbitrary memory regions. +The NEORV32 PMP is fully compatible to the RISC-V Privileged Architecture Specifications. In general, the PMP can +**grant permissions to user mode**, which by default has none, and can **revoke permissions from M-mode**, which +by default has full permissions. The PMP is configured via the <<_machine_physical_memory_protection_csrs>>. .PMP Rules when in Debug Mode [NOTE] @@ -708,6 +708,23 @@ Instruction fetches are also triggered when denied by a certain PMP rule. Howeve will not be executed and will not change CPU core state to preserve memory access protection. +==== `Smcntrpmf` - ISA Extension + +[IMPORTANT] +The `Smcntrpmf` ISA extension is frozen but not ratified yet. + +The _counter privilege mode filtering_ `Smcntrpmf` ISA extension allows to halt the standard cycle ([m]cycle[h]) +and instructions-retired (`[m]instret[h]`) counters if the CPU is in a specific privilege mode (machine oder user). +This ISA extension is automatically enabled if the <<_u_isa_extension>> is enabled. + +Four additional CSRs are provided by this extensions: + +* <<_mcyclecfgh, `mcyclecfg`>> +* <<_mcyclecfgh, `mcyclecfgh`>> +* <<_minstretcfgh, `minstretcfg`>> +* <<_minstretcfgh, `minstretcfgh`>> + + ==== `Sdext` ISA Extension This ISA extension enables the RISC-V-compatible "external debug support" by implementing diff --git a/docs/datasheet/cpu_csr.adoc b/docs/datasheet/cpu_csr.adoc index 130bf9110..f543ff719 100644 --- a/docs/datasheet/cpu_csr.adoc +++ b/docs/datasheet/cpu_csr.adoc @@ -25,9 +25,6 @@ bits can actually be modified. | 0x001 | <<_fflags>> | `CSR_FFLAGS` | URW | Floating-point accrued exceptions | 0x002 | <<_frm>> | `CSR_FRM` | URW | Floating-point dynamic rounding mode | 0x003 | <<_fcsr>> | `CSR_FCSR` | URW | Floating-point control and status -5+^| **<<_machine_configuration_csrs>>** -| 0x30a | <<_menvcfg>> | `CSR_MENVCFG` | MRW | Machine environment configuration register - low word -| 0x31a | <<_menvcfgh>> | `CSR_MENVCFGH` | MRW | Machine environment configuration register - low word 5+^| **<<_machine_trap_setup_csrs>>** | 0x300 | <<_mstatus>> | `CSR_MSTATUS` | MRW | Machine status register - low word | 0x301 | <<_misa>> | `CSR_MISA` | MRW | Machine CPU ISA and extensions @@ -74,7 +71,11 @@ bits can actually be modified. | 0xc03 .. 0xc0f | <<_hpmcounterh, `hpmcounter3`>> .. <<_hpmcounterh, `hpmcounter15`>> | `CSR_HPMCOUNTER3` .. `CSR_HPMCOUNTER15H` | URO | User performance-monitoring counter 3..15 low word | 0xc83 .. 0xc8f | <<_hpmcounterh, `hpmcounter3h`>> .. <<_hpmcounterh, `hpmcounter15h`>> | `CSR_HPMCOUNTER3H` .. `CSR_HPMCOUNTER15H` | URO | User performance-monitoring counter 3..15 high word 5+^| **<<_machine_counter_setup_csrs>>** -| 0x320 | <<_mcountinhibit>> | `CSR_MCOUNTINHIBIT` | MRW | Machine counter-inhibit register +| 0x320 | <<_mcountinhibit>> | `CSR_MCOUNTINHIBIT` | MRW | Machine counter-inhibit register +| 0x321 | <<_mcyclecfgh, `mcyclecfg`>> | `CSR_MCYCLECFG` | MRW | Machine cycle counter privilege mode filtering - low word +| 0x322 | <<_minstretcfgh, `minstretcfg`>> | `CSR_MINSTRETCFG` | MRW | Machine instret counter privilege mode filtering - low word +| 0x721 | <<_mcyclecfgh, `mcyclecfgh`>> | `CSR_MCYCLECFGH` | MRW | Machine cycle counter privilege mode filtering - high word +| 0x722 | <<_minstretcfgh, `minstretcfgh`>> | `CSR_MINSTRETCFGH` | MRW | Machine instret counter privilege mode filtering - high word 5+^| **<<_machine_information_csrs>>** | 0xf11 | <<_mvendorid>> | `CSR_MVENDORID` | MRO | Machine vendor ID | 0xf12 | <<_marchid>> | `CSR_MARCHID` | MRO | Machine architecture ID @@ -108,13 +109,12 @@ bits can actually be modified. [cols="^1,^1,<10"] [options="header",grid="rows"] |======================= -| Bit | R/W | Function -| 0 | r/w | **NX**: inexact -| 1 | r/w | **UF**: underflow -| 2 | r/w | **OF**: overflow -| 3 | r/w | **DZ**: division by zero -| 4 | r/w | **NV**: invalid operation -| 31:5 | r/- | _reserved_, writes are ignored; reads always return 0 +| Bit | R/W | Function +| 0 | r/w | **NX**: inexact +| 1 | r/w | **UF**: underflow +| 2 | r/w | **OF**: overflow +| 3 | r/w | **DZ**: division by zero +| 4 | r/w | **NV**: invalid operation |======================= {empty} + @@ -135,9 +135,8 @@ bits can actually be modified. [cols="^1,^1,<10"] [options="header",grid="rows"] |======================= -| Bit | R/W | Function -| 2:0 | r/w | Rounding mode -| 31:3 | r/- | _reserved_, writes are ignored; reads always return 0 +| Bit | R/W | Function +| 2:0 | r/w | Rounding mode |======================= @@ -159,44 +158,9 @@ bits can actually be modified. [cols="^1,^1,<10"] [options="header",grid="rows"] |======================= -| Bit | R/W | Function -| 4:0 | r/w | Accrued exception flags (<<_fflags>>) -| 7:5 | r/w | Rounding mode (<<_frm>>) -| 31:6 | r/- | _reserved_, writes are ignored; reads always return 0 -|======================= - - -<<< -// #################################################################################################################### -:sectnums: -==== Machine Configuration CSRs - -[discrete] -===== **`menvcfg`** - -[cols="<1,<8"] -[frame="topbot",grid="none"] -|======================= -| Name | Machine environment configuration register -| Address | `0x30a` -| Reset value | `0x00000000` -| ISA | `Zicsr` & `U` -| Description | The features of this CSR are not implemented yet. The register is read-only and always returns zero. -|======================= - - -{empty} + -[discrete] -===== **`menvcfgh`** - -[cols="<1,<8"] -[frame="topbot",grid="none"] -|======================= -| Name | Machine environment configuration register - high word -| Address | `0x31a` -| Reset value | `0x00000000` -| ISA | `Zicsr` & `U` -| Description | The features of this CSR are not implemented yet. The register is read-only and always returns zero. +| Bit | R/W | Function +| 4:0 | r/w | Accrued exception flags (<<_fflags>>) +| 7:5 | r/w | Rounding mode (<<_frm>>) |======================= @@ -222,10 +186,10 @@ bits can actually be modified. [cols="^1,^3,^1,<9"] [options="header",grid="rows"] |======================= -| Bit | Name [C] | R/W | Function +| Bit | Name [C] | R/W | Function | 3 | `CSR_MSTATUS_MIE` | r/w | **MIE**: Machine-mode interrupt enable flag | 7 | `CSR_MSTATUS_MPIE` | r/w | **MPIE**: Previous machine-mode interrupt enable flag state -| 12:11 | `CSR_MSTATUS_MPP_H` : `CSR_MSTATUS_MPP_L` | r/w | **MPP**: Previous machine privilege mode, 11 = machine (M) mode, 00 = user (U) mode +| 12:11 | `CSR_MSTATUS_MPP_H` : `CSR_MSTATUS_MPP_L` | r/w | **MPP**: Previous machine privilege mode, 11 = machine (M) mode, 00 = user (U) mode (other values will fall-back to M mode) | 17 | `CSR_MSTATUS_MPRV` | r/w | **MPRV**: Effective privilege mode for load/stores in machine mode; use `MPP` as effective privilege mode when set; hardwired to zero if user-mode not implemented | 21 | `CSR_MSTATUS_TW` | r/w | **TW**: Trap on execution of `wfi` instruction in user mode when set; hardwired to zero if user-mode not implemented |======================= @@ -322,8 +286,8 @@ interrupt is triggered or an exception is raised. [options="header",grid="rows"] |======================= | Bit | R/W | Function -| 31:2 | r/w | **BASE**: 4-byte aligned base address of trap base handler | 1:0 | r/- | **MODE**: always zero; BASE defines entry for _all_ traps +| 31:2 | r/w | **BASE**: 4-byte aligned base address of trap base handler |======================= @@ -339,18 +303,17 @@ interrupt is triggered or an exception is raised. | Reset value | `0x00000000` | ISA | `Zicsr` & `U` | Description | The `mcounteren` CSR is used to constrain user-mode access to the CPU's counter CSRs. -This CSR is also available if U mode is disabled, but the register is hardwired to all-zero in this case. |======================= .`mcounteren` CSR bits [cols="^1,^1,<8"] [options="header",grid="rows"] |======================= -| Bit | R/W | Function -| 0 | r/w (!) | **CY**: User-mode is allowed to read <<_cycleh>> CSRs when set -| 1 | r/- | **TM**: not implemented, hardwired to zero -| 2 | r/w (!) | **IR**: User-mode is allowed to read <<_instreth>> CSRs when set -| 15:3 | r/w (!) | **HPM**: user-mode is allowed to read <<_hpmcounterh>> CSRs when set +| Bit | R/W | Function +| 0 | r/w (!) | **CY**: User-mode is allowed to read <<_cycleh>> CSRs when set +| 1 | r/- | **TM**: not implemented, hardwired to zero +| 2 | r/w (!) | **IR**: User-mode is allowed to read <<_instreth>> CSRs when set +| 15:3 | r/w (!) | **HPM**: user-mode is allowed to read <<_hpmcounterh>> CSRs when set |======================= [IMPORTANT] @@ -428,10 +391,9 @@ an instruction is triggered / an exception is raised. See section <<_traps_excep [cols="^1,^1,<10"] [options="header",grid="rows"] |======================= -| Bit | R/W | Function -| 4:0 | r/w | **Exception code**: see <<_neorv32_trap_listing>> -| 30:5 | r/- | _Reserved_, read as zero -| 31 | r/w | **Interrupt**: `1` if the trap is caused by an interrupt (`0` if the trap is caused by an exception) +| Bit | R/W | Function +| 4:0 | r/w | **Exception code**: see <<_neorv32_trap_listing>> +| 31 | r/w | **Interrupt**: `1` if the trap is caused by an interrupt (`0` if the trap is caused by an exception) |======================= @@ -545,12 +507,11 @@ See section <<_pmp_isa_extension>> for more information. [options="header",grid="rows"] |======================= | Bit | Name [C] | R/W | Function -| 7 | `PMPCFG_L` | r/w | **L**: Lock bit, prevents further write accesses, also enforces access rights in machine-mode, can only be cleared by CPU reset -| 6:5 | - | r/- | _reserved_, read as zero -| 4:3 | `PMPCFG_A_MSB` : `PMPCFG_A_LSB` | r/w | **A**: Mode configuration (`00` = OFF, `01` = TOR, `10` = NA4, `11` = NAPOT) -| 2 | `PMPCFG_X` | r/w | **X**: Execute permission -| 1 | `PMPCFG_W` | r/w | **W**: Write permission | 0 | `PMPCFG_R` | r/w | **R**: Read permission +| 1 | `PMPCFG_W` | r/w | **W**: Write permission +| 2 | `PMPCFG_X` | r/w | **X**: Execute permission +| 4:3 | `PMPCFG_A_MSB` : `PMPCFG_A_LSB` | r/w | **A**: Mode configuration (`00` = OFF, `01` = TOR, `10` = NA4, `11` = NAPOT) +| 7 | `PMPCFG_L` | r/w | **L**: Lock bit, prevents further write accesses, also enforces access rights in machine-mode, can only be cleared by CPU reset |======================= @@ -701,23 +662,22 @@ cycle even if more than one trigger event is observed. [cols="^1,^3,^1,<9"] [options="header",grid="rows"] |======================= -| Bit | Name [C] | R/W | Event Description -| 0 | `HPMCNT_EVENT_CY` | r/w | active clock cycle (CPU not in sleep mode) -| 1 | - | r/- | _not implemented, always read as zero_ -| 2 | `HPMCNT_EVENT_IR` | r/w | retired instruction (compressed or uncompressed) -| 3 | `HPMCNT_EVENT_CIR` | r/w | retired compressed instruction -| 4 | `HPMCNT_EVENT_WAIT_IF` | r/w | instruction fetch memory wait cycle -| 5 | `HPMCNT_EVENT_WAIT_II` | r/w | instruction issue pipeline wait cycle -| 6 | `HPMCNT_EVENT_WAIT_MC` | r/w | multi-cycle ALU operation wait cycle (like iterative shift operation) -| 7 | `HPMCNT_EVENT_LOAD` | r/w | memory data load operation -| 8 | `HPMCNT_EVENT_STORE` | r/w | memory data store operation -| 9 | `HPMCNT_EVENT_WAIT_LS` | r/w | load/store memory wait cycle -| 10 | `HPMCNT_EVENT_JUMP` | r/w | unconditional jump / jump-and-link -| 11 | `HPMCNT_EVENT_BRANCH` | r/w | conditional branch (_taken_ or _not taken_) -| 12 | `HPMCNT_EVENT_TBRANCH` | r/w | _taken_ conditional branch -| 13 | `HPMCNT_EVENT_TRAP` | r/w | entered trap (synchronous exception or interrupt) -| 14 | `HPMCNT_EVENT_ILLEGAL` | r/w | illegal instruction exception -| 31:15 | - | r/- | _reserved_, read as zero +| Bit | Name [C] | R/W | Event Description +| 0 | `HPMCNT_EVENT_CY` | r/w | active clock cycle (CPU not in sleep mode) +| 1 | - | r/- | _not implemented, always read as zero_ +| 2 | `HPMCNT_EVENT_IR` | r/w | retired instruction (compressed or uncompressed) +| 3 | `HPMCNT_EVENT_CIR` | r/w | retired compressed instruction +| 4 | `HPMCNT_EVENT_WAIT_IF` | r/w | instruction fetch memory wait cycle +| 5 | `HPMCNT_EVENT_WAIT_II` | r/w | instruction issue pipeline wait cycle +| 6 | `HPMCNT_EVENT_WAIT_MC` | r/w | multi-cycle ALU operation wait cycle (like iterative shift operation) +| 7 | `HPMCNT_EVENT_LOAD` | r/w | memory data load operation +| 8 | `HPMCNT_EVENT_STORE` | r/w | memory data store operation +| 9 | `HPMCNT_EVENT_WAIT_LS` | r/w | load/store memory wait cycle +| 10 | `HPMCNT_EVENT_JUMP` | r/w | unconditional jump / jump-and-link +| 11 | `HPMCNT_EVENT_BRANCH` | r/w | conditional branch (_taken_ or _not taken_) +| 12 | `HPMCNT_EVENT_TBRANCH` | r/w | _taken_ conditional branch +| 13 | `HPMCNT_EVENT_TRAP` | r/w | entered trap (synchronous exception or interrupt) +| 14 | `HPMCNT_EVENT_ILLEGAL` | r/w | illegal instruction exception |======================= @@ -779,11 +739,61 @@ counter CSRs are read-only. Any write access will raise an illegal instruction e [cols="^1,^3,^1,<9"] [options="header",grid="rows"] |======================= -| Bit | Name [C] | R/W | Event +| Bit | Name [C] | R/W | Description | 0 | `CSR_MCOUNTINHIBIT_IR` | r/w | **IR**: Set to `1` to halt `[m]instret[h]`; hardwired to zero if `Zicntr` ISA extension is disabled | 1 | - | r/- | **TM**: Hardwired to zero as `time[h]` CSRs are not implemented | 2 | `CSR_MCOUNTINHIBIT_CY` | r/w | **CY**: Set to `1` to halt `[m]cycle[h]`; hardwired to zero if `Zicntr` ISA extension is disabled -| 15:3 | `CSR_MCOUNTINHIBIT_HPM3` : `CSR_MCOUNTINHIBIT_HPM31` | r/w | **HPMx**: Set to `1` to halt `[m]hpmcount*[h]`; hardwired to zero if `Zihpm` ISA extension is disabled +| 15:3 | `CSR_MCOUNTINHIBIT_HPM3` : `CSR_MCOUNTINHIBIT_HPM15` | r/w | **HPMx**: Set to `1` to halt `[m]hpmcount*[h]`; hardwired to zero if `Zihpm` ISA extension is disabled +|======================= + + +{empty} + +[discrete] +===== **`mcyclecfg[h]`** + +[cols="<1,<8"] +[frame="topbot",grid="none"] +|======================= +| Name | Machine cycle counter privilege mode filtering +| Address | `0x321` (`mcyclecfg`) +| | `0x721` (`mcyclecfgh`) +| Reset value | `0x00000000` +| ISA | `Zicsr` & `U` (<<_smcntrpmf_isa_extension>>) +| Description | Halt cycle counter when the CPU is in a specific privilege mode. Note that `mcyclecfg` is hardwired to all-zero. +|======================= + +.`mcyclecfgh` CSR Bits +[cols="^1,^3,^1,<9"] +[options="header",grid="rows"] +|======================= +| Bit | Name [C] | R/W | Description +| 28 | `CSR_MCYCLECFGH_UINH` | r/w | **UINH**: Set to `1` to halt `[m]cycle[h]` counter when CPU is in user-mode +| 30 | `CSR_MCYCLECFGH_MINH` | r/w | **MINH**: Set to `1` to halt `[m]cycle[h]` counter when CPU is in machine-mode +|======================= + + +{empty} + +[discrete] +===== **`minstretcfg[h]`** + +[cols="<1,<8"] +[frame="topbot",grid="none"] +|======================= +| Name | Machine instret counter privilege mode filtering +| Address | `0x322` (`minstretcfg`) +| | `0x722` (`minstretcfgh`) +| Reset value | `0x00000000` +| ISA | `Zicsr` & `U` (<<_smcntrpmf_isa_extension>>) +| Description | Halt instret counter when the CPU is in a specific privilege mode. Note that `minstretcfg` is hardwired to all-zero. +|======================= + +.`minstretcfgh` CSR Bits +[cols="^1,^3,^1,<9"] +[options="header",grid="rows"] +|======================= +| Bit | Name [C] | R/W | Description +| 28 | `CSR_MINSTRETCFGH_UINH` | r/w | **UINH**: Set to `1` to halt `[m]instret[h]` counter when CPU is in user-mode +| 30 | `CSR_MINSTRETCFGH_MINH` | r/w | **MINH**: Set to `1` to halt `[m]instret[h]` counter when CPU is in machine-mode |======================= @@ -834,7 +844,7 @@ counter CSRs are read-only. Any write access will raise an illegal instruction e | Reset value | `DEFINED` | ISA | `Zicsr` | Description | The `mimpid` CSR is read-only and provides the version of the -NEORV32 as BCD-coded number (example: `mimpid` = _0x01020312_ → 01.02.03.12 → version 1.2.3.12). +NEORV32 as BCD-coded number (example: `mimpid = 0x01020312` → 01.02.03.12 → version 1.2.3.12). |======================= @@ -898,22 +908,22 @@ discover ISA sub-extensions and CPU configuration options [cols="^1,^3,^1,<5"] [options="header",grid="rows"] |======================= -| Bit | Name [C] | R/W | Function +| Bit | Name [C] | R/W | Description | 0 | `CSR_MXISA_ZICSR` | r/- | <<_zicsr_isa_extension>> available | 1 | `CSR_MXISA_ZIFENCEI` | r/- | <<_zifencei_isa_extension>> available | 2 | `CSR_MXISA_ZMMUL` | r/- | <<_zmmul_isa_extension>> available | 3 | `CSR_MXISA_ZXCFU` | r/- | <<_zxcfu_isa_extension>> available -| 4 | - | r/- | _reserved_, read as zero +| 4 | `CSR_MXISA_SMCNTRPMF` | r/- | <<_smcntrpmf_isa_extension>> available | 5 | `CSR_MXISA_ZFINX` | r/- | <<_zfinx_isa_extension>> available -| 6 | - | r/- | _reserved_, read as zero +| 6 | - | r/- | hardwired to zero | 7 | `CSR_MXISA_ZICNTR` | r/- | <<_zicntr_isa_extension>> available | 8 | `CSR_MXISA_PMP` | r/- | <<_pmp_isa_extension>> available | 9 | `CSR_MXISA_ZIHPM` | r/- | <<_zihpm_isa_extension>> available | 10 | `CSR_MXISA_SDEXT` | r/- | <<_sdext_isa_extension>> available | 11 | `CSR_MXISA_SDTRIG` | r/- | <<_sdtrig_isa_extension>> available -| 19:12 | - | r/- | _reserved_, read as zero +| 19:12 | - | r/- | hardwired to zero | 20 | `CSR_MXISA_IS_SIM` | r/- | set if CPU is being **simulated** (⚠️ not guaranteed) -| 31:21 | - | r/- | _reserved_, read as zero +| 31:21 | - | r/- | hardwired to zero | 30 | `CSR_MXISA_FASTMUL` | r/- | fast multiplication available when set (`FAST_MUL_EN`) | 31 | `CSR_MXISA_FASTSHIFT` | r/- | fast shifts available when set (`FAST_SHIFT_EN`) |======================= diff --git a/docs/figures/neorv32_processor.png b/docs/figures/neorv32_processor.png index b4569a0be..95350b859 100644 Binary files a/docs/figures/neorv32_processor.png and b/docs/figures/neorv32_processor.png differ diff --git a/rtl/core/neorv32_cpu_control.vhd b/rtl/core/neorv32_cpu_control.vhd index ad1ac0df6..3e3162e34 100644 --- a/rtl/core/neorv32_cpu_control.vhd +++ b/rtl/core/neorv32_cpu_control.vhd @@ -239,53 +239,57 @@ architecture neorv32_cpu_control_rtl of neorv32_cpu_control is -- control and status registers (CSRs) -- type csr_t is record - addr : std_ulogic_vector(11 downto 0); -- csr address - raddr : std_ulogic_vector(11 downto 0); -- simplified csr read address - we : std_ulogic; -- csr write enable - we_nxt : std_ulogic; - re : std_ulogic; -- csr read enable - re_nxt : std_ulogic; - wdata : std_ulogic_vector(XLEN-1 downto 0); -- csr write data - rdata : std_ulogic_vector(XLEN-1 downto 0); -- csr read data + addr : std_ulogic_vector(11 downto 0); -- csr address + raddr : std_ulogic_vector(11 downto 0); -- simplified csr read address + we : std_ulogic; -- csr write enable + we_nxt : std_ulogic; + re : std_ulogic; -- csr read enable + re_nxt : std_ulogic; + wdata : std_ulogic_vector(XLEN-1 downto 0); -- csr write data + rdata : std_ulogic_vector(XLEN-1 downto 0); -- csr read data -- - mstatus_mie : std_ulogic; -- machine-mode IRQ enable - mstatus_mpie : std_ulogic; -- previous machine-mode IRQ enable - mstatus_mpp : std_ulogic; -- machine previous privilege mode - mstatus_mprv : std_ulogic; -- effective privilege level for machine-mode load/stores - mstatus_tw : std_ulogic; -- do not allow user mode to execute WFI instruction when set + mstatus_mie : std_ulogic; -- machine-mode IRQ enable + mstatus_mpie : std_ulogic; -- previous machine-mode IRQ enable + mstatus_mpp : std_ulogic; -- machine previous privilege mode + mstatus_mprv : std_ulogic; -- effective privilege level for machine-mode load/stores + mstatus_tw : std_ulogic; -- do not allow user mode to execute WFI instruction when set -- - mie_msi : std_ulogic; -- machine software interrupt enable - mie_mei : std_ulogic; -- machine external interrupt enable - mie_mti : std_ulogic; -- machine timer interrupt enable - mie_firq : std_ulogic_vector(15 downto 0); -- fast interrupt enable - mip_firq_nclr : std_ulogic_vector(15 downto 0); -- clear pending FIRQ (active-low) + mie_msi : std_ulogic; -- machine software interrupt enable + mie_mei : std_ulogic; -- machine external interrupt enable + mie_mti : std_ulogic; -- machine timer interrupt enable + mie_firq : std_ulogic_vector(15 downto 0); -- fast interrupt enable + mip_firq_nclr : std_ulogic_vector(15 downto 0); -- clear pending FIRQ (active-low) -- - privilege : std_ulogic; -- current privilege mode - privilege_eff : std_ulogic; -- current *effective* privilege mode + privilege : std_ulogic; -- current privilege mode + privilege_eff : std_ulogic; -- current *effective* privilege mode -- - mepc : std_ulogic_vector(XLEN-1 downto 0); -- machine exception PC - mcause : std_ulogic_vector(5 downto 0); -- machine trap cause - mtvec : std_ulogic_vector(XLEN-1 downto 0); -- machine trap-handler base address - mtval : std_ulogic_vector(XLEN-1 downto 0); -- machine bad address or instruction - mtinst : std_ulogic_vector(XLEN-1 downto 0); -- machine trap instruction - mscratch : std_ulogic_vector(XLEN-1 downto 0); -- machine scratch register - mcounteren : std_ulogic; -- machine counter access enable (from user-mode) - mcountinhibit : std_ulogic_vector(15 downto 0); -- inhibit counter auto-increment + mepc : std_ulogic_vector(XLEN-1 downto 0); -- machine exception PC + mcause : std_ulogic_vector(5 downto 0); -- machine trap cause + mtvec : std_ulogic_vector(XLEN-1 downto 0); -- machine trap-handler base address + mtval : std_ulogic_vector(XLEN-1 downto 0); -- machine bad address or instruction + mtinst : std_ulogic_vector(XLEN-1 downto 0); -- machine trap instruction + mscratch : std_ulogic_vector(XLEN-1 downto 0); -- machine scratch register + mcounteren : std_ulogic; -- machine counter access enable (from user-mode) + mcountinhibit : std_ulogic_vector(15 downto 0); -- inhibit counter auto-increment + mcyclecfg_minh : std_ulogic; -- inhibit cycle counter when in machine-mode + mcyclecfg_uinh : std_ulogic; -- inhibit cycle counter when in user-mode + minstretcfg_minh : std_ulogic; -- inhibit instret counter when in machine-mode + minstretcfg_uinh : std_ulogic; -- inhibit instret counter when in user-mode -- - dcsr_ebreakm : std_ulogic; -- behavior of ebreak instruction in m-mode - dcsr_ebreaku : std_ulogic; -- behavior of ebreak instruction in u-mode - dcsr_step : std_ulogic; -- single-step mode - dcsr_prv : std_ulogic; -- current privilege level when entering debug mode - dcsr_cause : std_ulogic_vector(2 downto 0); -- why was debug mode entered - dcsr_rd : std_ulogic_vector(XLEN-1 downto 0); -- debug mode control and status register - dpc : std_ulogic_vector(XLEN-1 downto 0); -- mode program counter - dscratch0 : std_ulogic_vector(XLEN-1 downto 0); -- debug mode scratch register 0 + dcsr_ebreakm : std_ulogic; -- behavior of ebreak instruction in m-mode + dcsr_ebreaku : std_ulogic; -- behavior of ebreak instruction in u-mode + dcsr_step : std_ulogic; -- single-step mode + dcsr_prv : std_ulogic; -- current privilege level when entering debug mode + dcsr_cause : std_ulogic_vector(2 downto 0); -- why was debug mode entered + dcsr_rd : std_ulogic_vector(XLEN-1 downto 0); -- debug mode control and status register + dpc : std_ulogic_vector(XLEN-1 downto 0); -- mode program counter + dscratch0 : std_ulogic_vector(XLEN-1 downto 0); -- debug mode scratch register 0 -- - tdata1_exe : std_ulogic; -- enable (match) trigger - tdata1_action : std_ulogic; -- enter debug mode / ebreak exception when trigger fires - tdata1_dmode : std_ulogic; -- set to ignore tdata* CSR access from machine-mode - tdata1_rd : std_ulogic_vector(XLEN-1 downto 0); -- trigger register read-back - tdata2 : std_ulogic_vector(XLEN-1 downto 0); -- address-match register + tdata1_exe : std_ulogic; -- enable (match) trigger + tdata1_action : std_ulogic; -- enter debug mode / ebreak exception when trigger fires + tdata1_dmode : std_ulogic; -- set to ignore tdata* CSR access from machine-mode + tdata1_rd : std_ulogic_vector(XLEN-1 downto 0); -- trigger register read-back + tdata2 : std_ulogic_vector(XLEN-1 downto 0); -- address-match register end record; signal csr : csr_t; @@ -1149,13 +1153,17 @@ begin when csr_fflags_c | csr_frm_c | csr_fcsr_c => csr_reg_valid <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx); -- available if FPU implemented - -- machine trap setup/handling, counter setup, environment & information registers, etc. -- - when csr_mstatus_c | csr_mstatush_c | csr_misa_c | csr_mie_c | csr_mtvec_c | csr_mscratch_c | - csr_mepc_c | csr_mcause_c | csr_mip_c | csr_mtval_c | csr_mtinst_c | csr_mcountinhibit_c | - csr_mcounteren_c | csr_menvcfg_c | csr_menvcfgh_c | csr_mvendorid_c | csr_marchid_c | csr_mimpid_c | - csr_mhartid_c | csr_mconfigptr_c | csr_mxisa_c => + -- machine trap setup/handling, environment/information registers, etc. -- + when csr_mstatus_c | csr_mstatush_c | csr_misa_c | csr_mie_c | csr_mtvec_c | + csr_mscratch_c | csr_mepc_c | csr_mcause_c | csr_mip_c | csr_mtval_c | + csr_mtinst_c | csr_mcountinhibit_c | csr_mvendorid_c | csr_marchid_c | csr_mimpid_c | + csr_mhartid_c | csr_mconfigptr_c | csr_mxisa_c => csr_reg_valid <= '1'; -- always available (but CSR might be hardwired) + -- machine-controlled user-mode CSRs -- + when csr_mcounteren_c | csr_mcyclecfg_c | csr_minstretcfg_c | csr_mcyclecfgh_c | csr_minstretcfgh_c => + csr_reg_valid <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_U); -- available if U-mode implemented + -- physical memory protection (PMP) -- when csr_pmpcfg0_c | csr_pmpcfg1_c | csr_pmpcfg2_c | csr_pmpcfg3_c | -- configuration csr_pmpaddr0_c | csr_pmpaddr1_c | csr_pmpaddr2_c | csr_pmpaddr3_c | @@ -1609,37 +1617,41 @@ begin csr_write_access: process(rstn_i, clk_i) begin if (rstn_i = '0') then - csr.we <= '0'; - csr.privilege <= priv_mode_m_c; - csr.mstatus_mie <= '0'; - csr.mstatus_mpie <= '0'; - csr.mstatus_mpp <= '0'; - csr.mstatus_mprv <= '0'; - csr.mstatus_tw <= '0'; - csr.mie_msi <= '0'; - csr.mie_mei <= '0'; - csr.mie_mti <= '0'; - csr.mie_firq <= (others => '0'); - csr.mtvec <= (others => '0'); - csr.mscratch <= x"19880704"; - csr.mepc <= (others => '0'); - csr.mcause <= (others => '0'); - csr.mtval <= (others => '0'); - csr.mtinst <= (others => '0'); - csr.mcounteren <= '0'; - csr.mcountinhibit <= (others => '0'); - csr.mip_firq_nclr <= (others => '0'); - csr.dcsr_ebreakm <= '0'; - csr.dcsr_ebreaku <= '0'; - csr.dcsr_step <= '0'; - csr.dcsr_prv <= priv_mode_m_c; - csr.dcsr_cause <= (others => '0'); - csr.dpc <= (others => '0'); - csr.dscratch0 <= (others => '0'); - csr.tdata1_exe <= '0'; - csr.tdata1_action <= '0'; - csr.tdata1_dmode <= '0'; - csr.tdata2 <= (others => '0'); + csr.we <= '0'; + csr.privilege <= priv_mode_m_c; + csr.mstatus_mie <= '0'; + csr.mstatus_mpie <= '0'; + csr.mstatus_mpp <= '0'; + csr.mstatus_mprv <= '0'; + csr.mstatus_tw <= '0'; + csr.mie_msi <= '0'; + csr.mie_mei <= '0'; + csr.mie_mti <= '0'; + csr.mie_firq <= (others => '0'); + csr.mtvec <= (others => '0'); + csr.mscratch <= x"19880704"; + csr.mepc <= (others => '0'); + csr.mcause <= (others => '0'); + csr.mtval <= (others => '0'); + csr.mtinst <= (others => '0'); + csr.mcounteren <= '0'; + csr.mcountinhibit <= (others => '0'); + csr.mcyclecfg_minh <= '0'; + csr.mcyclecfg_uinh <= '0'; + csr.minstretcfg_minh <= '0'; + csr.minstretcfg_uinh <= '0'; + csr.mip_firq_nclr <= (others => '0'); + csr.dcsr_ebreakm <= '0'; + csr.dcsr_ebreaku <= '0'; + csr.dcsr_step <= '0'; + csr.dcsr_prv <= priv_mode_m_c; + csr.dcsr_cause <= (others => '0'); + csr.dpc <= (others => '0'); + csr.dscratch0 <= (others => '0'); + csr.tdata1_exe <= '0'; + csr.tdata1_action <= '0'; + csr.tdata1_dmode <= '0'; + csr.tdata2 <= (others => '0'); elsif rising_edge(clk_i) then -- write access? -- @@ -1710,6 +1722,18 @@ begin csr.mcountinhibit(15 downto 3) <= csr.wdata(15 downto 3); end if; + when csr_mcyclecfgh_c => -- machine cycle counter privilege mode filtering + if (CPU_EXTENSION_RISCV_Zicntr = true) then + csr.mcyclecfg_minh <= csr.wdata(30); + csr.mcyclecfg_uinh <= csr.wdata(28); + end if; + + when csr_minstretcfgh_c => -- machine instret counter privilege mode filtering + if (CPU_EXTENSION_RISCV_Zicntr = true) then + csr.minstretcfg_minh <= csr.wdata(30); + csr.minstretcfg_uinh <= csr.wdata(28); + end if; + -- debug mode CSRs -- -- -------------------------------------------------------------------- when csr_dcsr_c => -- debug mode control and status register @@ -1850,13 +1874,17 @@ begin -- no user mode -- if (CPU_EXTENSION_RISCV_U = false) then - csr.privilege <= priv_mode_m_c; - csr.mstatus_mpp <= priv_mode_m_c; - csr.mstatus_mprv <= '0'; - csr.mstatus_tw <= '0'; - csr.dcsr_ebreaku <= '0'; - csr.dcsr_prv <= '0'; - csr.mcounteren <= '0'; + csr.privilege <= priv_mode_m_c; + csr.mstatus_mpp <= priv_mode_m_c; + csr.mstatus_mprv <= '0'; + csr.mstatus_tw <= '0'; + csr.dcsr_ebreaku <= '0'; + csr.dcsr_prv <= '0'; + csr.mcounteren <= '0'; + csr.mcyclecfg_minh <= '0'; + csr.mcyclecfg_uinh <= '0'; + csr.minstretcfg_minh <= '0'; + csr.minstretcfg_uinh <= '0'; end if; -- no debug mode -- @@ -1934,11 +1962,6 @@ begin end if; end if; - -- machine configuration -- - -- -------------------------------------------------------------------- --- when csr_menvcfg_c => csr_rdata <= (others => '0'); -- hardwired to zero --- when csr_menvcfgh_c => csr_rdata <= (others => '0'); -- hardwired to zero - -- machine trap handling -- -- -------------------------------------------------------------------- when csr_mscratch_c => -- machine scratch register @@ -1976,6 +1999,21 @@ begin end loop; end if; +-- when csr_mcyclecfg_c => csr_rdata <= (others => '0'); -- hardwired to zero +-- when csr_minstretcfg_c => csr_rdata <= (others => '0'); -- hardwired to zero + + when csr_mcyclecfgh_c => -- machine cycle counter privilege mode filtering + if (CPU_EXTENSION_RISCV_Zicntr = true) then + csr_rdata(30) <= csr.mcyclecfg_minh; + csr_rdata(28) <= csr.mcyclecfg_uinh; + end if; + + when csr_minstretcfgh_c => -- machine instret counter privilege mode filtering + if (CPU_EXTENSION_RISCV_Zicntr = true) then + csr_rdata(30) <= csr.minstretcfg_minh; + csr_rdata(28) <= csr.minstretcfg_uinh; + end if; + -- HPM event select -- when csr_mhpmevent3_c => if (hpm_num_c > 00) then csr_rdata <= hpmevent_rd(03); end if; when csr_mhpmevent4_c => if (hpm_num_c > 01) then csr_rdata <= hpmevent_rd(04); end if; @@ -2061,7 +2099,7 @@ begin csr_rdata(01) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- Zifencei: instruction stream sync. csr_rdata(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zmmul); -- Zmmul: mul/div csr_rdata(03) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zxcfu); -- Zxcfu: custom RISC-V instructions --- csr_rdata(04) <= '0'; -- reserved + csr_rdata(04) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_U); -- Smcntrpmf: counter privilege mode filtering (enabled if U implemented) csr_rdata(05) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx); -- Zfinx: FPU using x registers -- csr_rdata(06) <= '0'; -- reserved csr_rdata(07) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicntr); -- Zicntr: base counters @@ -2253,9 +2291,15 @@ begin end if; end process counter_event; - -- RISC-V-specific basic counter events (for HPM and base counters) -- - cnt_event(hpmcnt_event_cy_c) <= '1' when (execute_engine.state /= SLEEP) else '0'; -- active cycle - cnt_event(hpmcnt_event_ir_c) <= '1' when (execute_engine.state = EXECUTE) else '0'; -- retired instruction + -- RISC-V-specific base counter events (for HPM and base counters) -- + cnt_event(hpmcnt_event_cy_c) <= '1' when (execute_engine.state /= SLEEP) and ( -- active cycle + ((csr.privilege = priv_mode_m_c) and (csr.mcyclecfg_minh = '0')) or -- not inhibited when in machine-mode + ((csr.privilege = priv_mode_u_c) and (csr.mcyclecfg_uinh = '0')) -- not inhibited when in user-mode + ) else '0'; + cnt_event(hpmcnt_event_ir_c) <= '1' when (execute_engine.state = EXECUTE) and ( -- retired (=executed) instruction + ((csr.privilege = priv_mode_m_c) and (csr.minstretcfg_minh = '0')) or -- not inhibited when in machine-mode + ((csr.privilege = priv_mode_u_c) and (csr.minstretcfg_uinh = '0')) -- not inhibited when in user-mode + ) else '0'; cnt_event(hpmcnt_event_tm_c) <= '0'; -- unused/reserved (time) -- NEORV32-specific counter events (for HPM counters only) -- diff --git a/rtl/core/neorv32_package.vhd b/rtl/core/neorv32_package.vhd index 93d869246..7b9c6e5d9 100644 --- a/rtl/core/neorv32_package.vhd +++ b/rtl/core/neorv32_package.vhd @@ -56,7 +56,7 @@ package neorv32_package is -- Architecture Constants ----------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- - constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01080802"; -- hardware version + constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01080803"; -- hardware version constant archid_c : natural := 19; -- official RISC-V architecture ID constant XLEN : natural := 32; -- native data path width, do not change! @@ -342,13 +342,11 @@ package neorv32_package is constant csr_mie_c : std_ulogic_vector(11 downto 0) := x"304"; constant csr_mtvec_c : std_ulogic_vector(11 downto 0) := x"305"; constant csr_mcounteren_c : std_ulogic_vector(11 downto 0) := x"306"; - -- constant csr_mstatush_c : std_ulogic_vector(11 downto 0) := x"310"; - -- machine configuration -- - constant csr_menvcfg_c : std_ulogic_vector(11 downto 0) := x"30a"; - constant csr_menvcfgh_c : std_ulogic_vector(11 downto 0) := x"31a"; -- machine counter setup -- constant csr_mcountinhibit_c : std_ulogic_vector(11 downto 0) := x"320"; + constant csr_mcyclecfg_c : std_ulogic_vector(11 downto 0) := x"321"; + constant csr_minstretcfg_c : std_ulogic_vector(11 downto 0) := x"322"; constant csr_mhpmevent3_c : std_ulogic_vector(11 downto 0) := x"323"; constant csr_mhpmevent4_c : std_ulogic_vector(11 downto 0) := x"324"; constant csr_mhpmevent5_c : std_ulogic_vector(11 downto 0) := x"325"; @@ -391,6 +389,9 @@ package neorv32_package is constant csr_pmpaddr13_c : std_ulogic_vector(11 downto 0) := x"3bd"; constant csr_pmpaddr14_c : std_ulogic_vector(11 downto 0) := x"3be"; constant csr_pmpaddr15_c : std_ulogic_vector(11 downto 0) := x"3bf"; + -- machine counter setup - continued -- + constant csr_mcyclecfgh_c : std_ulogic_vector(11 downto 0) := x"721"; + constant csr_minstretcfgh_c : std_ulogic_vector(11 downto 0) := x"722"; -- trigger module registers -- constant csr_tselect_c : std_ulogic_vector(11 downto 0) := x"7a0"; constant csr_tdata1_c : std_ulogic_vector(11 downto 0) := x"7a1"; diff --git a/sim/neorv32_tb.vhd b/sim/neorv32_tb.vhd index c54d8e991..2c889dfaa 100644 --- a/sim/neorv32_tb.vhd +++ b/sim/neorv32_tb.vhd @@ -183,7 +183,7 @@ begin if ci_mode then -- No need to send the full expectation in one big chunk check_uart(net, uart1_rx_handle, nul & nul); - check_uart(net, uart1_rx_handle, "0/54" & cr & lf); + check_uart(net, uart1_rx_handle, "0/55" & cr & lf); end if; -- Wait until all expected data has been received diff --git a/sw/example/processor_check/main.c b/sw/example/processor_check/main.c index ce563807f..76149cfde 100644 --- a/sw/example/processor_check/main.c +++ b/sw/example/processor_check/main.c @@ -161,9 +161,11 @@ int main() { // check available hardware extensions and compare with compiler flags neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch - // prepare (performance) counters + // prepare counters neorv32_cpu_csr_write(CSR_MCOUNTINHIBIT, 0); // enable counter auto increment (ALL counters) - neorv32_cpu_csr_write(CSR_MCOUNTEREN, -1); // allow counter access from user-mode code + if (neorv32_cpu_csr_read(CSR_MISA) & (1 << CSR_MISA_U)) { + neorv32_cpu_csr_write(CSR_MCOUNTEREN, -1); // allow counter access from user-mode code + } // set CMP of machine system timer MTIME to max to prevent an IRQ neorv32_mtime_set_timecmp(-1); @@ -397,6 +399,47 @@ int main() { neorv32_cpu_csr_write(CSR_MCOUNTINHIBIT, 0); + // ---------------------------------------------------------- + // Test mcyclecfg: counter privilege mode filtering + // ---------------------------------------------------------- + neorv32_cpu_csr_write(CSR_MCAUSE, mcause_never_c); + PRINT_STANDARD("[%i] mcyclecfg CSR ", cnt_test); + + if (neorv32_cpu_csr_read(CSR_MXISA) & (1 << CSR_MXISA_SMCNTRPMF)) { + cnt_test++; + + neorv32_cpu_csr_write(CSR_MCYCLECFGH, 1<mcyclecfgh CSR (r/w): Machine cycle counter privilege mode filtering + **************************************************************************/ +enum NEORV32_CSR_MCYCLECFGH_enum { + CSR_MCYCLECFGH_UINH = 28, /**< CPU mcyclecfgh CSR (28): UINH - Inhibit cycle counter when in user-mode when set (r/w) */ + CSR_MCYCLECFGH_MINH = 30 /**< CPU mcyclecfgh CSR (30): MINH - Inhibit cycle counter when in machine-mode when set (r/w) */ +}; + + +/**********************************************************************//** + * CPU minstretcfgh CSR (r/w): Machine instret counter privilege mode filtering + **************************************************************************/ +enum NEORV32_CSR_MINSTRETCFGH_enum { + CSR_MINSTRETCFGH_UINH = 28, /**< CPU minstretcfgh CSR (28): UINH - Inhibit instret counter when in user-mode when set (r/w) */ + CSR_MINSTRETCFGH_MINH = 30 /**< CPU minstretcfgh CSR (30): MINH - Inhibit instret counter when in machine-mode when set (r/w) */ +}; + + /**********************************************************************//** * CPU mie CSR (r/w): Machine interrupt enable **************************************************************************/ @@ -347,11 +369,11 @@ enum NEORV32_CSR_XISA_enum { CSR_MXISA_ZIFENCEI = 1, /**< CPU mxisa CSR (1): instruction stream sync (r/-)*/ CSR_MXISA_ZMMUL = 2, /**< CPU mxisa CSR (2): hardware mul/div (r/-)*/ CSR_MXISA_ZXCFU = 3, /**< CPU mxisa CSR (3): custom RISC-V instructions (r/-)*/ - - CSR_MXISA_ZFINX = 5, /**< CPU mxisa CSR (5): FPU using x registers, "F-alternative" (r/-)*/ + CSR_MXISA_SMCNTRPMF = 4, /**< CPU mxisa CSR (4): counter privilege mode filtering (r/-)*/ + CSR_MXISA_ZFINX = 5, /**< CPU mxisa CSR (5): FPU using x registers (r/-)*/ CSR_MXISA_ZICNTR = 7, /**< CPU mxisa CSR (7): standard instruction, cycle and time counter CSRs (r/-)*/ - CSR_MXISA_PMP = 8, /**< CPU mxisa CSR (8): physical memory protection (also "Smpmp") (r/-)*/ + CSR_MXISA_PMP = 8, /**< CPU mxisa CSR (8): physical memory protection ("Smpmp") (r/-)*/ CSR_MXISA_ZIHPM = 9, /**< CPU mxisa CSR (9): hardware performance monitors (r/-)*/ CSR_MXISA_SDEXT = 10, /**< CPU mxisa CSR (10): RISC-V debug mode (r/-)*/ CSR_MXISA_SDTRIG = 11, /**< CPU mxisa CSR (11): RISC-V trigger module (r/-)*/ diff --git a/sw/lib/source/neorv32_rte.c b/sw/lib/source/neorv32_rte.c index cdafd92a9..d375e7b3e 100644 --- a/sw/lib/source/neorv32_rte.c +++ b/sw/lib/source/neorv32_rte.c @@ -467,16 +467,17 @@ void neorv32_rte_print_hw_config(void) { // CPU sub-extensions tmp = neorv32_cpu_csr_read(CSR_MXISA); - if (tmp & (1<