``acl_remove`` commands are deprecated with no replacement. Authorization
for VNC should be performed using the pluggable QAuthZ objects.
-Guest Emulator ISAs
--------------------
-
-RISC-V ISA privledge specification version 1.09.1 (since 4.1)
-'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
-
-The RISC-V ISA privledge specification version 1.09.1 has been deprecated.
-QEMU supports both the newer version 1.10.0 and the ratified version 1.11.0, these
-should be used instead of the 1.09.1 version.
-
System emulator CPUS
--------------------
The ``[hub_id name]`` parameter tuple of the 'hostfwd_add' and
'hostfwd_remove' HMP commands has been replaced by ``netdev_id``.
+Guest Emulator ISAs
+-------------------
+
+RISC-V ISA privledge specification version 1.09.1 (removed in 5.1)
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The RISC-V ISA privledge specification version 1.09.1 has been removed.
+QEMU supports both the newer version 1.10.0 and the ratified version 1.11.0, these
+should be used instead of the 1.09.1 version.
+
System emulator CPUS
--------------------
priv_version = PRIV_VERSION_1_11_0;
} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
priv_version = PRIV_VERSION_1_10_0;
- } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.9.1")) {
- priv_version = PRIV_VERSION_1_09_1;
} else {
error_setg(errp,
"Unsupported privilege spec version '%s'",
RISCV_FEATURE_MISA
};
-#define PRIV_VERSION_1_09_1 0x00010901
#define PRIV_VERSION_1_10_0 0x00011000
#define PRIV_VERSION_1_11_0 0x00011100
mxr = get_field(env->vsstatus, MSTATUS_MXR);
}
- if (env->priv_ver >= PRIV_VERSION_1_10_0) {
- if (first_stage == true) {
- if (use_background) {
- base = (hwaddr)get_field(env->vsatp, SATP_PPN) << PGSHIFT;
- vm = get_field(env->vsatp, SATP_MODE);
- } else {
- base = (hwaddr)get_field(env->satp, SATP_PPN) << PGSHIFT;
- vm = get_field(env->satp, SATP_MODE);
- }
- widened = 0;
+ if (first_stage == true) {
+ if (use_background) {
+ base = (hwaddr)get_field(env->vsatp, SATP_PPN) << PGSHIFT;
+ vm = get_field(env->vsatp, SATP_MODE);
} else {
- base = (hwaddr)get_field(env->hgatp, HGATP_PPN) << PGSHIFT;
- vm = get_field(env->hgatp, HGATP_MODE);
- widened = 2;
- }
- sum = get_field(env->mstatus, MSTATUS_SUM);
- switch (vm) {
- case VM_1_10_SV32:
- levels = 2; ptidxbits = 10; ptesize = 4; break;
- case VM_1_10_SV39:
- levels = 3; ptidxbits = 9; ptesize = 8; break;
- case VM_1_10_SV48:
- levels = 4; ptidxbits = 9; ptesize = 8; break;
- case VM_1_10_SV57:
- levels = 5; ptidxbits = 9; ptesize = 8; break;
- case VM_1_10_MBARE:
- *physical = addr;
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- return TRANSLATE_SUCCESS;
- default:
- g_assert_not_reached();
+ base = (hwaddr)get_field(env->satp, SATP_PPN) << PGSHIFT;
+ vm = get_field(env->satp, SATP_MODE);
}
- } else {
widened = 0;
- base = (hwaddr)(env->sptbr) << PGSHIFT;
- sum = !get_field(env->mstatus, MSTATUS_PUM);
- vm = get_field(env->mstatus, MSTATUS_VM);
- switch (vm) {
- case VM_1_09_SV32:
- levels = 2; ptidxbits = 10; ptesize = 4; break;
- case VM_1_09_SV39:
- levels = 3; ptidxbits = 9; ptesize = 8; break;
- case VM_1_09_SV48:
- levels = 4; ptidxbits = 9; ptesize = 8; break;
- case VM_1_09_MBARE:
- *physical = addr;
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- return TRANSLATE_SUCCESS;
- default:
- g_assert_not_reached();
- }
+ } else {
+ base = (hwaddr)get_field(env->hgatp, HGATP_PPN) << PGSHIFT;
+ vm = get_field(env->hgatp, HGATP_MODE);
+ widened = 2;
+ }
+ sum = get_field(env->mstatus, MSTATUS_SUM);
+ switch (vm) {
+ case VM_1_10_SV32:
+ levels = 2; ptidxbits = 10; ptesize = 4; break;
+ case VM_1_10_SV39:
+ levels = 3; ptidxbits = 9; ptesize = 8; break;
+ case VM_1_10_SV48:
+ levels = 4; ptidxbits = 9; ptesize = 8; break;
+ case VM_1_10_SV57:
+ levels = 5; ptidxbits = 9; ptesize = 8; break;
+ case VM_1_10_MBARE:
+ *physical = addr;
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ return TRANSLATE_SUCCESS;
+ default:
+ g_assert_not_reached();
}
CPUState *cs = env_cpu(env);
int page_fault_exceptions;
if (first_stage) {
page_fault_exceptions =
- (env->priv_ver >= PRIV_VERSION_1_10_0) &&
get_field(env->satp, SATP_MODE) != VM_1_10_MBARE &&
!pmp_violation;
} else {
}
s = env->mstatus;
- s = set_field(s, MSTATUS_SPIE, env->priv_ver >= PRIV_VERSION_1_10_0 ?
- get_field(s, MSTATUS_SIE) : get_field(s, MSTATUS_UIE << env->priv));
+ s = set_field(s, MSTATUS_SPIE, get_field(s, MSTATUS_SIE));
s = set_field(s, MSTATUS_SPP, env->priv);
s = set_field(s, MSTATUS_SIE, 0);
env->mstatus = s;
}
s = env->mstatus;
- s = set_field(s, MSTATUS_MPIE, env->priv_ver >= PRIV_VERSION_1_10_0 ?
- get_field(s, MSTATUS_MIE) : get_field(s, MSTATUS_UIE << env->priv));
+ s = set_field(s, MSTATUS_MPIE, get_field(s, MSTATUS_MIE));
s = set_field(s, MSTATUS_MPP, env->priv);
s = set_field(s, MSTATUS_MIE, 0);
env->mstatus = s;
#if !defined(CONFIG_USER_ONLY)
CPUState *cs = env_cpu(env);
RISCVCPU *cpu = RISCV_CPU(cs);
- uint32_t ctr_en = ~0u;
if (!cpu->cfg.ext_counters) {
/* The Counters extensions is not enabled */
return -1;
}
-
- /*
- * The counters are always enabled at run time on newer priv specs, as the
- * CSR has changed from controlling that the counters can be read to
- * controlling that the counters increment.
- */
- if (env->priv_ver > PRIV_VERSION_1_09_1) {
- return 0;
- }
-
- if (env->priv < PRV_M) {
- ctr_en &= env->mcounteren;
- }
- if (env->priv < PRV_S) {
- ctr_en &= env->scounteren;
- }
- if (!(ctr_en & (1u << (csrno & 31)))) {
- return -1;
- }
#endif
return 0;
}
(1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) |
(1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) |
(1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT));
-static const target_ulong sstatus_v1_9_mask = SSTATUS_SIE | SSTATUS_SPIE |
- SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
- SSTATUS_SUM | SSTATUS_SD;
static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD;
static const target_ulong vsip_writable_mask = MIP_VSSIP;
#if defined(TARGET_RISCV32)
-static const char valid_vm_1_09[16] = {
- [VM_1_09_MBARE] = 1,
- [VM_1_09_SV32] = 1,
-};
static const char valid_vm_1_10[16] = {
[VM_1_10_MBARE] = 1,
[VM_1_10_SV32] = 1
};
#elif defined(TARGET_RISCV64)
-static const char valid_vm_1_09[16] = {
- [VM_1_09_MBARE] = 1,
- [VM_1_09_SV39] = 1,
- [VM_1_09_SV48] = 1,
-};
static const char valid_vm_1_10[16] = {
[VM_1_10_MBARE] = 1,
[VM_1_10_SV39] = 1,
static int validate_vm(CPURISCVState *env, target_ulong vm)
{
- return (env->priv_ver >= PRIV_VERSION_1_10_0) ?
- valid_vm_1_10[vm & 0xf] : valid_vm_1_09[vm & 0xf];
+ return valid_vm_1_10[vm & 0xf];
}
static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
int dirty;
/* flush tlb on mstatus fields that affect VM */
- if (env->priv_ver <= PRIV_VERSION_1_09_1) {
- if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP |
- MSTATUS_MPRV | MSTATUS_SUM | MSTATUS_VM)) {
- tlb_flush(env_cpu(env));
- }
- mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
- MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
- MSTATUS_MPP | MSTATUS_MXR |
- (validate_vm(env, get_field(val, MSTATUS_VM)) ?
- MSTATUS_VM : 0);
+ if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
+ MSTATUS_MPRV | MSTATUS_SUM)) {
+ tlb_flush(env_cpu(env));
}
- if (env->priv_ver >= PRIV_VERSION_1_10_0) {
- if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
- MSTATUS_MPRV | MSTATUS_SUM)) {
- tlb_flush(env_cpu(env));
- }
- mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
- MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
- MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
- MSTATUS_TW;
+ mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
+ MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
+ MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
+ MSTATUS_TW;
#if defined(TARGET_RISCV64)
- /*
- * RV32: MPV and MTL are not in mstatus. The current plan is to
- * add them to mstatush. For now, we just don't support it.
- */
- mask |= MSTATUS_MTL | MSTATUS_MPV;
+ /*
+ * RV32: MPV and MTL are not in mstatus. The current plan is to
+ * add them to mstatush. For now, we just don't support it.
+ */
+ mask |= MSTATUS_MTL | MSTATUS_MPV;
#endif
- }
mstatus = (mstatus & ~mask) | (val & mask);
static int read_mcounteren(CPURISCVState *env, int csrno, target_ulong *val)
{
- if (env->priv_ver < PRIV_VERSION_1_10_0) {
- return -1;
- }
*val = env->mcounteren;
return 0;
}
static int write_mcounteren(CPURISCVState *env, int csrno, target_ulong val)
{
- if (env->priv_ver < PRIV_VERSION_1_10_0) {
- return -1;
- }
env->mcounteren = val;
return 0;
}
/* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */
static int read_mscounteren(CPURISCVState *env, int csrno, target_ulong *val)
{
- if (env->priv_ver > PRIV_VERSION_1_09_1
- && env->priv_ver < PRIV_VERSION_1_11_0) {
+ if (env->priv_ver < PRIV_VERSION_1_11_0) {
return -1;
}
*val = env->mcounteren;
/* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */
static int write_mscounteren(CPURISCVState *env, int csrno, target_ulong val)
{
- if (env->priv_ver > PRIV_VERSION_1_09_1
- && env->priv_ver < PRIV_VERSION_1_11_0) {
+ if (env->priv_ver < PRIV_VERSION_1_11_0) {
return -1;
}
env->mcounteren = val;
return 0;
}
-static int read_mucounteren(CPURISCVState *env, int csrno, target_ulong *val)
-{
- if (env->priv_ver > PRIV_VERSION_1_09_1) {
- return -1;
- }
- *val = env->scounteren;
- return 0;
-}
-
-static int write_mucounteren(CPURISCVState *env, int csrno, target_ulong val)
-{
- if (env->priv_ver > PRIV_VERSION_1_09_1) {
- return -1;
- }
- env->scounteren = val;
- return 0;
-}
-
/* Machine Trap Handling */
static int read_mscratch(CPURISCVState *env, int csrno, target_ulong *val)
{
/* Supervisor Trap Setup */
static int read_sstatus(CPURISCVState *env, int csrno, target_ulong *val)
{
- target_ulong mask = ((env->priv_ver >= PRIV_VERSION_1_10_0) ?
- sstatus_v1_10_mask : sstatus_v1_9_mask);
+ target_ulong mask = (sstatus_v1_10_mask);
*val = env->mstatus & mask;
return 0;
}
static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val)
{
- target_ulong mask = ((env->priv_ver >= PRIV_VERSION_1_10_0) ?
- sstatus_v1_10_mask : sstatus_v1_9_mask);
+ target_ulong mask = (sstatus_v1_10_mask);
target_ulong newval = (env->mstatus & ~mask) | (val & mask);
return write_mstatus(env, CSR_MSTATUS, newval);
}
static int read_scounteren(CPURISCVState *env, int csrno, target_ulong *val)
{
- if (env->priv_ver < PRIV_VERSION_1_10_0) {
- return -1;
- }
*val = env->scounteren;
return 0;
}
static int write_scounteren(CPURISCVState *env, int csrno, target_ulong val)
{
- if (env->priv_ver < PRIV_VERSION_1_10_0) {
- return -1;
- }
env->scounteren = val;
return 0;
}
{
if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
*val = 0;
- } else if (env->priv_ver >= PRIV_VERSION_1_10_0) {
- if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
- return -1;
- } else {
- *val = env->satp;
- }
+ return 0;
+ }
+
+ if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+ return -1;
} else {
- *val = env->sptbr;
+ *val = env->satp;
}
+
return 0;
}
if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
return 0;
}
- if (env->priv_ver <= PRIV_VERSION_1_09_1 && (val ^ env->sptbr)) {
- tlb_flush(env_cpu(env));
- env->sptbr = val & (((target_ulong)
- 1 << (TARGET_PHYS_ADDR_SPACE_BITS - PGSHIFT)) - 1);
- }
- if (env->priv_ver >= PRIV_VERSION_1_10_0 &&
- validate_vm(env, get_field(val, SATP_MODE)) &&
+ if (validate_vm(env, get_field(val, SATP_MODE)) &&
((val ^ env->satp) & (SATP_MODE | SATP_ASID | SATP_PPN)))
{
if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
[CSR_MSTATUSH] = { any, read_mstatush, write_mstatush },
#endif
- /* Legacy Counter Setup (priv v1.9.1) */
- [CSR_MUCOUNTEREN] = { any, read_mucounteren, write_mucounteren },
[CSR_MSCOUNTEREN] = { any, read_mscounteren, write_mscounteren },
/* Machine Trap Handling */
static bool trans_sfence_vma(DisasContext *ctx, arg_sfence_vma *a)
{
#ifndef CONFIG_USER_ONLY
- if (ctx->priv_ver >= PRIV_VERSION_1_10_0) {
- gen_helper_tlb_flush(cpu_env);
- return true;
- }
+ gen_helper_tlb_flush(cpu_env);
+ return true;
#endif
return false;
}
static bool trans_sfence_vm(DisasContext *ctx, arg_sfence_vm *a)
{
-#ifndef CONFIG_USER_ONLY
- if (ctx->priv_ver <= PRIV_VERSION_1_09_1) {
- gen_helper_tlb_flush(cpu_env);
- return true;
- }
-#endif
return false;
}
static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
{
#ifndef CONFIG_USER_ONLY
- if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
- has_ext(ctx, RVH)) {
+ if (has_ext(ctx, RVH)) {
/* Hpervisor extensions exist */
/*
* if (env->priv == PRV_M ||
static bool trans_hfence_bvma(DisasContext *ctx, arg_sfence_vma *a)
{
#ifndef CONFIG_USER_ONLY
- if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
- has_ext(ctx, RVH)) {
+ if (has_ext(ctx, RVH)) {
/* Hpervisor extensions exist */
/*
* if (env->priv == PRV_M ||
return;
}
- if (env->priv_ver < PRIV_VERSION_1_10_0) {
- monitor_printf(mon, "Privileged mode < 1.10 unsupported\n");
- return;
- }
-
if (!(env->satp & SATP_MODE)) {
monitor_printf(mon, "No translation or protection\n");
return;
riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
}
- if (env->priv_ver >= PRIV_VERSION_1_10_0 &&
- get_field(env->mstatus, MSTATUS_TSR) && !(env->priv >= PRV_M)) {
+ if (get_field(env->mstatus, MSTATUS_TSR) && !(env->priv >= PRV_M)) {
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
}
} else {
prev_priv = get_field(mstatus, MSTATUS_SPP);
- mstatus = set_field(mstatus,
- env->priv_ver >= PRIV_VERSION_1_10_0 ?
- MSTATUS_SIE : MSTATUS_UIE << prev_priv,
- get_field(mstatus, MSTATUS_SPIE));
+ mstatus = set_field(mstatus, MSTATUS_SIE,
+ get_field(mstatus, MSTATUS_SPIE));
mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
env->mstatus = mstatus;
target_ulong mstatus = env->mstatus;
target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
target_ulong prev_virt = MSTATUS_MPV_ISSET(env);
- mstatus = set_field(mstatus,
- env->priv_ver >= PRIV_VERSION_1_10_0 ?
- MSTATUS_MIE : MSTATUS_UIE << prev_priv,
- get_field(mstatus, MSTATUS_MPIE));
+ mstatus = set_field(mstatus, MSTATUS_MIE,
+ get_field(mstatus, MSTATUS_MPIE));
mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
#ifdef TARGET_RISCV32
CPUState *cs = env_cpu(env);
if ((env->priv == PRV_S &&
- env->priv_ver >= PRIV_VERSION_1_10_0 &&
get_field(env->mstatus, MSTATUS_TW)) ||
riscv_cpu_virt_enabled(env)) {
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
CPUState *cs = env_cpu(env);
if (!(env->priv >= PRV_S) ||
(env->priv == PRV_S &&
- env->priv_ver >= PRIV_VERSION_1_10_0 &&
get_field(env->mstatus, MSTATUS_TVM))) {
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
} else {