csr: Fix pmpaddr and perf counter privileges (#698)

* pmp: Fix csr

- Add proper granularity (G=1)
- Disallow NA4
- Fix read of pmpaddr
- Add PMP benchmark to CI

Signed-off-by: Moritz Schneider <moritz.schneider@inf.ethz.ch>

* Fix mcounteren/scounteren CSR logic

The privilege check should verify that the __current__ privilege level has
access to the counter CSRs. Before it checked if the privilege level of
the CSR instruction has access to the counters. Essentially, the m-mode
could not access any counter csr if mcounteren/scounteren was not set.

* Fix pmpcfg csr incase of NA4

The next pmpcfg register value needs to be set to the previous value if
NA4 is selected.
This commit is contained in:
Moritz Schneider 2021-07-29 12:59:35 +02:00 committed by GitHub
parent 5fd9bec354
commit 5a19ef678f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 20 deletions

View file

@ -1,7 +1,7 @@
#!/bin/bash
set -e
ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
VERSION="7cc76ea83b4f827596158c8ba0763e93da65de8f"
VERSION="eeacd5507db7a0f50ca8c4f27aff220fcbb60bdf"
cd $ROOT/tmp

View file

@ -5,3 +5,4 @@ qsort.riscv
rsort.riscv
towers.riscv
vvadd.riscv
pmp.riscv

View file

@ -283,26 +283,26 @@ module csr_regfile import ariane_pkg::*; #(
riscv::CSR_PMPCFG0: csr_rdata = pmpcfg_q[7:0];
riscv::CSR_PMPCFG2: csr_rdata = pmpcfg_q[15:8];
// PMPADDR
// Important: we only support granularity 8 bytes (G=2)
// Important: we only support granularity 8 bytes (G=1)
// -> last bit of pmpaddr must be set 0/1 based on the mode:
// NA4, NAPOT: 1
// TOR, OFF: 0
riscv::CSR_PMPADDR0: csr_rdata = {10'b0, pmpaddr_q[0][riscv::PLEN-3:1], (pmpcfg_q[0].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)};
riscv::CSR_PMPADDR1: csr_rdata = {10'b0, pmpaddr_q[1][riscv::PLEN-3:1], (pmpcfg_q[1].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)};
riscv::CSR_PMPADDR2: csr_rdata = {10'b0, pmpaddr_q[2][riscv::PLEN-3:1], (pmpcfg_q[2].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)};
riscv::CSR_PMPADDR3: csr_rdata = {10'b0, pmpaddr_q[3][riscv::PLEN-3:1], (pmpcfg_q[3].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)};
riscv::CSR_PMPADDR4: csr_rdata = {10'b0, pmpaddr_q[4][riscv::PLEN-3:1], (pmpcfg_q[4].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)};
riscv::CSR_PMPADDR5: csr_rdata = {10'b0, pmpaddr_q[5][riscv::PLEN-3:1], (pmpcfg_q[5].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)};
riscv::CSR_PMPADDR6: csr_rdata = {10'b0, pmpaddr_q[6][riscv::PLEN-3:1], (pmpcfg_q[6].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)};
riscv::CSR_PMPADDR7: csr_rdata = {10'b0, pmpaddr_q[7][riscv::PLEN-3:1], (pmpcfg_q[7].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)};
riscv::CSR_PMPADDR8: csr_rdata = {10'b0, pmpaddr_q[8][riscv::PLEN-3:1], (pmpcfg_q[8].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)};
riscv::CSR_PMPADDR9: csr_rdata = {10'b0, pmpaddr_q[9][riscv::PLEN-3:1], (pmpcfg_q[9].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)};
riscv::CSR_PMPADDR10: csr_rdata = {10'b0, pmpaddr_q[10][riscv::PLEN-3:1], (pmpcfg_q[10].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)};
riscv::CSR_PMPADDR11: csr_rdata = {10'b0, pmpaddr_q[11][riscv::PLEN-3:1], (pmpcfg_q[11].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)};
riscv::CSR_PMPADDR12: csr_rdata = {10'b0, pmpaddr_q[12][riscv::PLEN-3:1], (pmpcfg_q[12].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)};
riscv::CSR_PMPADDR13: csr_rdata = {10'b0, pmpaddr_q[13][riscv::PLEN-3:1], (pmpcfg_q[13].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)};
riscv::CSR_PMPADDR14: csr_rdata = {10'b0, pmpaddr_q[14][riscv::PLEN-3:1], (pmpcfg_q[14].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)};
riscv::CSR_PMPADDR15: csr_rdata = {10'b0, pmpaddr_q[15][riscv::PLEN-3:1], (pmpcfg_q[15].addr_mode[1] == 1'b1 ? 1'b1 : 1'b0)};
riscv::CSR_PMPADDR0: csr_rdata = {10'b0, pmpaddr_q[ 0][riscv::PLEN-3:1], (pmpcfg_q[ 0].addr_mode[1] == 1'b1 ? pmpaddr_q[ 0][0] : 1'b0)};
riscv::CSR_PMPADDR1: csr_rdata = {10'b0, pmpaddr_q[ 1][riscv::PLEN-3:1], (pmpcfg_q[ 1].addr_mode[1] == 1'b1 ? pmpaddr_q[ 1][0] : 1'b0)};
riscv::CSR_PMPADDR2: csr_rdata = {10'b0, pmpaddr_q[ 2][riscv::PLEN-3:1], (pmpcfg_q[ 2].addr_mode[1] == 1'b1 ? pmpaddr_q[ 2][0] : 1'b0)};
riscv::CSR_PMPADDR3: csr_rdata = {10'b0, pmpaddr_q[ 3][riscv::PLEN-3:1], (pmpcfg_q[ 3].addr_mode[1] == 1'b1 ? pmpaddr_q[ 3][0] : 1'b0)};
riscv::CSR_PMPADDR4: csr_rdata = {10'b0, pmpaddr_q[ 4][riscv::PLEN-3:1], (pmpcfg_q[ 4].addr_mode[1] == 1'b1 ? pmpaddr_q[ 4][0] : 1'b0)};
riscv::CSR_PMPADDR5: csr_rdata = {10'b0, pmpaddr_q[ 5][riscv::PLEN-3:1], (pmpcfg_q[ 5].addr_mode[1] == 1'b1 ? pmpaddr_q[ 5][0] : 1'b0)};
riscv::CSR_PMPADDR6: csr_rdata = {10'b0, pmpaddr_q[ 6][riscv::PLEN-3:1], (pmpcfg_q[ 6].addr_mode[1] == 1'b1 ? pmpaddr_q[ 6][0] : 1'b0)};
riscv::CSR_PMPADDR7: csr_rdata = {10'b0, pmpaddr_q[ 7][riscv::PLEN-3:1], (pmpcfg_q[ 7].addr_mode[1] == 1'b1 ? pmpaddr_q[ 7][0] : 1'b0)};
riscv::CSR_PMPADDR8: csr_rdata = {10'b0, pmpaddr_q[ 8][riscv::PLEN-3:1], (pmpcfg_q[ 8].addr_mode[1] == 1'b1 ? pmpaddr_q[ 8][0] : 1'b0)};
riscv::CSR_PMPADDR9: csr_rdata = {10'b0, pmpaddr_q[ 9][riscv::PLEN-3:1], (pmpcfg_q[ 9].addr_mode[1] == 1'b1 ? pmpaddr_q[ 9][0] : 1'b0)};
riscv::CSR_PMPADDR10: csr_rdata = {10'b0, pmpaddr_q[10][riscv::PLEN-3:1], (pmpcfg_q[10].addr_mode[1] == 1'b1 ? pmpaddr_q[10][0] : 1'b0)};
riscv::CSR_PMPADDR11: csr_rdata = {10'b0, pmpaddr_q[11][riscv::PLEN-3:1], (pmpcfg_q[11].addr_mode[1] == 1'b1 ? pmpaddr_q[11][0] : 1'b0)};
riscv::CSR_PMPADDR12: csr_rdata = {10'b0, pmpaddr_q[12][riscv::PLEN-3:1], (pmpcfg_q[12].addr_mode[1] == 1'b1 ? pmpaddr_q[12][0] : 1'b0)};
riscv::CSR_PMPADDR13: csr_rdata = {10'b0, pmpaddr_q[13][riscv::PLEN-3:1], (pmpcfg_q[13].addr_mode[1] == 1'b1 ? pmpaddr_q[13][0] : 1'b0)};
riscv::CSR_PMPADDR14: csr_rdata = {10'b0, pmpaddr_q[14][riscv::PLEN-3:1], (pmpcfg_q[14].addr_mode[1] == 1'b1 ? pmpaddr_q[14][0] : 1'b0)};
riscv::CSR_PMPADDR15: csr_rdata = {10'b0, pmpaddr_q[15][riscv::PLEN-3:1], (pmpcfg_q[15].addr_mode[1] == 1'b1 ? pmpaddr_q[15][0] : 1'b0)};
default: read_access_exception = 1'b1;
endcase
end
@ -925,7 +925,7 @@ module csr_regfile import ariane_pkg::*; #(
// check counter-enabled counter CSR accesses
// counter address range is C00 to C1F
if (csr_addr_i inside {[riscv::CSR_CYCLE:riscv::CSR_HPM_COUNTER_31]}) begin
unique case (csr_addr.csr_decode.priv_lvl)
unique case (priv_lvl_o)
riscv::PRIV_LVL_M: privilege_violation = 1'b0;
riscv::PRIV_LVL_S: privilege_violation = ~mcounteren_q[csr_addr_i[4:0]];
riscv::PRIV_LVL_U: privilege_violation = ~mcounteren_q[csr_addr_i[4:0]] & ~scounteren_q[csr_addr_i[4:0]];
@ -1152,7 +1152,11 @@ module csr_regfile import ariane_pkg::*; #(
// pmp
for(int i = 0; i < 16; i++) begin
if(i < NrPMPEntries) begin
pmpcfg_q[i] <= pmpcfg_d[i];
// We only support >=8-byte granularity, NA4 is disabled
if(pmpcfg_q[i].addr_mode != riscv::NA4)
pmpcfg_q[i] <= pmpcfg_d[i];
else
pmpcfg_q[i] <= pmpcfg_q[i];
pmpaddr_q[i] <= pmpaddr_d[i];
end else begin
pmpcfg_q[i] <= '0;