aboutsummaryrefslogtreecommitdiff
path: root/c_emulator
diff options
context:
space:
mode:
authorTim Hutt <timothy.hutt@codasip.com>2024-02-02 11:56:55 +0000
committerBill McSpadden <bill@riscv.org>2024-02-05 11:22:09 -0600
commit4de2bff12d967d91dd064e4a49e25ca4785f25e3 (patch)
treeb106b03932811b9f35c4ac025a89c6f47862dc8f /c_emulator
parentd5e89a71e3a84495c1b88a7749c25fd6b9da684b (diff)
downloadsail-riscv-4de2bff12d967d91dd064e4a49e25ca4785f25e3.zip
sail-riscv-4de2bff12d967d91dd064e4a49e25ca4785f25e3.tar.gz
sail-riscv-4de2bff12d967d91dd064e4a49e25ca4785f25e3.tar.bz2
Improve PMP support
This implements a lot of missing functionality for PMPs. * Support 64 PMPs as well as 0 and 16. * Support setting PMP grain * Return correct address bits on read (some read as 0 or 1 depending on the grain and match type) * Unlock PMPs on reset * Implement pmpcfg WARL legalisation Co-authored-by: Ben Fletcher <benjamin.fletcher@codasip.com>
Diffstat (limited to 'c_emulator')
-rw-r--r--c_emulator/riscv_platform.c15
-rw-r--r--c_emulator/riscv_platform.h4
-rw-r--r--c_emulator/riscv_platform_impl.c4
-rw-r--r--c_emulator/riscv_platform_impl.h4
-rw-r--r--c_emulator/riscv_sim.c27
5 files changed, 42 insertions, 12 deletions
diff --git a/c_emulator/riscv_platform.c b/c_emulator/riscv_platform.c
index fbd63fa..253da35 100644
--- a/c_emulator/riscv_platform.c
+++ b/c_emulator/riscv_platform.c
@@ -47,6 +47,16 @@ bool sys_enable_vext(unit u)
return rv_enable_vext;
}
+uint64_t sys_pmp_count(unit u)
+{
+ return rv_pmp_count;
+}
+
+uint64_t sys_pmp_grain(unit u)
+{
+ return rv_pmp_grain;
+}
+
bool sys_enable_writable_misa(unit u)
{
return rv_enable_writable_misa;
@@ -67,11 +77,6 @@ bool plat_mtval_has_illegal_inst_bits(unit u)
return rv_mtval_has_illegal_inst_bits;
}
-bool plat_enable_pmp(unit u)
-{
- return rv_enable_pmp;
-}
-
mach_bits plat_ram_base(unit u)
{
return rv_ram_base;
diff --git a/c_emulator/riscv_platform.h b/c_emulator/riscv_platform.h
index 4b6541f..38fac2f 100644
--- a/c_emulator/riscv_platform.h
+++ b/c_emulator/riscv_platform.h
@@ -9,10 +9,12 @@ bool sys_enable_writable_misa(unit);
bool sys_enable_writable_fiom(unit);
bool sys_enable_vext(unit);
+uint64_t sys_pmp_count(unit);
+uint64_t sys_pmp_grain(unit);
+
bool plat_enable_dirty_update(unit);
bool plat_enable_misaligned_access(unit);
bool plat_mtval_has_illegal_inst_bits(unit);
-bool plat_enable_pmp(unit);
mach_bits plat_ram_base(unit);
mach_bits plat_ram_size(unit);
diff --git a/c_emulator/riscv_platform_impl.c b/c_emulator/riscv_platform_impl.c
index 15ff8ad..c2ae256 100644
--- a/c_emulator/riscv_platform_impl.c
+++ b/c_emulator/riscv_platform_impl.c
@@ -3,7 +3,9 @@
#include <stdio.h>
/* Settings of the platform implementation, with common defaults. */
-bool rv_enable_pmp = false;
+uint64_t rv_pmp_count = 0;
+uint64_t rv_pmp_grain = 0;
+
bool rv_enable_zfinx = false;
bool rv_enable_rvc = true;
bool rv_enable_next = false;
diff --git a/c_emulator/riscv_platform_impl.h b/c_emulator/riscv_platform_impl.h
index e5c562a..e3e4a96 100644
--- a/c_emulator/riscv_platform_impl.h
+++ b/c_emulator/riscv_platform_impl.h
@@ -8,7 +8,9 @@
#define DEFAULT_RSTVEC 0x00001000
-extern bool rv_enable_pmp;
+extern uint64_t rv_pmp_count;
+extern uint64_t rv_pmp_grain;
+
extern bool rv_enable_zfinx;
extern bool rv_enable_rvc;
extern bool rv_enable_next;
diff --git a/c_emulator/riscv_sim.c b/c_emulator/riscv_sim.c
index 13d1653..f3c6343 100644
--- a/c_emulator/riscv_sim.c
+++ b/c_emulator/riscv_sim.c
@@ -51,6 +51,8 @@ const char *RV32ISA = "RV32IMAC";
#define OPT_TRACE_OUTPUT 1000
#define OPT_ENABLE_WRITABLE_FIOM 1001
+#define OPT_PMP_COUNT 1002
+#define OPT_PMP_GRAIN 1003
static bool do_dump_dts = false;
static bool do_show_times = false;
@@ -119,7 +121,8 @@ char *sailcov_file = NULL;
static struct option options[] = {
{"enable-dirty-update", no_argument, 0, 'd' },
{"enable-misaligned", no_argument, 0, 'm' },
- {"enable-pmp", no_argument, 0, 'P' },
+ {"pmp-count", required_argument, 0, OPT_PMP_COUNT },
+ {"pmp-grain", required_argument, 0, OPT_PMP_GRAIN },
{"enable-next", no_argument, 0, 'N' },
{"ram-size", required_argument, 0, 'z' },
{"disable-compressed", no_argument, 0, 'C' },
@@ -236,6 +239,8 @@ static int process_args(int argc, char **argv)
{
int c;
uint64_t ram_size = 0;
+ uint64_t pmp_count = 0;
+ uint64_t pmp_grain = 0;
while (true) {
c = getopt_long(argc, argv,
"a"
@@ -281,9 +286,23 @@ static int process_args(int argc, char **argv)
fprintf(stderr, "enabling misaligned access.\n");
rv_enable_misaligned = true;
break;
- case 'P':
- fprintf(stderr, "enabling PMP support.\n");
- rv_enable_pmp = true;
+ case OPT_PMP_COUNT:
+ pmp_count = atol(optarg);
+ fprintf(stderr, "PMP count: %lld\n", pmp_count);
+ if (pmp_count != 0 && pmp_count != 16 && pmp_count != 64) {
+ fprintf(stderr, "invalid PMP count: must be 0, 16 or 64");
+ exit(1);
+ }
+ rv_pmp_count = pmp_count;
+ break;
+ case OPT_PMP_GRAIN:
+ pmp_grain = atol(optarg);
+ fprintf(stderr, "PMP grain: %lld\n", pmp_grain);
+ if (pmp_grain >= 64) {
+ fprintf(stderr, "invalid PMP grain: must less than 64");
+ exit(1);
+ }
+ rv_pmp_grain = pmp_grain;
break;
case 'C':
fprintf(stderr, "disabling RVC compressed instructions.\n");