Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ GTAGS
*.depend_raw
*.swp
*.patch
.vscode
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
url = https://gitlab.com/qemu-project/dtc.git
[submodule "roms/u-boot"]
path = roms/u-boot
url = https://gitlab.com/qemu-project/u-boot.git
url = https://gitlab.com/qemu-project-mirrors/u-boot.git
[submodule "roms/skiboot"]
path = roms/skiboot
url = https://gitlab.com/qemu-project/skiboot.git
Expand All @@ -39,7 +39,7 @@
url = https://gitlab.com/qemu-project/seabios-hppa.git
[submodule "roms/u-boot-sam460ex"]
path = roms/u-boot-sam460ex
url = https://gitlab.com/qemu-project/u-boot-sam460ex.git
url = https://gitlab.com/qemu-project-mirrors/u-boot-sam460ex.git
[submodule "tests/fp/berkeley-testfloat-3"]
path = tests/fp/berkeley-testfloat-3
url = https://gitlab.com/qemu-project/berkeley-testfloat-3.git
Expand Down
45 changes: 41 additions & 4 deletions disas/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ typedef enum {
rv_codec_css_swsp,
rv_codec_css_sdsp,
rv_codec_css_sqsp,
rv_codec_scbndsi
rv_codec_scbndsi,
rv_codec_cbo_rs1
} rv_codec;

typedef enum {
Expand Down Expand Up @@ -637,6 +638,15 @@ typedef enum {
rv_op_c_sc_rv32,
rv_op_c_lcsp_rv32,
rv_op_c_scsp_rv32,

rv_op_cbo_clean,
rv_op_cbo_clean_cap,
rv_op_cbo_flush,
rv_op_cbo_flush_cap,
rv_op_cbo_inval,
rv_op_cbo_inval_cap,
rv_op_cbo_zero,
rv_op_cbo_zero_cap
} rv_op;

/* structures */
Expand Down Expand Up @@ -765,6 +775,8 @@ static const char rv_freg_name_sym[32][5] = {
#define rv_fmt_cd_rs1 "O\tC0,1"
#define rv_fmt_rs1_offset "O\t1,o"
#define rv_fmt_rs2_offset "O\t2,o"
#define rv_fmt_cbo_rs1 "O\t1"
#define rv_fmt_cbo_cs1 "O\tC1"

/* pseudo-instruction constraints */

Expand Down Expand Up @@ -1487,7 +1499,16 @@ const rv_opcode_data opcode_data[] = {
[rv_op_cfsd] = { "cfsd", rv_codec_s, rv_fmt_frs2_offset_cs1, NULL, 0, 0, 0 },

/* 2 registers, 1 flag, 1 immediate */
[rv_op_scbndsi] = { "scbdsi", rv_codec_scbndsi, rv_fmt_cd_cs1_imm, NULL, 0, 0, 0 }
[rv_op_scbndsi] = { "scbdsi", rv_codec_scbndsi, rv_fmt_cd_cs1_imm, NULL, 0, 0, 0 },

[rv_op_cbo_clean] = { "cbo.clean", rv_codec_cbo_rs1, rv_fmt_cbo_rs1, NULL, 0, 0, 0 },
[rv_op_cbo_clean_cap] = { "cbo.clean", rv_codec_cbo_rs1, rv_fmt_cbo_cs1, NULL, 0, 0, 0 },
[rv_op_cbo_flush] = { "cbo.flush", rv_codec_cbo_rs1, rv_fmt_cbo_rs1, NULL, 0, 0, 0 },
[rv_op_cbo_flush_cap] = { "cbo.flush", rv_codec_cbo_rs1, rv_fmt_cbo_cs1, NULL, 0, 0, 0 },
[rv_op_cbo_inval] = { "cbo.inval", rv_codec_cbo_rs1, rv_fmt_cbo_rs1, NULL, 0, 0, 0 },
[rv_op_cbo_inval_cap] = { "cbo.inval", rv_codec_cbo_rs1, rv_fmt_cbo_cs1, NULL, 0, 0, 0 },
[rv_op_cbo_zero] = { "cbo.zero", rv_codec_cbo_rs1, rv_fmt_cbo_rs1, NULL, 0, 0, 0 },
[rv_op_cbo_zero_cap] = { "cbo.zero", rv_codec_cbo_rs1, rv_fmt_cbo_cs1, NULL, 0, 0, 0 }
};

/* CSR names */
Expand Down Expand Up @@ -1954,8 +1975,21 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa, int flags)
case 2:
if (isa == rv64 && flags & RISCV_DIS_FLAG_CHERI_V9) {
op = (flags & RISCV_DIS_FLAG_CAPMODE) ? rv_op_clc : rv_op_lc;
} else {
op = rv_op_lq;
} else if (((inst >> 7) & 0b11111) == 0) {
switch (((inst >> 20) & 0b111111111111)) {
case 0:
op = (flags & RISCV_DIS_FLAG_CAPMODE) ? rv_op_cbo_inval_cap : rv_op_cbo_inval;
break;
case 1:
op = (flags & RISCV_DIS_FLAG_CAPMODE) ? rv_op_cbo_clean_cap : rv_op_cbo_clean;
break;
case 2:
op = (flags & RISCV_DIS_FLAG_CAPMODE) ? rv_op_cbo_flush_cap : rv_op_cbo_flush;
break;
case 4:
op = (flags & RISCV_DIS_FLAG_CAPMODE) ? rv_op_cbo_zero_cap : rv_op_cbo_zero;
break;
}
}
break;
case 4:
Expand Down Expand Up @@ -3140,6 +3174,9 @@ static void decode_inst_operands(rv_decode *dec)
dec->imm = operand_scaled(inst) ? operand_uimm20(inst) << 4
: operand_uimm20(inst);
break;
case rv_codec_cbo_rs1:
dec->rs1 = operand_rs1(inst);
break;
};
}

