Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added STIDC and UTIDC registers #247

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions target/riscv/cheri-archspecific-early.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,19 @@ enum CheriSCR {
CheriSCR_PCC = 0,
CheriSCR_DDC = 1,

CheriSCR_UTIDC = 3,
CheriSCR_UTCC = 4,
CheriSCR_UTDC = 5,
CheriSCR_UScratchC = 6,
CheriSCR_UEPCC = 7,

CheriSCR_STIDC = 11,
CheriSCR_STCC = 12,
CheriSCR_STDC = 13,
CheriSCR_SScratchC = 14,
CheriSCR_SEPCC = 15,

CheriSCR_MTIDC = 27,
CheriSCR_MTCC = 28,
CheriSCR_MTDC = 29,
CheriSCR_MScratchC = 30,
Expand Down
3 changes: 3 additions & 0 deletions target/riscv/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -756,16 +756,19 @@ 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);
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;
Expand Down
6 changes: 6 additions & 0 deletions target/riscv/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,13 +201,15 @@ 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)
#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)
Expand All @@ -219,6 +221,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)
Expand Down Expand Up @@ -834,16 +837,19 @@ static inline cap_register_t *riscv_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;
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;
Expand Down
83 changes: 51 additions & 32 deletions target/riscv/op_helper_cheri.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,24 +49,36 @@

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_R_Flag = 1,
ASR_W_Flag = 2,
ASR_RW_Flag = ASR_W_Flag | ASR_R_Flag,
U_Always = (PRV_U + 1) << 2,
U_ASR_W = U_Always | ASR_W_Flag,
U_ASR_RW = U_ASR_W | ASR_R_Flag,
S_Always = (PRV_S + 1) << 2,
S_ASR_W = S_Always | ASR_W_Flag,
S_ASR_RW = S_ASR_W | ASR_R_Flag,
H_Always = (PRV_H + 1) << 2,
H_ASR_W = H_Always | ASR_W_Flag,
H_ASR_RW = H_ASR_W | ASR_R_Flag,
M_Always = (PRV_M + 1) << 2,
M_ASR_W = M_Always | ASR_W_Flag,
M_ASR_RW = M_ASR_W | ASR_R_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)

static inline int scr_needs_asr_r(enum SCRAccessMode mode)
{
return (mode & ASR_R_Flag) == ASR_R_Flag;
}

static inline int scr_needs_asr_w(enum SCRAccessMode mode)
{
return (mode & ASR_Flag) == ASR_Flag;
return (mode & ASR_W_Flag) == ASR_W_Flag;
}

