From 02032d279450bfb35290582764a4b3b59f4b729d Mon Sep 17 00:00:00 2001 From: Franz Fuchs Date: Thu, 18 Apr 2024 10:26:22 +0100 Subject: [PATCH 1/4] Added STIDC and UTIDC registers --- target/riscv/cheri-archspecific-early.h | 2 ++ target/riscv/cpu.c | 2 ++ target/riscv/cpu.h | 2 ++ target/riscv/op_helper_cheri.c | 4 ++++ 4 files changed, 10 insertions(+) diff --git a/target/riscv/cheri-archspecific-early.h b/target/riscv/cheri-archspecific-early.h index b8b5e73c8e..56e56e0db4 100644 --- a/target/riscv/cheri-archspecific-early.h +++ b/target/riscv/cheri-archspecific-early.h @@ -84,11 +84,13 @@ enum CheriSCR { CheriSCR_UTDC = 5, CheriSCR_UScratchC = 6, CheriSCR_UEPCC = 7, + CheriSCR_UTIDC = 8, CheriSCR_STCC = 12, CheriSCR_STDC = 13, CheriSCR_SScratchC = 14, CheriSCR_SEPCC = 15, + CheriSCR_STIDC = 16, CheriSCR_MTCC = 28, CheriSCR_MTDC = 29, diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 98d54ba317..7242809413 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -743,11 +743,13 @@ static void riscv_cpu_reset(DeviceState *dev) null_capability(&env->UTDC); null_capability(&env->UScratchC); set_max_perms_capability(&env->UEPCC, 0); + null_capability(&env->UTIDC); // Supervisor mode trap handling set_max_perms_capability(&env->STCC, 0); null_capability(&env->STDC); null_capability(&env->SScratchC); set_max_perms_capability(&env->SEPCC, 0); + null_capability(&env->STIDC); // Machine mode trap handling set_max_perms_capability(&env->MTCC, 0); null_capability(&env->MTDC); diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 71ea82f7e2..1451b625a0 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -204,6 +204,7 @@ struct CPURISCVState { cap_register_t UTDC; // SCR 5 User trap data cap. (UTDC) cap_register_t UScratchC; // SCR 6 User scratch cap. (UScratchC) cap_register_t UEPCC; // SCR 7 User exception PC cap. (UEPCC) + cap_register_t UTIDC; // SCR 8 User thread identifier cap. (UTIDC) #endif #ifdef TARGET_CHERI @@ -211,6 +212,7 @@ struct CPURISCVState { cap_register_t STDC; // SCR 13 Supervisor trap data cap. (STDC) cap_register_t SScratchC; // SCR 14 Supervisor scratch cap. (SScratchC) cap_register_t SEPCC; // SCR 15 Supervisor exception PC cap. (SEPCC) + cap_register_t STIDC; // SCR 16 Supervisor thread identifier cap. (STIDC) #else target_ulong stvec; target_ulong sepc; diff --git a/target/riscv/op_helper_cheri.c b/target/riscv/op_helper_cheri.c index a1ed682746..eb01d82f86 100644 --- a/target/riscv/op_helper_cheri.c +++ b/target/riscv/op_helper_cheri.c @@ -89,6 +89,7 @@ struct SCRInfo { .access = U_ASR, .name = "UScratchC"}, [CheriSCR_UEPCC] = {.r = true, .w = true, .access = U_ASR, .name = "UEPCC"}, + [CheriSCR_UTIDC] = {.r = true, .w = false, .access = U_Always, .name = "UTIDC"}, [CheriSCR_STCC] = {.r = true, .w = true, .access = S_ASR, .name = "STCC"}, [CheriSCR_STDC] = {.r = true, .w = true, .access = S_ASR, .name = "STDC"}, @@ -97,6 +98,7 @@ struct SCRInfo { .access = S_ASR, .name = "SScratchC"}, [CheriSCR_SEPCC] = {.r = true, .w = true, .access = S_ASR, .name = "SEPCC"}, + [CheriSCR_STIDC] = {.r = true, .w = true, .access = S_ASR, .name = "STIDC"}, [CheriSCR_MTCC] = {.r = true, .w = true, .access = M_ASR, .name = "MTCC"}, [CheriSCR_MTDC] = {.r = true, .w = true, .access = M_ASR, .name = "MTDC"}, @@ -123,11 +125,13 @@ static inline cap_register_t *get_scr(CPUArchState *env, uint32_t index) case CheriSCR_UTDC: return &env->UTDC; case CheriSCR_UScratchC: return &env->UScratchC; case CheriSCR_UEPCC: return &env->UEPCC; + case CheriSCR_UTIDC: return &env->UTIDC; case CheriSCR_STCC: return &env->STCC; case CheriSCR_STDC: return &env->STDC; case CheriSCR_SScratchC: return &env->SScratchC; case CheriSCR_SEPCC: return &env->SEPCC; + case CheriSCR_STIDC: return &env->STIDC; case CheriSCR_MTCC: return &env->MTCC; case CheriSCR_MTDC: return &env->MTDC; From 1fd9a10d74000217ca2882fc6242140f0a769210 Mon Sep 17 00:00:00 2001 From: Franz Fuchs Date: Fri, 19 Apr 2024 08:27:36 +0100 Subject: [PATCH 2/4] Changed numbers for STIDC and UTIDC --- target/riscv/cheri-archspecific-early.h | 4 ++-- target/riscv/cpu.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/target/riscv/cheri-archspecific-early.h b/target/riscv/cheri-archspecific-early.h index 56e56e0db4..307f7d8329 100644 --- a/target/riscv/cheri-archspecific-early.h +++ b/target/riscv/cheri-archspecific-early.h @@ -80,17 +80,17 @@ enum CheriSCR { CheriSCR_PCC = 0, CheriSCR_DDC = 1, + CheriSCR_UTIDC = 3, CheriSCR_UTCC = 4, CheriSCR_UTDC = 5, CheriSCR_UScratchC = 6, CheriSCR_UEPCC = 7, - CheriSCR_UTIDC = 8, + CheriSCR_STIDC = 11, CheriSCR_STCC = 12, CheriSCR_STDC = 13, CheriSCR_SScratchC = 14, CheriSCR_SEPCC = 15, - CheriSCR_STIDC = 16, CheriSCR_MTCC = 28, CheriSCR_MTDC = 29, diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 1451b625a0..5920f3229b 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -200,19 +200,19 @@ struct CPURISCVState { #ifdef TARGET_CHERI // XXX: not implemented properly + cap_register_t UTIDC; // SCR 3 User thread identifier cap. (UTIDC) cap_register_t UTCC; // SCR 4 User trap code cap. (UTCC) cap_register_t UTDC; // SCR 5 User trap data cap. (UTDC) cap_register_t UScratchC; // SCR 6 User scratch cap. (UScratchC) cap_register_t UEPCC; // SCR 7 User exception PC cap. (UEPCC) - cap_register_t UTIDC; // SCR 8 User thread identifier cap. (UTIDC) #endif #ifdef TARGET_CHERI + cap_register_t STIDC; // SCR 11 Supervisor thread identifier cap. (STIDC) cap_register_t STCC; // SCR 12 Supervisor trap code cap. (STCC) cap_register_t STDC; // SCR 13 Supervisor trap data cap. (STDC) cap_register_t SScratchC; // SCR 14 Supervisor scratch cap. (SScratchC) cap_register_t SEPCC; // SCR 15 Supervisor exception PC cap. (SEPCC) - cap_register_t STIDC; // SCR 16 Supervisor thread identifier cap. (STIDC) #else target_ulong stvec; target_ulong sepc; From 986f0a1a38ca5d82ad7b6082daf06aa67a7574e0 Mon Sep 17 00:00:00 2001 From: Franz Fuchs Date: Wed, 8 May 2024 08:38:36 +0100 Subject: [PATCH 3/4] Added MTIDC registers and enforced ASR only on writes for xTIDC registers --- target/riscv/cheri-archspecific-early.h | 1 + target/riscv/cpu.c | 1 + target/riscv/cpu.h | 1 + target/riscv/op_helper_cheri.c | 38 ++++++++++++++++++------- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/target/riscv/cheri-archspecific-early.h b/target/riscv/cheri-archspecific-early.h index 307f7d8329..5bf6227432 100644 --- a/target/riscv/cheri-archspecific-early.h +++ b/target/riscv/cheri-archspecific-early.h @@ -92,6 +92,7 @@ enum CheriSCR { CheriSCR_SScratchC = 14, CheriSCR_SEPCC = 15, + CheriSCR_MTIDC = 27, CheriSCR_MTCC = 28, CheriSCR_MTDC = 29, CheriSCR_MScratchC = 30, diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 7242809413..ebb319f8f1 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -755,6 +755,7 @@ static void riscv_cpu_reset(DeviceState *dev) null_capability(&env->MTDC); null_capability(&env->MScratchC); set_max_perms_capability(&env->MEPCC, 0); + null_capability(&env->MTIDC); #endif /* TARGET_CHERI */ #ifdef CONFIG_DEBUG_TCG env->_pc_is_current = true; diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 5920f3229b..92d6ea68a4 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -220,6 +220,7 @@ struct CPURISCVState { target_ulong scause; #ifdef TARGET_CHERI + cap_register_t MTIDC; // SCR 27 Machine thread identifier cap. (MTIDC) cap_register_t MTCC; // SCR 28 Machine trap code cap. (MTCC) cap_register_t MTDC; // SCR 29 Machine trap data cap. (MTDC) cap_register_t MScratchC; // SCR 30 Machine scratch cap. (MScratchC) diff --git a/target/riscv/op_helper_cheri.c b/target/riscv/op_helper_cheri.c index eb01d82f86..1f7b3583fd 100644 --- a/target/riscv/op_helper_cheri.c +++ b/target/riscv/op_helper_cheri.c @@ -50,25 +50,35 @@ enum SCRAccessMode { SCR_Invalid = 0, ASR_Flag = 1, - U_Always = (PRV_U + 1) << 1, - U_ASR = U_Always | ASR_Flag, - S_Always = (PRV_S + 1) << 1, - S_ASR = S_Always | ASR_Flag, - H_Always = (PRV_H + 1) << 1, - H_ASR = H_Always | ASR_Flag, - M_Always = (PRV_M + 1) << 1, - M_ASR = M_Always | ASR_Flag, + ASR_W_Flag = 2, + U_Always = (PRV_U + 1) << 2, + U_ASR_W = U_Always | ASR_W_Flag, + U_ASR = U_ASR_W | ASR_Flag, + S_Always = (PRV_S + 1) << 2, + S_ASR_W = S_Always | ASR_W_Flag, + S_ASR = S_ASR_W | ASR_Flag, + H_Always = (PRV_H + 1) << 2, + H_ASR_W = H_Always | ASR_W_Flag, + H_ASR = H_ASR_W | ASR_Flag, + M_Always = (PRV_M + 1) << 2, + M_ASR_W = M_Always | ASR_W_Flag, + M_ASR = M_ASR_W | ASR_Flag, }; static inline int scr_min_priv(enum SCRAccessMode mode) { - return ((int)mode >> 1) - 1; + return ((int)mode >> 2) - 1; } static inline int scr_needs_asr(enum SCRAccessMode mode) { return (mode & ASR_Flag) == ASR_Flag; } +static inline int scr_needs_asr_w(enum SCRAccessMode mode) +{ + return (mode & ASR_W_Flag) == ASR_W_Flag; +} + struct SCRInfo { bool r; bool w; @@ -89,7 +99,7 @@ struct SCRInfo { .access = U_ASR, .name = "UScratchC"}, [CheriSCR_UEPCC] = {.r = true, .w = true, .access = U_ASR, .name = "UEPCC"}, - [CheriSCR_UTIDC] = {.r = true, .w = false, .access = U_Always, .name = "UTIDC"}, + [CheriSCR_UTIDC] = {.r = true, .w = true, .access = U_ASR_W, .name = "UTIDC"}, [CheriSCR_STCC] = {.r = true, .w = true, .access = S_ASR, .name = "STCC"}, [CheriSCR_STDC] = {.r = true, .w = true, .access = S_ASR, .name = "STDC"}, @@ -98,7 +108,7 @@ struct SCRInfo { .access = S_ASR, .name = "SScratchC"}, [CheriSCR_SEPCC] = {.r = true, .w = true, .access = S_ASR, .name = "SEPCC"}, - [CheriSCR_STIDC] = {.r = true, .w = true, .access = S_ASR, .name = "STIDC"}, + [CheriSCR_STIDC] = {.r = true, .w = true, .access = S_ASR_W, .name = "STIDC"}, [CheriSCR_MTCC] = {.r = true, .w = true, .access = M_ASR, .name = "MTCC"}, [CheriSCR_MTDC] = {.r = true, .w = true, .access = M_ASR, .name = "MTDC"}, @@ -107,6 +117,7 @@ struct SCRInfo { .access = M_ASR, .name = "MScratchC"}, [CheriSCR_MEPCC] = {.r = true, .w = true, .access = M_ASR, .name = "MEPCC"}, + [CheriSCR_MTIDC] = {.r = true, .w = true, .access = M_ASR_W, .name = "MTIDC"}, [CheriSCR_BSTCC] = {.r = true, .w = true, .access = H_ASR, .name= "BSTCC"}, [CheriSCR_BSTDC] = {.r = true, .w = true, .access = H_ASR, .name= "BSTCC"}, @@ -137,6 +148,7 @@ static inline cap_register_t *get_scr(CPUArchState *env, uint32_t index) case CheriSCR_MTDC: return &env->MTDC; case CheriSCR_MScratchC: return &env->MScratchC; case CheriSCR_MEPCC: return &env->MEPCC; + case CheriSCR_MTIDC: return &env->MTIDC; case CheriSCR_BSTCC: return &env->VSTCC; case CheriSCR_BSTDC: return &env->VSTDC; @@ -169,6 +181,10 @@ void HELPER(cspecialrw)(CPUArchState *env, uint32_t cd, uint32_t cs, _host_return_address); } bool can_access_sysregs = cheri_have_access_sysregs(env); + bool is_write = (cd != 0); + if (is_write && scr_needs_asr_w(mode) && !can_access_sysregs) { + raise_cheri_exception(env, CapEx_AccessSystemRegsViolation, 32 + index); + } if (scr_needs_asr(mode) && !can_access_sysregs) { raise_cheri_exception(env, CapEx_AccessSystemRegsViolation, 32 + index); } From d8b4544e02f2eccc2797dc3be9983452ecc666e3 Mon Sep 17 00:00:00 2001 From: Franz Fuchs Date: Wed, 8 May 2024 08:54:57 +0100 Subject: [PATCH 4/4] Fixed error in is_write logic --- target/riscv/op_helper_cheri.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/riscv/op_helper_cheri.c b/target/riscv/op_helper_cheri.c index 1f7b3583fd..a01fbdccf4 100644 --- a/target/riscv/op_helper_cheri.c +++ b/target/riscv/op_helper_cheri.c @@ -181,7 +181,7 @@ void HELPER(cspecialrw)(CPUArchState *env, uint32_t cd, uint32_t cs, _host_return_address); } bool can_access_sysregs = cheri_have_access_sysregs(env); - bool is_write = (cd != 0); + bool is_write = (cs != 0); if (is_write && scr_needs_asr_w(mode) && !can_access_sysregs) { raise_cheri_exception(env, CapEx_AccessSystemRegsViolation, 32 + index); }