Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix PMP locking #363

Merged
merged 4 commits into from
Jul 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ mimpid = 0x01040312 => 01.04.03.12 => Version 01.04.03.12 => v1.4.3.12


| Date (*dd.mm.yyyy*) | Version | Comment |
|:----------:|:-------:|:--------|
|:-------------------:|:-------:|:--------|
| 11.07.2022 | 1.7.3.8 | **physical memory protection(PMP)**: locking entry `i` in TOR mode will now also prevent write access to `pmpaddr(i-1)` (RISC-V compatibility); [#363](https://github.com/stnolting/neorv32/pull/363) |
| 09.07.2022 | 1.7.3.7 | :bug: fixed **bootloader's** byte order when using the flash for application storage: :warning: was BIG-endian, is now also LITTLE-endian; [#362](https://github.com/stnolting/neorv32/pull/362) |
| 08.07.2022 | 1.7.3.6 | :test_tube: added burst mode option to **XIP module** to accelerate consecutive flash read accesses; :warning: fixed XIP endianness: was BIG-endian and is now LITTLE-endian; [#361](https://github.com/stnolting/neorv32/pull/361) |
| 08.07.2022 | 1.7.3.5 | Update "raw" executable generation options of makefile and image generator; [#360](https://github.com/stnolting/neorv32/pull/360) |
Expand Down
15 changes: 5 additions & 10 deletions docs/datasheet/cpu.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,18 @@ has been moved to a separate repository: https://github.com/stnolting/neorv32-ve
:sectnums:
==== RISC-V Incompatibility Issues and Limitations

This list shows the currently identified issues regarding full RISC-V-compatibility. Note that most
of the cases listed below are "special cases" that should not occur in "normal" programs. However,
some of these incompatibilities can be circumvented using software emulation (for example for
handling unaligned memory accesses).
This list shows the currently identified issues regarding full RISC-V-compatibility.

.Read-Only "Read-Write" CSRs
[IMPORTANT]
The NEORV32 <<_misa>> and <<_mtval>> CSRs are _read-only_ - the RISC-V specs. declare
these registers as _read/write_. Any machine-mode write access to them is ignored and will _not_
The NEORV32 <<_misa>> and <<_mtval>> CSRs are _read-only_ - the RISC-V specs. declares
these registers to be _read/write_. Any machine-mode write access to them is ignored and will _not_
cause any exceptions or side-effects to maintain RISC-V compatibility.

.Physical Memory Protection
.Physical Memory Protection (PMP)
[IMPORTANT]
The RISC-V-compatible NEORV32 <<_machine_physical_memory_protection_csrs>> only implements the **TOR**
(top of region) mode and only up to 16 PMP regions. Furthermore, the <<_pmpcfg>>'s _lock bits_ only lock
the according PMP entry and not the entries below. All region rules are checked in parallel **without**
prioritization so for identical memory regions the most restrictive PMP rule will be enforced.
(top of region) mode and only up to 16 PMP regions.

.No Hardware Support of Misaligned Memory Accesses
[WARNING]
Expand Down
3 changes: 2 additions & 1 deletion docs/datasheet/cpu_csr.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,8 @@ as the MSB is hardwired to zero
|=======================

[WARNING]
Setting the lock bit `L` **only locks the according PMP entry** and not the PMP entries below!
Setting the lock bit `L` and setting TOR mode in `pmpcfg(i)` will also lock write access to `pmpaddr(i-1)`.
See the RISC-V specs. for more information.


:sectnums!:
Expand Down
51 changes: 29 additions & 22 deletions rtl/core/neorv32_cpu_control.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -1872,30 +1872,37 @@ begin

-- physical memory protection --
-- --------------------------------------------------------------------
-- R/W: pmpcfg* - PMP configuration registers --
if (csr.addr(11 downto 2) = csr_class_pmpcfg_c) then -- pmp configuration CSR class
for i in 0 to PMP_NUM_REGIONS-1 loop
if (csr.addr(1 downto 0) = std_ulogic_vector(to_unsigned(i/4, 2))) then
if (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpcfg entry
csr.pmpcfg(i)(0) <= csr.wdata((i mod 4)*8+0); -- R - read
csr.pmpcfg(i)(1) <= csr.wdata((i mod 4)*8+1); -- W - write
csr.pmpcfg(i)(2) <= csr.wdata((i mod 4)*8+2); -- X - execute
csr.pmpcfg(i)(3) <= csr.wdata((i mod 4)*8+3); -- A_L - mode low [TOR-mode only!]
csr.pmpcfg(i)(4) <= '0'; -- A_H - mode high [TOR-mode only!]
csr.pmpcfg(i)(5) <= '0'; -- reserved
csr.pmpcfg(i)(6) <= '0'; -- reserved
csr.pmpcfg(i)(7) <= csr.wdata((i mod 4)*8+7); -- L (locked / also enforce in machine-mode)
if (PMP_NUM_REGIONS > 0) then
-- R/W: pmpcfg* - PMP configuration registers --
if (csr.addr(11 downto 2) = csr_class_pmpcfg_c) then -- pmp configuration CSR class
for i in 0 to PMP_NUM_REGIONS-1 loop
if (csr.addr(1 downto 0) = std_ulogic_vector(to_unsigned(i/4, 2))) then
if (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpcfg entry
csr.pmpcfg(i)(0) <= csr.wdata((i mod 4)*8+0); -- R - read
csr.pmpcfg(i)(1) <= csr.wdata((i mod 4)*8+1); -- W - write
csr.pmpcfg(i)(2) <= csr.wdata((i mod 4)*8+2); -- X - execute
csr.pmpcfg(i)(3) <= csr.wdata((i mod 4)*8+3); -- A_L - mode low [TOR-mode only!]
csr.pmpcfg(i)(4) <= '0'; -- A_H - mode high [TOR-mode only!]
csr.pmpcfg(i)(5) <= '0'; -- reserved
csr.pmpcfg(i)(6) <= '0'; -- reserved
csr.pmpcfg(i)(7) <= csr.wdata((i mod 4)*8+7); -- L (locked / also enforce in machine-mode)
end if;
end if;
end loop; -- i (pmpcfg entry)
end if;
-- R/W: pmpaddr* - PMP address registers --
if (csr.addr(11 downto 4) = csr_class_pmpaddr_c) then
for i in 0 to PMP_NUM_REGIONS-2 loop
if (csr.addr(3 downto 0) = std_ulogic_vector(to_unsigned(i, 4))) and (csr.pmpcfg(i)(7) = '0') and -- unlocked access
((csr.pmpcfg(i+1)(7) = '0') or (csr.pmpcfg(i+1)(3) = '0')) then -- pmpcfg(i+1) not "LOCKED TOR" [TOR-mode only!]
csr.pmpaddr(i) <= csr.wdata(data_width_c-3 downto index_size_f(PMP_MIN_GRANULARITY)-2);
end if;
end loop; -- i (PMP regions)
-- very last entry --
if (csr.addr(3 downto 0) = std_ulogic_vector(to_unsigned(PMP_NUM_REGIONS-1, 4))) and (csr.pmpcfg(PMP_NUM_REGIONS-1)(7) = '0') then -- unlocked access
csr.pmpaddr(PMP_NUM_REGIONS-1) <= csr.wdata(data_width_c-3 downto index_size_f(PMP_MIN_GRANULARITY)-2);
end if;
end loop; -- i (pmpcfg entry)
end if;
-- R/W: pmpaddr* - PMP address registers --
if (csr.addr(11 downto 4) = csr_class_pmpaddr_c) then
for i in 0 to PMP_NUM_REGIONS-1 loop
if (csr.addr(3 downto 0) = std_ulogic_vector(to_unsigned(i, 4))) and (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpaddr access
csr.pmpaddr(i) <= csr.wdata(data_width_c-3 downto index_size_f(PMP_MIN_GRANULARITY)-2);
end if;
end loop; -- i (PMP regions)
end if;
end if;

-- machine counter setup --
Expand Down
2 changes: 1 addition & 1 deletion rtl/core/neorv32_package.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ package neorv32_package is
-- Architecture Constants (do not modify!) ------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant data_width_c : natural := 32; -- native data path width - do not change!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070307"; -- NEORV32 version - no touchy!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070308"; -- NEORV32 version - no touchy!
constant archid_c : natural := 19; -- official RISC-V architecture ID - hands off!

-- Check if we're inside the Matrix -------------------------------------------------------
Expand Down