Skip to content

Commit

Permalink
Merge branch 'ctrl-flow-insn' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
Mingkai-Li committed Aug 19, 2023
2 parents 4848bdf + ac4c3f9 commit 0d62655
Show file tree
Hide file tree
Showing 22 changed files with 469 additions and 257 deletions.
1 change: 1 addition & 0 deletions riscv/cap.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ struct cap_reg_t

cap_reg_t() {
tag = WORD_TAG_DATA;
cap.reset();
}
/*tag check*/
inline bool is_cap() const {
Expand Down
2 changes: 2 additions & 0 deletions riscv/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ class regfile_t
#define require_debug require(p->is_cap_debug_enabled())
#define require_normal_world require(p->is_secure_world() == false)
#define require_transcapstone require(p->is_pure_capstone() == false)
/*simulator status*/
#define IS_PURE_CAPSTONE (p->is_pure_capstone())
/*register operand*/
// RS1, RS2, RD are defined elsewhere, meaning the value of the register
#define insn_rs1 insn.rs1()
Expand Down
12 changes: 6 additions & 6 deletions riscv/encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -4533,12 +4533,12 @@ DECLARE_INSN(cs_cincoffsetimm, MATCH_CINCOFFSETIMM, MASK_I_S)
DECLARE_INSN(cs_ldc, MATCH_LDC, MASK_I_S)
DECLARE_INSN(cs_stc, MATCH_STC, MASK_I_S)
// ctl-flow-insn
// DECLARE_INSN(cs_call, MATCH_CALL, MASK_R_RI)
// DECLARE_INSN(cs_ret, MATCH_RETURN, MASK_R_RI)
// DECLARE_INSN(cs_cjalr, MATCH_CJALR, MASK_I_S)
// DECLARE_INSN(cs_cbnz, MATCH_CBNZ, MASK_I_S)
// DECLARE_INSN(cs_capenter, MATCH_CAPENTER, MASK_R_RI)
// DECLARE_INSN(cs_capexit, MATCH_CAPEXIT, MASK_R_RI)
DECLARE_INSN(cs_call, MATCH_CALL, MASK_R_RI)
DECLARE_INSN(cs_return, MATCH_RETURN, MASK_R_RI)
DECLARE_INSN(cs_cjalr, MATCH_CJALR, MASK_I_S)
DECLARE_INSN(cs_cbnz, MATCH_CBNZ, MASK_I_S)
DECLARE_INSN(cs_capenter, MATCH_CAPENTER, MASK_R_RI)
DECLARE_INSN(cs_capexit, MATCH_CAPEXIT, MASK_R_RI)
// ctrl-status-insn
DECLARE_INSN(cs_ccsrrw, MATCH_CCSRRW, MASK_I_S)
// debug instrucstions
Expand Down
6 changes: 2 additions & 4 deletions riscv/insn_template.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#define cap_pc_forward() \
if (p->is_secure_world()) { \
/*no need to set state.pc here, it's set by the caller*/ \
p->get_state()->cap_pc.cursor = npc; \
cap64_t cap_pc = p->get_state()->cap_pc; \
bool pc_valid_cap = p->valid_cap(cap_pc.node_id); \
if (!pc_valid_cap) throw trap_capstone_instruction_access_fault(insn.bits()); \
Expand All @@ -16,8 +18,6 @@
if (!pc_valid_perm) throw trap_capstone_instruction_access_fault(insn.bits()); \
bool pc_in_bounds = cap_pc.in_bound(insn_length(OPCODE)); \
if (!pc_in_bounds) throw trap_capstone_instruction_access_fault(insn.bits()); \
/*no need to set state.pc here, it's set by the caller*/ \
p->get_state()->cap_pc.cursor = npc; \
}

reg_t rv32i_NAME(processor_t* p, insn_t insn, reg_t pc)
Expand All @@ -27,7 +27,6 @@ reg_t rv32i_NAME(processor_t* p, insn_t insn, reg_t pc)
#include "insns/NAME.h"
trace_opcode(p, OPCODE, insn);
#undef xlen
cap_pc_forward();
return npc;
}

Expand All @@ -52,7 +51,6 @@ reg_t rv32e_NAME(processor_t* p, insn_t insn, reg_t pc)
#include "insns/NAME.h"
trace_opcode(p, OPCODE, insn);
#undef xlen
cap_pc_forward();
return npc;
}

Expand Down
78 changes: 0 additions & 78 deletions riscv/insns/call.h

This file was deleted.

3 changes: 0 additions & 3 deletions riscv/insns/capenter.h

This file was deleted.

3 changes: 0 additions & 3 deletions riscv/insns/capexit.h

This file was deleted.

46 changes: 46 additions & 0 deletions riscv/insns/cs_call.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// #include "decode.h"
// #include "trap.h"