struct SCRInfo {
Expand All @@ -82,35 +94,38 @@ struct SCRInfo {
[CheriSCR_PCC] = {.r = true, .w = false, .access = U_Always, .name = "PCC"},
[CheriSCR_DDC] = {.r = true, .w = true, .access = U_Always, .name = "DDC"},

[CheriSCR_UTCC] = {.r = true, .w = true, .access = U_ASR, .name = "UTCC"},
[CheriSCR_UTDC] = {.r = true, .w = true, .access = U_ASR, .name = "UTDC"},
[CheriSCR_UTCC] = {.r = true, .w = true, .access = U_ASR_RW, .name = "UTCC"},
[CheriSCR_UTDC] = {.r = true, .w = true, .access = U_ASR_RW, .name = "UTDC"},
[CheriSCR_UScratchC] = {.r = true,
.w = true,
.access = U_ASR,
.access = U_ASR_RW,
.name = "UScratchC"},
[CheriSCR_UEPCC] = {.r = true, .w = true, .access = U_ASR, .name = "UEPCC"},
[CheriSCR_UEPCC] = {.r = true, .w = true, .access = U_ASR_RW, .name = "UEPCC"},
[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"},
[CheriSCR_STCC] = {.r = true, .w = true, .access = S_ASR_RW, .name = "STCC"},
[CheriSCR_STDC] = {.r = true, .w = true, .access = S_ASR_RW, .name = "STDC"},
[CheriSCR_SScratchC] = {.r = true,
.w = true,
.access = S_ASR,
.access = S_ASR_RW,
.name = "SScratchC"},
[CheriSCR_SEPCC] = {.r = true, .w = true, .access = S_ASR, .name = "SEPCC"},
[CheriSCR_SEPCC] = {.r = true, .w = true, .access = S_ASR_RW, .name = "SEPCC"},
[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"},
[CheriSCR_MTCC] = {.r = true, .w = true, .access = M_ASR_RW, .name = "MTCC"},
[CheriSCR_MTDC] = {.r = true, .w = true, .access = M_ASR_RW, .name = "MTDC"},
[CheriSCR_MScratchC] = {.r = true,
.w = true,
.access = M_ASR,
.access = M_ASR_RW,
.name = "MScratchC"},
[CheriSCR_MEPCC] = {.r = true, .w = true, .access = M_ASR, .name = "MEPCC"},
[CheriSCR_MEPCC] = {.r = true, .w = true, .access = M_ASR_RW, .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"},
[CheriSCR_BSScratchC] = {.r = true, .w = true, .access = H_ASR,
[CheriSCR_BSTCC] = {.r = true, .w = true, .access = H_ASR_RW, .name= "BSTCC"},
[CheriSCR_BSTDC] = {.r = true, .w = true, .access = H_ASR_RW, .name= "BSTCC"},
[CheriSCR_BSScratchC] = {.r = true, .w = true, .access = H_ASR_RW,
.name= "BSTCC"},
[CheriSCR_BSEPCC] = {.r = true, .w = true, .access = H_ASR, .name= "BSTCC"},
[CheriSCR_BSEPCC] = {.r = true, .w = true, .access = H_ASR_RW, .name= "BSTCC"},
};

#ifdef CONFIG_TCG_LOG_INSTR
Expand All @@ -132,12 +147,16 @@ void HELPER(cspecialrw)(CPUArchState *env, uint32_t cd, uint32_t cs,

assert(index <= 31 && "Bug in translator?");
enum SCRAccessMode mode = scr_info[index].access;
if (mode == SCR_Invalid || (cs != 0 && !scr_info[index].w)) {
bool is_write = cs != 0;
bool is_read = cd != 0;
if (mode == SCR_Invalid || (is_write && !scr_info[index].w)) {
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST,
_host_return_address);
}
bool can_access_sysregs = cheri_have_access_sysregs(env);
if (scr_needs_asr(mode) && !can_access_sysregs) {
if (((is_write && scr_needs_asr_w(mode)) ||
(is_read && scr_needs_asr_r(mode))) &&
!can_access_sysregs) {
raise_cheri_exception(env, CapEx_AccessSystemRegsViolation, 32 + index);
}
if (scr_min_priv(mode) > env->priv) {
Expand All @@ -146,7 +165,7 @@ void HELPER(cspecialrw)(CPUArchState *env, uint32_t cd, uint32_t cs,
cap_register_t *scr = riscv_get_scr(env, index);
// Make a copy of the write value in case cd == cs
cap_register_t new_val = *get_readonly_capreg(env, cs);
if (cd != 0) {
if (is_read) {
assert(scr_info[index].r && "Bug? Should be readable");
// For xEPCC we clear the low address bit(s) when reading to match xEPC.
// See helper_sret/helper_mret for more context.
Expand Down Expand Up @@ -177,7 +196,7 @@ void HELPER(cspecialrw)(CPUArchState *env, uint32_t cd, uint32_t cs,
break;
}
}
if (cs != 0) {
if (is_write) {
assert(scr_info[index].w && "Bug? Should be writable");
#ifdef CONFIG_TCG_LOG_INSTR
if (qemu_log_instr_enabled(env)) {
Expand Down
Loading