Expand Down
3 changes: 1 addition & 2 deletions target/cheri-common/cheri_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

#include "cheri_defs.h"

#ifdef TARGET_CHERI
#ifdef TARGET_AARCH64
#define PRINT_CAP_MODE(cr) (unsigned)(cap_get_cursor(cr) & 1)
#else
Expand All @@ -50,8 +51,6 @@
cap_get_otype_signext(cr), cap_get_base(cr), cap_get_cursor(cr), \
cap_get_top(cr), (cr)->cr_bounds_valid

#ifdef TARGET_CHERI

static inline target_ulong cap_get_cursor(const cap_register_t *c)
{
return c->_cr_cursor;
Expand Down
22 changes: 19 additions & 3 deletions target/riscv/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,10 @@ static void rv64_codasip_a730_cpu_init(Object *obj)

qdev_prop_set_bit(DEVICE(obj), "mmu", true);
qdev_prop_set_bit(DEVICE(obj), "pmp", false);
qdev_prop_set_bit(DEVICE(obj), "zicbom", true);
qdev_prop_set_bit(DEVICE(obj), "x-zba", true);
qdev_prop_set_bit(DEVICE(obj), "x-zbb", true);
qdev_prop_set_bit(DEVICE(obj), "x-zbs", true);

/*
* QEMU 6.x has no support for limiting the virtual addressing modes
Expand Down Expand Up @@ -293,8 +297,7 @@ static void rv32_codasip_l730_cpu_init(Object *obj)
*/
set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);

/* This CPU supports priv v1.12. QEMU 6.x supports only up to 1.11. */
set_priv_version(env, PRIV_VERSION_1_11_0);
set_priv_version(env, PRIV_VERSION_1_12_0);
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
qdev_prop_set_bit(DEVICE(obj), "pmp", false);
}
Expand Down Expand Up @@ -1029,6 +1032,14 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)