/*exception*/
if (IS_NORMAL_WORLD())
throw trap_capstone_illegal_instruction(insn.bits());
if (!IS_CAP(insn_rs1))
throw trap_capstone_unexpected_operand_type(insn.bits());
if (!VALID_CAP(insn_rs1))
throw trap_capstone_invalid_capability(insn.bits());
if (READ_CAP(insn_rs1).type != CAP_TYPE_SEALED || READ_CAP(insn_rs1).async != CAP_ASYNC_SYNC)
throw trap_capstone_unexpected_cap_type(insn.bits());
/*call a sealed capability*/
MOVC(cra_index, insn_rs1);
/*pc*/
uint64_t tmp_addr = READ_CAP(cra_index).base;
uint128_t tmp_val;
cap64_t tmp_cap;
SET_CAP_ACCESS();
tmp_val = MMU.load_uint128(tmp_addr);
tmp_cap.from128(tmp_val);
SET_CAP_ACCESS();
MMU.store_uint128(tmp_addr, STATE.cap_pc.to128());
STATE.cap_pc = tmp_cap;
set_pc(tmp_cap.cursor);
/*ceh*/
tmp_addr += CLENBYTES;
SET_CAP_ACCESS();
tmp_val = MMU.load_uint128(tmp_addr);
tmp_cap.from128(tmp_val);
SET_CAP_ACCESS();
MMU.store_uint128(tmp_addr, STATE.ceh.cap.to128());
STATE.ceh.cap = tmp_cap;
/*csp*/
tmp_addr += CLENBYTES;
SET_CAP_ACCESS();
tmp_val = MMU.load_uint128(tmp_addr);
tmp_cap.from128(tmp_val);
SET_CAP_ACCESS();
MMU.store_uint128(tmp_addr, READ_CAP(csp_index).to128());
WRITE_CAP_DUMB(csp_index, tmp_cap);
/*cra*/
READ_CAP(cra_index).type = CAP_TYPE_SEALEDRET;
READ_CAP(cra_index).cursor = READ_CAP(cra_index).base;
READ_CAP(cra_index).reg = insn_rd;
READ_CAP(cra_index).async = CAP_ASYNC_SYNC;
118 changes: 118 additions & 0 deletions riscv/insns/cs_capenter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// #include "decode.h"
// #include "trap.h"
require_transcapstone;

/*exception*/
if (IS_SECURE_WORLD())
throw trap_capstone_illegal_instruction(insn.bits());
if (!IS_CAP(insn_rs1))
throw trap_capstone_unexpected_operand_type(insn.bits());
if (!VALID_CAP(insn_rs1))
throw trap_capstone_invalid_capability(insn.bits());
if (READ_CAP(insn_rs1).type != CAP_TYPE_SEALED)
throw trap_capstone_unexpected_cap_type(insn.bits());
/*synchronous*/
if (READ_CAP(insn_rs1).async == CAP_ASYNC_SYNC) {
MOVC(cra_index, insn_rs1);
/*normal_pc, normal_sp*/
STATE.normal_pc = STATE.pc;
if (IS_CAP(csp_index)) {
// normal_sp is a shadow register
// no RC update for the content of it
STATE.normal_sp_cap.set_cap(READ_CAP(csp_index));
}
else {
STATE.normal_sp_cap.set_data();
STATE.normal_sp = READ_REG(csp_index);
}
/*pc*/
uint64_t tmp_addr = READ_CAP(cra_index).base;
cap64_t tmp_cap;
SET_CAP_ACCESS();
uint128_t tmp_val = MMU.load_uint128(tmp_addr);
tmp_cap.from128(tmp_val);
UPDATE_RC_DOWN(STATE.cap_pc.node_id);
STATE.cap_pc = tmp_cap;
set_pc(tmp_cap.cursor);
/*ceh*/
tmp_addr += CLENBYTES;
SET_CAP_ACCESS();
tmp_val = MMU.load_uint128(tmp_addr);
tmp_cap.from128(tmp_val);
UPDATE_RC_DOWN(STATE.ceh.cap.node_id);
STATE.ceh.cap = tmp_cap;
/*csp*/
tmp_addr += CLENBYTES;
SET_CAP_ACCESS();
tmp_val = MMU.load_uint128(tmp_addr);
tmp_cap.from128(tmp_val);
if (IS_CAP(csp_index)) {
UPDATE_RC_DOWN(READ_CAP_NODE(csp_index));
}
WRITE_CAP_DUMB(csp_index, tmp_cap);
/*cra*/
READ_CAP(cra_index).type = CAP_TYPE_EXIT;
READ_CAP(cra_index).cursor = READ_CAP(cra_index).base;
/*switch_reg & exit_reg*/
STATE.switch_reg = insn_rs1;
STATE.exit_reg = insn_rd;
/*switch to secure world*/
TO_SECURE_WORLD();
}
/*asynchronous: exception/interrupt*/
else {
/*rs1 -> switch_cap*/
UPDATE_RC_DOWN(STATE.switch_cap.cap.node_id);
STATE.switch_cap.cap = READ_CAP(insn_rs1);
RESET_REG(insn_rs1);
/*normal_pc & normal_sp*/
STATE.normal_pc = STATE.pc;
if (IS_CAP(csp_index)) {
STATE.normal_sp_cap.set_cap(READ_CAP(csp_index));
}
else {
STATE.normal_sp_cap.set_data();
STATE.normal_sp = READ_REG(csp_index);
}
/*pc*/
uint64_t tmp_addr = STATE.switch_cap.cap.base;
cap64_t tmp_cap;
SET_CAP_ACCESS();
uint128_t tmp_val = MMU.load_uint128(tmp_addr);
tmp_cap.from128(tmp_val);
UPDATE_RC_UP(tmp_cap.node_id);
UPDATE_RC_DOWN(STATE.cap_pc.node_id);
STATE.cap_pc = tmp_cap;
set_pc(tmp_cap.cursor);
/*ceh*/
tmp_addr += CLENBYTES;
SET_CAP_ACCESS();
tmp_val = MMU.load_uint128(tmp_addr);
tmp_cap.from128(tmp_val);
UPDATE_RC_UP(tmp_cap.node_id);
UPDATE_RC_DOWN(STATE.ceh.cap.node_id);
STATE.ceh.cap = tmp_cap;
/*31 GPRs*/
for (uint64_t i = 1; i < 32; i++) {
tmp_addr += CLENBYTES;
SET_CAP_ACCESS();
if (GET_TAG(tmp_addr)) {
tmp_val = MMU.load_uint128(tmp_addr);
tmp_cap.from128(tmp_val);
UPDATE_RC_DOWN(READ_CAP_NODE(i));
UPDATE_RC_UP(tmp_cap.node_id);
WRITE_CAP_DUMB(i, tmp_cap);
}
else {
WRITE_DATA(i, MMU.load_uint64(tmp_addr));
}
}
/*switch_cap*/
STATE.switch_cap.cap.type = CAP_TYPE_UNINITIALIZED;
STATE.switch_cap.cap.cursor = STATE.switch_cap.cap.base;
/*switch_reg & exit_reg*/
STATE.switch_reg = insn_rs1;
STATE.exit_reg = insn_rd;
/*switch to secure world*/
TO_SECURE_WORLD();
}
52 changes: 52 additions & 0 deletions riscv/insns/cs_capexit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// #include "decode.h"
// #include "trap.h"
require_transcapstone;

