forked from riscv/sail-riscv
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix incorrect behaviour with INT_MAX pmpaddr
This fixes a bug if you set `pmpaddr` to `ones()`. For NAPOT it would return `(zeros(), zeros())`. For NA4 it would return `(ones(), zeros())`. In both cases it will match no addresses, whereas it should match all memory, or the top 4 bytes respectively. A test is included for NAPOT that fails before and passes afterwards. Fixes riscv#739
- Loading branch information
Showing
3 changed files
with
94 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -78,6 +78,7 @@ set(common_deps | |
|
||
set(tests | ||
"test_hello_world.c" | ||
"test_max_pmp.c" | ||
"test_minstret.S" | ||
) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#include "common/runtime.h" | ||
|
||
#include <stdint.h> | ||
#include <stddef.h> | ||
|
||
#define PMPCFG_L (0b1 << 7) | ||
#define PMPCFG_NA4 (0b10 << 3) | ||
#define PMPCFG_NAPOT (0b11 << 3) | ||
#define PMPCFG_X (0b1 << 2) | ||
#define PMPCFG_W (0b1 << 1) | ||
#define PMPCFG_R (0b1 << 0) | ||
|
||
#define MSTATUS_MPP_MASK (0b11 << 11) | ||
#define MSTATUS_MPRV_MASK (0b1 << 17) | ||
|
||
int main() | ||
{ | ||
printf("Testing 0xFF..FF PMP addresses\n"); | ||
|
||
uint_xlen_t ones = UINT_XLEN_MAX; | ||
|
||
asm volatile("csrw pmpaddr0, %[ones]" : : [ones] "r"(ones)); | ||
|
||
// Set mstatus.MPP and mstatus.MPRV so that loads/stores are | ||
// done in user mode. If they don't match the pmp then | ||
// they'll fail. | ||
uint_xlen_t mpp = MSTATUS_MPP_MASK; | ||
uint_xlen_t mprv = MSTATUS_MPRV_MASK; | ||
asm volatile("csrc mstatus, %[mpp];" | ||
"csrs mstatus, %[mprv];" | ||
: | ||
: [mpp] "r"(mpp), [mprv] "r"(mprv)); | ||
|
||
uint_xlen_t pmpcfg_napot = PMPCFG_NAPOT | PMPCFG_X | PMPCFG_W | PMPCFG_R; | ||
|
||
asm volatile("csrw pmpcfg0, %[cfg]" : : [cfg] "r"(pmpcfg_napot)); | ||
|
||
// Access memory to test loads/stores. | ||
printf("Passed\n"); | ||
return 0; | ||
} |