#ifdef TARGET_CHERI
if (cpu->cfg.ext_cheri) {
if (env->misa_ext & RVJ) {
/*
* According to the Cheri RISC-V spec, the J extension is incompatible
* with capability pointer mode.
*/
error_setg(errp, "J extension is not supported on Cheri systems.");
return;
}
set_feature(env, RISCV_FEATURE_CHERI);
#ifdef TARGET_CHERI_RISCV_V9
/* Non-standard extensions present */
Expand Down Expand Up @@ -1193,7 +1204,12 @@ static const char *riscv_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname)
if (strcmp(xmlname, "riscv-csr.xml") == 0) {
return cpu->dyn_csr_xml;
}
#ifdef TARGET_CHERI
#ifdef TARGET_CHERI_RISCV_STD
if (strcmp(xmlname, "riscv-ycsr.xml") == 0) {
return cpu->dyn_ycsr_xml;
}
#endif
#ifdef TARGET_CHERI_RISCV_V9
if (strcmp(xmlname, "riscv-scr.xml") == 0) {
return cpu->dyn_scr_xml;
}
Expand Down
5 changes: 4 additions & 1 deletion target/riscv/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,9 @@ struct RISCVCPU {
CPURISCVState env;

char *dyn_csr_xml;
#ifdef TARGET_CHERI
#ifdef TARGET_CHERI_RISCV_STD
char *dyn_ycsr_xml;
#elif defined(TARGET_CHERI_RISCV_V9)
char *dyn_scr_xml;
#endif

Expand Down Expand Up @@ -904,6 +906,7 @@ typedef void (*riscv_csr_cap_write_fn)(CPURISCVState *env,
#define CSR_OP_IA_CONVERSION (1 << 1)
#define CSR_OP_UPDATE_SCADDR (1 << 2)
#define CSR_OP_EXTENDED_REG (1 << 3)
#define CSR_OP_IS_CODE_PTR (1 << 4)
#define CSR_OP_DIRECT_WRITE (0)

struct _csr_cap_ops {
Expand Down
34 changes: 33 additions & 1 deletion target/riscv/cpu_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,20 @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
return TRANSLATE_SUCCESS;
}

static void pte_print(target_ulong pte, int level)
{
qemu_log_mask(
CPU_LOG_MMU, "PTE - " TARGET_FMT_lx " %s%s%s%s%s%s%s%s%s%s %d\n", pte,
#if defined(TARGET_CHERI) && !defined(TARGET_RISCV32)
pte & PTE_CRG ? "CRG" : "", pte & PTE_CW ? "CW" : "",
#else
"", "",
#endif
pte & PTE_R ? "R" : "", pte & PTE_W ? "W" : "", pte & PTE_X ? "X" : "",
pte & PTE_A ? "A" : "", pte & PTE_U ? "U" : "", pte & PTE_D ? "D" : "",
pte & PTE_A ? "A" : "", pte & PTE_V ? "V" : "", level);
}

/* get_physical_address - get the physical address for this virtual address
*
* Do a page table walk to obtain the physical address corresponding to a
Expand Down Expand Up @@ -731,7 +745,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
} else {
pte = address_space_ldq(cs->as, pte_addr, attrs, &res);
}

pte_print(pte, i);
if (res != MEMTX_OK) {
qemu_log_mask(
CPU_LOG_MMU,
Expand Down Expand Up @@ -1655,6 +1669,24 @@ void riscv_cpu_do_interrupt(CPUState *cs)
target_ulong mtvec = GET_SPECIAL_REG_ADDR(env, mtvec, mtvecc);
target_ulong new_pc = (mtvec >> 2 << 2) +
((async && (mtvec & 3) == 1) ? cause * 4 : 0);

/*
* This checks that the exception handler is at the same address that
* caused the exception and the exception is related to reading an
* instruction. We know up front that going into the handler will
* trigger the same exception again.
*/
if ((cause == RISCV_EXCP_INST_ACCESS_FAULT ||
cause == RISCV_EXCP_ILLEGAL_INST) &&
#ifdef TARGET_CHERI
cap_exactly_equal(&env->pcc, &env->mtvecc)) {
#else
(env->pc == new_pc)) {
#endif
error_report("*** infinite exception loop detected ***");
exit(EXIT_FAILURE);
}

riscv_update_pc_for_exc_handler(env, &env->mtvecc, new_pc);
riscv_cpu_set_mode(env, PRV_M);
}
Expand Down
24 changes: 16 additions & 8 deletions target/riscv/csr.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ static RISCVException read_fcsr(CPURISCVState *env, int csrno,
{
*val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
| (env->frm << FSR_RD_SHIFT);
if (vs(env, csrno) >= 0) {
if (vs(env, csrno) == RISCV_EXCP_NONE) {
*val |= (env->vxrm << FSR_VXRM_SHIFT)
| (env->vxsat << FSR_VXSAT_SHIFT);
}
Expand All @@ -334,7 +334,7 @@ static RISCVException write_fcsr(CPURISCVState *env, int csrno,
LRI_CSR_ACCESS);
#endif
env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
if (vs(env, csrno) >= 0) {
if (vs(env, csrno) == RISCV_EXCP_NONE) {
env->vxrm = (val & FSR_VXRM) >> FSR_VXRM_SHIFT;
env->vxsat = (val & FSR_VXSAT) >> FSR_VXSAT_SHIFT;
}
Expand Down Expand Up @@ -2223,6 +2223,11 @@ static void write_xtvecc(CPURISCVState *env, riscv_csr_cap_ops *csr_cap_info,
auth = csr;
}

if (!cap_has_perms(auth, CAP_ACCESS_SYS_REGS)) {
warn_report_once("Setting %s without ASR permission (likely a bug)",
csr_cap_info->name);
}

if (!is_representable_cap_with_addr(auth, new_tvec + RISCV_HICAUSE * 4)) {
error_report("Attempting to set vector register with unrepresentable "
"range (0x" TARGET_FMT_lx ") on %s: " PRINT_CAP_FMTSTR
Expand Down Expand Up @@ -2832,13 +2837,15 @@ static riscv_csr_cap_ops csr_cap_ops[] = {
{ "mscratchc", CSR_MSCRATCHC, read_capcsr_reg, write_cap_csr_reg,
CSR_OP_DIRECT_WRITE | CSR_OP_EXTENDED_REG },
{ "mtvecc", CSR_MTVECC, read_capcsr_reg, write_xtvecc,
CSR_OP_IA_CONVERSION | CSR_OP_UPDATE_SCADDR | CSR_OP_EXTENDED_REG },
CSR_OP_IA_CONVERSION | CSR_OP_UPDATE_SCADDR | CSR_OP_EXTENDED_REG |
CSR_OP_IS_CODE_PTR },
{ "stvecc", CSR_STVECC, read_capcsr_reg, write_xtvecc,
CSR_OP_IA_CONVERSION | CSR_OP_UPDATE_SCADDR | CSR_OP_EXTENDED_REG },
CSR_OP_IA_CONVERSION | CSR_OP_UPDATE_SCADDR | CSR_OP_EXTENDED_REG |
CSR_OP_IS_CODE_PTR },
{ "mepcc", CSR_MEPCC, read_xepcc, write_xepcc,
CSR_OP_IA_CONVERSION | CSR_OP_EXTENDED_REG },
CSR_OP_IA_CONVERSION | CSR_OP_EXTENDED_REG | CSR_OP_IS_CODE_PTR },
{ "sepcc", CSR_SEPCC, read_xepcc, write_xepcc,
CSR_OP_IA_CONVERSION | CSR_OP_EXTENDED_REG },
CSR_OP_IA_CONVERSION | CSR_OP_EXTENDED_REG | CSR_OP_IS_CODE_PTR },
{ "sscratchc", CSR_SSCRATCHC, read_capcsr_reg, write_cap_csr_reg,
CSR_OP_DIRECT_WRITE | CSR_OP_EXTENDED_REG },
{ "ddc", CSR_DDC, read_capcsr_reg, write_cap_csr_reg,
Expand All @@ -2852,11 +2859,12 @@ static riscv_csr_cap_ops csr_cap_ops[] = {
{ "vstidc", CSR_VSTIDC, read_capcsr_reg, write_cap_csr_reg,
CSR_OP_DIRECT_WRITE | CSR_OP_EXTENDED_REG },
{ "vsepcc", CSR_VSEPCC, read_xepcc, write_xepcc,
CSR_OP_IA_CONVERSION | CSR_OP_EXTENDED_REG },
CSR_OP_IA_CONVERSION | CSR_OP_EXTENDED_REG | CSR_OP_IS_CODE_PTR },
{ "vsscratchc", CSR_VSSCRATCHC, read_capcsr_reg, write_cap_csr_reg,
CSR_OP_DIRECT_WRITE | CSR_OP_EXTENDED_REG },
{ "vstvecc", CSR_VSTVECC, read_capcsr_reg, write_xtvecc,
CSR_OP_IA_CONVERSION | CSR_OP_UPDATE_SCADDR | CSR_OP_EXTENDED_REG },
CSR_OP_IA_CONVERSION | CSR_OP_UPDATE_SCADDR | CSR_OP_EXTENDED_REG |
CSR_OP_IS_CODE_PTR },
#ifdef TARGET_CHERI_RISCV_V9
/* For backwards compatibility add the *tdc registers */
{ "mtdc", CSR_MTDC, read_capcsr_reg, write_cap_csr_reg,
Expand Down
Loading
Loading