/*exception*/
if (IS_NORMAL_WORLD())
throw trap_capstone_illegal_instruction(insn.bits());
if (!IS_CAP(insn_rs1) || !IS_DATA(insn_rs2))
throw trap_capstone_unexpected_operand_type(insn.bits());
if (!VALID_CAP(insn_rs1))
throw trap_capstone_invalid_capability(insn.bits());
if (READ_CAP(insn_rs1).type != CAP_TYPE_EXIT)
throw trap_capstone_unexpected_cap_type(insn.bits());
/*synchronous exit to normal world*/
cap64_t cap = READ_CAP(insn_rs1);
RESET_REG(insn_rs1);
/*pc*/
STATE.cap_pc.cursor = RS2;
uint64_t tmp_addr = cap.base;
SET_CAP_ACCESS();
MMU.store_uint128(tmp_addr, STATE.cap_pc.to128());
/*ceh*/
tmp_addr += CLENBYTES;
SET_CAP_ACCESS();
MMU.store_uint128(tmp_addr, STATE.ceh.cap.to128());
/*csp*/
tmp_addr += CLENBYTES;
SET_CAP_ACCESS();
if (IS_CAP(csp_index)) {
MMU.store_uint128(tmp_addr, READ_CAP(csp_index).to128());
}
else {
MMU.store_uint128(tmp_addr, READ_REG(csp_index));
}
/*normal_pc & normal_sp*/
set_pc(STATE.normal_pc + 4);
if (STATE.normal_sp_cap.is_cap()) {
UPDATE_RC_DOWN(READ_CAP_NODE(csp_index));
WRITE_CAP_DUMB(csp_index, STATE.normal_sp_cap.cap);
}
else {
WRITE_DATA(csp_index, STATE.normal_sp);
}
/*x[switch_reg]*/
cap.type = CAP_TYPE_SEALED;
cap.async = CAP_ASYNC_SYNC;
UPDATE_RC_DOWN(READ_CAP_NODE(STATE.switch_reg));
WRITE_CAP_DUMB(STATE.switch_reg, cap);
/*x[exit_reg]*/
WRITE_DATA(STATE.exit_reg, 0);
/*switch to normal world*/
TO_NORMAL_WORLD();
Loading

0 comments on commit 0d62655

Please sign in to comment.