Skip to content

Commit 50f1cbc

Browse files
authored
Merge pull request #363 from stnolting/pmp_locking
Fix PMP locking
2 parents 31af2f9 + 339fba0 commit 50f1cbc

File tree

5 files changed

+39
-35
lines changed

5 files changed

+39
-35
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ mimpid = 0x01040312 => 01.04.03.12 => Version 01.04.03.12 => v1.4.3.12
3131

3232

3333
| Date (*dd.mm.yyyy*) | Version | Comment |
34-
|:----------:|:-------:|:--------|
34+
|:-------------------:|:-------:|:--------|
35+
| 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) |
3536
| 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) |
3637
| 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) |
3738
| 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) |

docs/datasheet/cpu.adoc

+5-10
Original file line numberDiff line numberDiff line change
@@ -64,23 +64,18 @@ has been moved to a separate repository: https://github.com/stnolting/neorv32-ve
6464
:sectnums:
6565
==== RISC-V Incompatibility Issues and Limitations
6666

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

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

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

8580
.No Hardware Support of Misaligned Memory Accesses
8681
[WARNING]

docs/datasheet/cpu_csr.adoc

+2-1
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,8 @@ as the MSB is hardwired to zero
539539
|=======================
540540

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

544545

545546
:sectnums!:

rtl/core/neorv32_cpu_control.vhd

+29-22
Original file line numberDiff line numberDiff line change
@@ -1872,30 +1872,37 @@ begin
18721872

18731873
-- physical memory protection --
18741874
-- --------------------------------------------------------------------
1875-
-- R/W: pmpcfg* - PMP configuration registers --
1876-
if (csr.addr(11 downto 2) = csr_class_pmpcfg_c) then -- pmp configuration CSR class
1877-
for i in 0 to PMP_NUM_REGIONS-1 loop
1878-
if (csr.addr(1 downto 0) = std_ulogic_vector(to_unsigned(i/4, 2))) then
1879-
if (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpcfg entry
1880-
csr.pmpcfg(i)(0) <= csr.wdata((i mod 4)*8+0); -- R - read
1881-
csr.pmpcfg(i)(1) <= csr.wdata((i mod 4)*8+1); -- W - write
1882-
csr.pmpcfg(i)(2) <= csr.wdata((i mod 4)*8+2); -- X - execute
1883-
csr.pmpcfg(i)(3) <= csr.wdata((i mod 4)*8+3); -- A_L - mode low [TOR-mode only!]
1884-
csr.pmpcfg(i)(4) <= '0'; -- A_H - mode high [TOR-mode only!]
1885-
csr.pmpcfg(i)(5) <= '0'; -- reserved
1886-
csr.pmpcfg(i)(6) <= '0'; -- reserved
1887-
csr.pmpcfg(i)(7) <= csr.wdata((i mod 4)*8+7); -- L (locked / also enforce in machine-mode)
1875+
if (PMP_NUM_REGIONS > 0) then
1876+
-- R/W: pmpcfg* - PMP configuration registers --
1877+
if (csr.addr(11 downto 2) = csr_class_pmpcfg_c) then -- pmp configuration CSR class
1878+
for i in 0 to PMP_NUM_REGIONS-1 loop
1879+
if (csr.addr(1 downto 0) = std_ulogic_vector(to_unsigned(i/4, 2))) then
1880+
if (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpcfg entry
1881+
csr.pmpcfg(i)(0) <= csr.wdata((i mod 4)*8+0); -- R - read
1882+
csr.pmpcfg(i)(1) <= csr.wdata((i mod 4)*8+1); -- W - write
1883+
csr.pmpcfg(i)(2) <= csr.wdata((i mod 4)*8+2); -- X - execute
1884+
csr.pmpcfg(i)(3) <= csr.wdata((i mod 4)*8+3); -- A_L - mode low [TOR-mode only!]
1885+
csr.pmpcfg(i)(4) <= '0'; -- A_H - mode high [TOR-mode only!]
1886+
csr.pmpcfg(i)(5) <= '0'; -- reserved
1887+
csr.pmpcfg(i)(6) <= '0'; -- reserved
1888+
csr.pmpcfg(i)(7) <= csr.wdata((i mod 4)*8+7); -- L (locked / also enforce in machine-mode)
1889+
end if;
18881890
end if;
1891+
end loop; -- i (pmpcfg entry)
1892+
end if;
1893+
-- R/W: pmpaddr* - PMP address registers --
1894+
if (csr.addr(11 downto 4) = csr_class_pmpaddr_c) then
1895+
for i in 0 to PMP_NUM_REGIONS-2 loop
1896+
if (csr.addr(3 downto 0) = std_ulogic_vector(to_unsigned(i, 4))) and (csr.pmpcfg(i)(7) = '0') and -- unlocked access
1897+
((csr.pmpcfg(i+1)(7) = '0') or (csr.pmpcfg(i+1)(3) = '0')) then -- pmpcfg(i+1) not "LOCKED TOR" [TOR-mode only!]
1898+
csr.pmpaddr(i) <= csr.wdata(data_width_c-3 downto index_size_f(PMP_MIN_GRANULARITY)-2);
1899+
end if;
1900+
end loop; -- i (PMP regions)
1901+
-- very last entry --
1902+
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
1903+
csr.pmpaddr(PMP_NUM_REGIONS-1) <= csr.wdata(data_width_c-3 downto index_size_f(PMP_MIN_GRANULARITY)-2);
18891904
end if;
1890-
end loop; -- i (pmpcfg entry)
1891-
end if;
1892-
-- R/W: pmpaddr* - PMP address registers --
1893-
if (csr.addr(11 downto 4) = csr_class_pmpaddr_c) then
1894-
for i in 0 to PMP_NUM_REGIONS-1 loop
1895-
if (csr.addr(3 downto 0) = std_ulogic_vector(to_unsigned(i, 4))) and (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpaddr access
1896-
csr.pmpaddr(i) <= csr.wdata(data_width_c-3 downto index_size_f(PMP_MIN_GRANULARITY)-2);
1897-
end if;
1898-
end loop; -- i (PMP regions)
1905+
end if;
18991906
end if;
19001907

19011908
-- machine counter setup --

rtl/core/neorv32_package.vhd

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ package neorv32_package is
6868
-- Architecture Constants (do not modify!) ------------------------------------------------
6969
-- -------------------------------------------------------------------------------------------
7070
constant data_width_c : natural := 32; -- native data path width - do not change!
71-
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070307"; -- NEORV32 version - no touchy!
71+
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070308"; -- NEORV32 version - no touchy!
7272
constant archid_c : natural := 19; -- official RISC-V architecture ID - hands off!
7373

7474
-- Check if we're inside the Matrix -------------------------------------------------------

0 commit comments

Comments
 (0)