mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 10:13:56 -06:00
Sixth RISC-V PR for 8.0
* Support for the Zicbiom, ZCicboz, and Zicbop extensions. * OpenSBI has been updated to version 1.2, see <https://github.com/riscv-software-src/opensbi/releases/tag/v1.2> for the release notes. * Support for setting the virtual address width (ie, sv39/sv48/sv57) on the command line. * Support for ACPI on RISC-V. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEKzw3R0RoQ7JKlDp6LhMZ81+7GIkFAmQGYGgTHHBhbG1lckBk YWJiZWx0LmNvbQAKCRAuExnzX7sYidmyEAC6FEMbbFM5D++qR6w6xM6hXgzcrev6 s1kyRRNVa45uSA78ti/Zi0hsDLNf7ZsNPndF0OIkkO5iAE0OVm3LU7tV1TqKcT82 Dd9VXxe93zEmfnuJazHrMa54SXPhhnNdWHtKlZ6vBfZpbxgx0FFs50xkCsrM5LQZ hYHxQUqPWQTvF2MdDHrxCuLcdKl+Wg3ysCcgRh2d049KUBrIu6vNaHC2+AGRjCbj BkrGCkB82fTmVJjzAcVWQxLoAV12pCbJS4og1GtP8hA7WevtB39tbPin9siBKRZp QBeiIsg0nebkpmZGrb+xWVwlIBNe9yYwJa0KmveQk8v7L5RIzjM1mtDL91VrVljC KC2tfT570m0Iq2NoFMb3wd/kESHFzVDM/g+XYqRd4KSoiCNP/RbqYNQBwbMc31Tr E27xfA1D8w2vem0Rk20x3KgPf1Z5OmGXjq6YObTpnAzG8cZlA37qKBP+ortt5aHX GZSg3CAwknHHVajd4aaegkPsHxm1tRvoTfh38MwkPSNxaA9GD0nz0k9xaYDmeZ2L olfanNsaQEwcVUId31+7sAENg1TZU0fnj879/nxkMUCazVTdL8/mz+IoTTx0QCST 3+9ATWcyJUlmjbDKIs7kr1L+wJdvvHEJggPAbbPI8ekpXaLZvUYOT6ObzYKNAmwY wELQBn8QKXcLVA== =5gAt -----END PGP SIGNATURE----- Merge tag 'pull-riscv-to-apply-20230306' of https://gitlab.com/palmer-dabbelt/qemu into staging Sixth RISC-V PR for 8.0 * Support for the Zicbiom, ZCicboz, and Zicbop extensions. * OpenSBI has been updated to version 1.2, see <https://github.com/riscv-software-src/opensbi/releases/tag/v1.2> for the release notes. * Support for setting the virtual address width (ie, sv39/sv48/sv57) on the command line. * Support for ACPI on RISC-V. # -----BEGIN PGP SIGNATURE----- # # iQJHBAABCAAxFiEEKzw3R0RoQ7JKlDp6LhMZ81+7GIkFAmQGYGgTHHBhbG1lckBk # YWJiZWx0LmNvbQAKCRAuExnzX7sYidmyEAC6FEMbbFM5D++qR6w6xM6hXgzcrev6 # s1kyRRNVa45uSA78ti/Zi0hsDLNf7ZsNPndF0OIkkO5iAE0OVm3LU7tV1TqKcT82 # Dd9VXxe93zEmfnuJazHrMa54SXPhhnNdWHtKlZ6vBfZpbxgx0FFs50xkCsrM5LQZ # hYHxQUqPWQTvF2MdDHrxCuLcdKl+Wg3ysCcgRh2d049KUBrIu6vNaHC2+AGRjCbj # BkrGCkB82fTmVJjzAcVWQxLoAV12pCbJS4og1GtP8hA7WevtB39tbPin9siBKRZp # QBeiIsg0nebkpmZGrb+xWVwlIBNe9yYwJa0KmveQk8v7L5RIzjM1mtDL91VrVljC # KC2tfT570m0Iq2NoFMb3wd/kESHFzVDM/g+XYqRd4KSoiCNP/RbqYNQBwbMc31Tr # E27xfA1D8w2vem0Rk20x3KgPf1Z5OmGXjq6YObTpnAzG8cZlA37qKBP+ortt5aHX # GZSg3CAwknHHVajd4aaegkPsHxm1tRvoTfh38MwkPSNxaA9GD0nz0k9xaYDmeZ2L # olfanNsaQEwcVUId31+7sAENg1TZU0fnj879/nxkMUCazVTdL8/mz+IoTTx0QCST # 3+9ATWcyJUlmjbDKIs7kr1L+wJdvvHEJggPAbbPI8ekpXaLZvUYOT6ObzYKNAmwY # wELQBn8QKXcLVA== # =5gAt # -----END PGP SIGNATURE----- # gpg: Signature made Mon 06 Mar 2023 21:51:36 GMT # gpg: using RSA key 2B3C3747446843B24A943A7A2E1319F35FBB1889 # gpg: issuer "palmer@dabbelt.com" # gpg: Good signature from "Palmer Dabbelt <palmer@dabbelt.com>" [unknown] # gpg: aka "Palmer Dabbelt <palmerdabbelt@google.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 00CE 76D1 8349 60DF CE88 6DF8 EF4C A150 2CCB AB41 # Subkey fingerprint: 2B3C 3747 4468 43B2 4A94 3A7A 2E13 19F3 5FBB 1889 * tag 'pull-riscv-to-apply-20230306' of https://gitlab.com/palmer-dabbelt/qemu: (22 commits) MAINTAINERS: Add entry for RISC-V ACPI hw/riscv/virt.c: Initialize the ACPI tables hw/riscv/virt: virt-acpi-build.c: Add RHCT Table hw/riscv/virt: virt-acpi-build.c: Add RINTC in MADT hw/riscv/virt: Enable basic ACPI infrastructure hw/riscv/virt: Add memmap pointer to RiscVVirtState hw/riscv/virt: Add a switch to disable ACPI hw/riscv/virt: Add OEM_ID and OEM_TABLE_ID fields riscv: Correctly set the device-tree entry 'mmu-type' riscv: Introduce satp mode hw capabilities riscv: Allow user to set the satp mode riscv: Change type of valid_vm_1_10_[32|64] to bool riscv: Pass Object to register_cpu_props instead of DeviceState roms/opensbi: Upgrade from v1.1 to v1.2 gitlab/opensbi: Move to docker:stable hw: intc: Use cpu_by_arch_id to fetch CPU state target/riscv: cpu: Implement get_arch_id callback disas/riscv Fix ctzw disassemble hw/riscv/virt.c: add cbo[mz]-block-size fdt properties target/riscv: add Zicbop cbo.prefetch{i, r, m} placeholder ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
9832009d9d
23 changed files with 1061 additions and 61 deletions
|
@ -28,6 +28,7 @@
|
|||
#include "time_helper.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/visitor.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "migration/vmstate.h"
|
||||
|
@ -75,6 +76,8 @@ struct isa_ext_data {
|
|||
static const struct isa_ext_data isa_edata_arr[] = {
|
||||
ISA_EXT_DATA_ENTRY(h, false, PRIV_VERSION_1_12_0, ext_h),
|
||||
ISA_EXT_DATA_ENTRY(v, false, PRIV_VERSION_1_10_0, ext_v),
|
||||
ISA_EXT_DATA_ENTRY(zicbom, true, PRIV_VERSION_1_12_0, ext_icbom),
|
||||
ISA_EXT_DATA_ENTRY(zicboz, true, PRIV_VERSION_1_12_0, ext_icboz),
|
||||
ISA_EXT_DATA_ENTRY(zicond, true, PRIV_VERSION_1_12_0, ext_zicond),
|
||||
ISA_EXT_DATA_ENTRY(zicsr, true, PRIV_VERSION_1_10_0, ext_icsr),
|
||||
ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei),
|
||||
|
@ -218,7 +221,7 @@ static const char * const riscv_intr_names[] = {
|
|||
"reserved"
|
||||
};
|
||||
|
||||
static void register_cpu_props(DeviceState *dev);
|
||||
static void register_cpu_props(Object *obj);
|
||||
|
||||
const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
|
||||
{
|
||||
|
@ -247,6 +250,89 @@ static void set_vext_version(CPURISCVState *env, int vext_ver)
|
|||
env->vext_ver = vext_ver;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static uint8_t satp_mode_from_str(const char *satp_mode_str)
|
||||
{
|
||||
if (!strncmp(satp_mode_str, "mbare", 5)) {
|
||||
return VM_1_10_MBARE;
|
||||
}
|
||||
|
||||
if (!strncmp(satp_mode_str, "sv32", 4)) {
|
||||
return VM_1_10_SV32;
|
||||
}
|
||||
|
||||
if (!strncmp(satp_mode_str, "sv39", 4)) {
|
||||
return VM_1_10_SV39;
|
||||
}
|
||||
|
||||
if (!strncmp(satp_mode_str, "sv48", 4)) {
|
||||
return VM_1_10_SV48;
|
||||
}
|
||||
|
||||
if (!strncmp(satp_mode_str, "sv57", 4)) {
|
||||
return VM_1_10_SV57;
|
||||
}
|
||||
|
||||
if (!strncmp(satp_mode_str, "sv64", 4)) {
|
||||
return VM_1_10_SV64;
|
||||
}
|
||||
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
uint8_t satp_mode_max_from_map(uint32_t map)
|
||||
{
|
||||
/* map here has at least one bit set, so no problem with clz */
|
||||
return 31 - __builtin_clz(map);
|
||||
}
|
||||
|
||||
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit)
|
||||
{
|
||||
if (is_32_bit) {
|
||||
switch (satp_mode) {
|
||||
case VM_1_10_SV32:
|
||||
return "sv32";
|
||||
case VM_1_10_MBARE:
|
||||
return "none";
|
||||
}
|
||||
} else {
|
||||
switch (satp_mode) {
|
||||
case VM_1_10_SV64:
|
||||
return "sv64";
|
||||
case VM_1_10_SV57:
|
||||
return "sv57";
|
||||
case VM_1_10_SV48:
|
||||
return "sv48";
|
||||
case VM_1_10_SV39:
|
||||
return "sv39";
|
||||
case VM_1_10_MBARE:
|
||||
return "none";
|
||||
}
|
||||
}
|
||||
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
static void set_satp_mode_max_supported(RISCVCPU *cpu,
|
||||
uint8_t satp_mode)
|
||||
{
|
||||
bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
|
||||
const bool *valid_vm = rv32 ? valid_vm_1_10_32 : valid_vm_1_10_64;
|
||||
|
||||
for (int i = 0; i <= satp_mode; ++i) {
|
||||
if (valid_vm[i]) {
|
||||
cpu->cfg.satp_mode.supported |= (1 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the satp mode to the max supported */
|
||||
static void set_satp_mode_default_map(RISCVCPU *cpu)
|
||||
{
|
||||
cpu->cfg.satp_mode.map = cpu->cfg.satp_mode.supported;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void riscv_any_cpu_init(Object *obj)
|
||||
{
|
||||
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
||||
|
@ -255,8 +341,15 @@ static void riscv_any_cpu_init(Object *obj)
|
|||
#elif defined(TARGET_RISCV64)
|
||||
set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
set_satp_mode_max_supported(RISCV_CPU(obj),
|
||||
riscv_cpu_mxl(&RISCV_CPU(obj)->env) == MXL_RV32 ?
|
||||
VM_1_10_SV32 : VM_1_10_SV57);
|
||||
#endif
|
||||
|
||||
set_priv_version(env, PRIV_VERSION_1_12_0);
|
||||
register_cpu_props(DEVICE(obj));
|
||||
register_cpu_props(obj);
|
||||
}
|
||||
|
||||
#if defined(TARGET_RISCV64)
|
||||
|
@ -265,17 +358,23 @@ static void rv64_base_cpu_init(Object *obj)
|
|||
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
||||
/* We set this in the realise function */
|
||||
set_misa(env, MXL_RV64, 0);
|
||||
register_cpu_props(DEVICE(obj));
|
||||
register_cpu_props(obj);
|
||||
/* Set latest version of privileged specification */
|
||||
set_priv_version(env, PRIV_VERSION_1_12_0);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rv64_sifive_u_cpu_init(Object *obj)
|
||||
{
|
||||
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
||||
set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
|
||||
register_cpu_props(DEVICE(obj));
|
||||
register_cpu_props(obj);
|
||||
set_priv_version(env, PRIV_VERSION_1_10_0);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rv64_sifive_e_cpu_init(Object *obj)
|
||||
|
@ -284,9 +383,12 @@ static void rv64_sifive_e_cpu_init(Object *obj)
|
|||
RISCVCPU *cpu = RISCV_CPU(obj);
|
||||
|
||||
set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
|
||||
register_cpu_props(DEVICE(obj));
|
||||
register_cpu_props(obj);
|
||||
set_priv_version(env, PRIV_VERSION_1_10_0);
|
||||
cpu->cfg.mmu = false;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rv64_thead_c906_cpu_init(Object *obj)
|
||||
|
@ -316,6 +418,9 @@ static void rv64_thead_c906_cpu_init(Object *obj)
|
|||
cpu->cfg.ext_xtheadsync = true;
|
||||
|
||||
cpu->cfg.mvendorid = THEAD_VENDOR_ID;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
set_satp_mode_max_supported(cpu, VM_1_10_SV39);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rv128_base_cpu_init(Object *obj)
|
||||
|
@ -329,9 +434,12 @@ static void rv128_base_cpu_init(Object *obj)
|
|||
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
||||
/* We set this in the realise function */
|
||||
set_misa(env, MXL_RV128, 0);
|
||||
register_cpu_props(DEVICE(obj));
|
||||
register_cpu_props(obj);
|
||||
/* Set latest version of privileged specification */
|
||||
set_priv_version(env, PRIV_VERSION_1_12_0);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static void rv32_base_cpu_init(Object *obj)
|
||||
|
@ -339,17 +447,23 @@ static void rv32_base_cpu_init(Object *obj)
|
|||
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
||||
/* We set this in the realise function */
|
||||
set_misa(env, MXL_RV32, 0);
|
||||
register_cpu_props(DEVICE(obj));
|
||||
register_cpu_props(obj);
|
||||
/* Set latest version of privileged specification */
|
||||
set_priv_version(env, PRIV_VERSION_1_12_0);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rv32_sifive_u_cpu_init(Object *obj)
|
||||
{
|
||||
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
||||
set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
|
||||
register_cpu_props(DEVICE(obj));
|
||||
register_cpu_props(obj);
|
||||
set_priv_version(env, PRIV_VERSION_1_10_0);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rv32_sifive_e_cpu_init(Object *obj)
|
||||
|
@ -358,9 +472,12 @@ static void rv32_sifive_e_cpu_init(Object *obj)
|
|||
RISCVCPU *cpu = RISCV_CPU(obj);
|
||||
|
||||
set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
|
||||
register_cpu_props(DEVICE(obj));
|
||||
register_cpu_props(obj);
|
||||
set_priv_version(env, PRIV_VERSION_1_10_0);
|
||||
cpu->cfg.mmu = false;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rv32_ibex_cpu_init(Object *obj)
|
||||
|
@ -369,9 +486,12 @@ static void rv32_ibex_cpu_init(Object *obj)
|
|||
RISCVCPU *cpu = RISCV_CPU(obj);
|
||||
|
||||
set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
|
||||
register_cpu_props(DEVICE(obj));
|
||||
register_cpu_props(obj);
|
||||
set_priv_version(env, PRIV_VERSION_1_11_0);
|
||||
cpu->cfg.mmu = false;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
|
||||
#endif
|
||||
cpu->cfg.epmp = true;
|
||||
}
|
||||
|
||||
|
@ -381,9 +501,12 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
|
|||
RISCVCPU *cpu = RISCV_CPU(obj);
|
||||
|
||||
set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
|
||||
register_cpu_props(DEVICE(obj));
|
||||
register_cpu_props(obj);
|
||||
set_priv_version(env, PRIV_VERSION_1_10_0);
|
||||
cpu->cfg.mmu = false;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -396,7 +519,7 @@ static void riscv_host_cpu_init(Object *obj)
|
|||
#elif defined(TARGET_RISCV64)
|
||||
set_misa(env, MXL_RV64, 0);
|
||||
#endif
|
||||
register_cpu_props(DEVICE(obj));
|
||||
register_cpu_props(obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -916,6 +1039,88 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
|
|||
set_misa(env, env->misa_mxl, ext);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
|
||||
{
|
||||
bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
|
||||
uint8_t satp_mode_map_max;
|
||||
uint8_t satp_mode_supported_max =
|
||||
satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
|
||||
|
||||
if (cpu->cfg.satp_mode.map == 0) {
|
||||
if (cpu->cfg.satp_mode.init == 0) {
|
||||
/* If unset by the user, we fallback to the default satp mode. */
|
||||
set_satp_mode_default_map(cpu);
|
||||
} else {
|
||||
/*
|
||||
* Find the lowest level that was disabled and then enable the
|
||||
* first valid level below which can be found in
|
||||
* valid_vm_1_10_32/64.
|
||||
*/
|
||||
for (int i = 1; i < 16; ++i) {
|
||||
if ((cpu->cfg.satp_mode.init & (1 << i)) &&
|
||||
(cpu->cfg.satp_mode.supported & (1 << i))) {
|
||||
for (int j = i - 1; j >= 0; --j) {
|
||||
if (cpu->cfg.satp_mode.supported & (1 << j)) {
|
||||
cpu->cfg.satp_mode.map |= (1 << j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
satp_mode_map_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map);
|
||||
|
||||
/* Make sure the user asked for a supported configuration (HW and qemu) */
|
||||
if (satp_mode_map_max > satp_mode_supported_max) {
|
||||
error_setg(errp, "satp_mode %s is higher than hw max capability %s",
|
||||
satp_mode_str(satp_mode_map_max, rv32),
|
||||
satp_mode_str(satp_mode_supported_max, rv32));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure the user did not ask for an invalid configuration as per
|
||||
* the specification.
|
||||
*/
|
||||
if (!rv32) {
|
||||
for (int i = satp_mode_map_max - 1; i >= 0; --i) {
|
||||
if (!(cpu->cfg.satp_mode.map & (1 << i)) &&
|
||||
(cpu->cfg.satp_mode.init & (1 << i)) &&
|
||||
(cpu->cfg.satp_mode.supported & (1 << i))) {
|
||||
error_setg(errp, "cannot disable %s satp mode if %s "
|
||||
"is enabled", satp_mode_str(i, false),
|
||||
satp_mode_str(satp_mode_map_max, false));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally expand the map so that all valid modes are set */
|
||||
for (int i = satp_mode_map_max - 1; i >= 0; --i) {
|
||||
if (cpu->cfg.satp_mode.supported & (1 << i)) {
|
||||
cpu->cfg.satp_mode.map |= (1 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
Error *local_err = NULL;
|
||||
|
||||
riscv_cpu_satp_mode_finalize(cpu, &local_err);
|
||||
if (local_err != NULL) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
CPUState *cs = CPU(dev);
|
||||
|
@ -1015,6 +1220,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
|||
}
|
||||
#endif
|
||||
|
||||
riscv_cpu_finalize_features(cpu, &local_err);
|
||||
if (local_err != NULL) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
riscv_cpu_register_gdb_regs_for_features(cs);
|
||||
|
||||
qemu_init_vcpu(cs);
|
||||
|
@ -1024,6 +1235,52 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
|||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static void cpu_riscv_get_satp(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
RISCVSATPMap *satp_map = opaque;
|
||||
uint8_t satp = satp_mode_from_str(name);
|
||||
bool value;
|
||||
|
||||
value = satp_map->map & (1 << satp);
|
||||
|
||||
visit_type_bool(v, name, &value, errp);
|
||||
}
|
||||
|
||||
static void cpu_riscv_set_satp(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
RISCVSATPMap *satp_map = opaque;
|
||||
uint8_t satp = satp_mode_from_str(name);
|
||||
bool value;
|
||||
|
||||
if (!visit_type_bool(v, name, &value, errp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
satp_map->map = deposit32(satp_map->map, satp, 1, value);
|
||||
satp_map->init |= 1 << satp;
|
||||
}
|
||||
|
||||
static void riscv_add_satp_mode_properties(Object *obj)
|
||||
{
|
||||
RISCVCPU *cpu = RISCV_CPU(obj);
|
||||
|
||||
if (cpu->env.misa_mxl == MXL_RV32) {
|
||||
object_property_add(obj, "sv32", "bool", cpu_riscv_get_satp,
|
||||
cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
|
||||
} else {
|
||||
object_property_add(obj, "sv39", "bool", cpu_riscv_get_satp,
|
||||
cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
|
||||
object_property_add(obj, "sv48", "bool", cpu_riscv_get_satp,
|
||||
cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
|
||||
object_property_add(obj, "sv57", "bool", cpu_riscv_get_satp,
|
||||
cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
|
||||
object_property_add(obj, "sv64", "bool", cpu_riscv_get_satp,
|
||||
cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
|
||||
}
|
||||
}
|
||||
|
||||
static void riscv_cpu_set_irq(void *opaque, int irq, int level)
|
||||
{
|
||||
RISCVCPU *cpu = RISCV_CPU(opaque);
|
||||
|
@ -1167,6 +1424,11 @@ static Property riscv_cpu_extensions[] = {
|
|||
DEFINE_PROP_BOOL("zhinx", RISCVCPU, cfg.ext_zhinx, false),
|
||||
DEFINE_PROP_BOOL("zhinxmin", RISCVCPU, cfg.ext_zhinxmin, false),
|
||||
|
||||
DEFINE_PROP_BOOL("zicbom", RISCVCPU, cfg.ext_icbom, true),
|
||||
DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64),
|
||||
DEFINE_PROP_BOOL("zicboz", RISCVCPU, cfg.ext_icboz, true),
|
||||
DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64),
|
||||
|
||||
DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false),
|
||||
|
||||
/* Vendor-specific custom extensions */
|
||||
|
@ -1203,11 +1465,12 @@ static Property riscv_cpu_extensions[] = {
|
|||
* properties and leave. env.misa_ext = 0 means that we want
|
||||
* all the default properties to be registered.
|
||||
*/
|
||||
static void register_cpu_props(DeviceState *dev)
|
||||
static void register_cpu_props(Object *obj)
|
||||
{
|
||||
RISCVCPU *cpu = RISCV_CPU(OBJECT(dev));
|
||||
RISCVCPU *cpu = RISCV_CPU(obj);
|
||||
uint32_t misa_ext = cpu->env.misa_ext;
|
||||
Property *prop;
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
|
||||
/*
|
||||
* If misa_ext is not zero, set cfg properties now to
|
||||
|
@ -1238,6 +1501,10 @@ static void register_cpu_props(DeviceState *dev)
|
|||
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
|
||||
qdev_property_add_static(dev, prop);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
riscv_add_satp_mode_properties(obj);
|
||||
#endif
|
||||
}
|
||||
|
||||
static Property riscv_cpu_properties[] = {
|
||||
|
@ -1294,6 +1561,13 @@ static const char *riscv_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname)
|
|||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static int64_t riscv_get_arch_id(CPUState *cs)
|
||||
{
|
||||
RISCVCPU *cpu = RISCV_CPU(cs);
|
||||
|
||||
return cpu->env.mhartid;
|
||||
}
|
||||
|
||||
#include "hw/core/sysemu-cpu-ops.h"
|
||||
|
||||
static const struct SysemuCPUOps riscv_sysemu_ops = {
|
||||
|
@ -1348,6 +1622,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
|
|||
cc->disas_set_info = riscv_cpu_disas_set_info;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
cc->sysemu_ops = &riscv_sysemu_ops;
|
||||
cc->get_arch_id = riscv_get_arch_id;
|
||||
#endif
|
||||
cc->gdb_arch_name = riscv_gdb_arch_name;
|
||||
cc->gdb_get_dynamic_xml = riscv_gdb_get_dynamic_xml;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "qom/object.h"
|
||||
#include "qemu/int128.h"
|
||||
#include "cpu_bits.h"
|
||||
#include "qapi/qapi-types-common.h"
|
||||
|
||||
#define TCG_GUEST_DEFAULT_MO 0
|
||||
|
||||
|
@ -401,6 +402,21 @@ struct RISCVCPUClass {
|
|||
ResettablePhases parent_phases;
|
||||
};
|
||||
|
||||
/*
|
||||
* map is a 16-bit bitmap: the most significant set bit in map is the maximum
|
||||
* satp mode that is supported. It may be chosen by the user and must respect
|
||||
* what qemu implements (valid_1_10_32/64) and what the hw is capable of
|
||||
* (supported bitmap below).
|
||||
*
|
||||
* init is a 16-bit bitmap used to make sure the user selected a correct
|
||||
* configuration as per the specification.
|
||||
*
|
||||
* supported is a 16-bit bitmap used to reflect the hw capabilities.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t map, init, supported;
|
||||
} RISCVSATPMap;
|
||||
|
||||
struct RISCVCPUConfig {
|
||||
bool ext_i;
|
||||
bool ext_e;
|
||||
|
@ -434,6 +450,8 @@ struct RISCVCPUConfig {
|
|||
bool ext_zkt;
|
||||
bool ext_ifencei;
|
||||
bool ext_icsr;
|
||||
bool ext_icbom;
|
||||
bool ext_icboz;
|
||||
bool ext_zicond;
|
||||
bool ext_zihintpause;
|
||||
bool ext_smstateen;
|
||||
|
@ -486,6 +504,8 @@ struct RISCVCPUConfig {
|
|||
char *vext_spec;
|
||||
uint16_t vlen;
|
||||
uint16_t elen;
|
||||
uint16_t cbom_blocksize;
|
||||
uint16_t cboz_blocksize;
|
||||
bool mmu;
|
||||
bool pmp;
|
||||
bool epmp;
|
||||
|
@ -493,6 +513,10 @@ struct RISCVCPUConfig {
|
|||
bool misa_w;
|
||||
|
||||
bool short_isa_string;
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
RISCVSATPMap satp_mode;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct RISCVCPUConfig RISCVCPUConfig;
|
||||
|
@ -794,9 +818,14 @@ enum riscv_pmu_event_idx {
|
|||
/* CSR function table */
|
||||
extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
|
||||
|
||||
extern const bool valid_vm_1_10_32[], valid_vm_1_10_64[];
|
||||
|
||||
void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
|
||||
void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
|
||||
|
||||
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
|
||||
|
||||
uint8_t satp_mode_max_from_map(uint32_t map);
|
||||
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
|
||||
|
||||
#endif /* RISCV_CPU_H */
|
||||
|
|
|
@ -1141,16 +1141,16 @@ static const target_ulong hip_writable_mask = MIP_VSSIP;
|
|||
static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
|
||||
static const target_ulong vsip_writable_mask = MIP_VSSIP;
|
||||
|
||||
static const char valid_vm_1_10_32[16] = {
|
||||
[VM_1_10_MBARE] = 1,
|
||||
[VM_1_10_SV32] = 1
|
||||
const bool valid_vm_1_10_32[16] = {
|
||||
[VM_1_10_MBARE] = true,
|
||||
[VM_1_10_SV32] = true
|
||||
};
|
||||
|
||||
static const char valid_vm_1_10_64[16] = {
|
||||
[VM_1_10_MBARE] = 1,
|
||||
[VM_1_10_SV39] = 1,
|
||||
[VM_1_10_SV48] = 1,
|
||||
[VM_1_10_SV57] = 1
|
||||
const bool valid_vm_1_10_64[16] = {
|
||||
[VM_1_10_MBARE] = true,
|
||||
[VM_1_10_SV39] = true,
|
||||
[VM_1_10_SV48] = true,
|
||||
[VM_1_10_SV57] = true
|
||||
};
|
||||
|
||||
/* Machine Information Registers */
|
||||
|
@ -1230,13 +1230,11 @@ static RISCVException read_mstatus(CPURISCVState *env, int csrno,
|
|||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
static int validate_vm(CPURISCVState *env, target_ulong vm)
|
||||
static bool validate_vm(CPURISCVState *env, target_ulong vm)
|
||||
{
|
||||
if (riscv_cpu_mxl(env) == MXL_RV32) {
|
||||
return valid_vm_1_10_32[vm & 0xf];
|
||||
} else {
|
||||
return valid_vm_1_10_64[vm & 0xf];
|
||||
}
|
||||
RISCVCPU *cpu = RISCV_CPU(env_cpu(env));
|
||||
|
||||
return (vm & 0xf) <= satp_mode_max_from_map(cpu->cfg.satp_mode.map);
|
||||
}
|
||||
|
||||
static RISCVException write_mstatus(CPURISCVState *env, int csrno,
|
||||
|
@ -2669,7 +2667,8 @@ static RISCVException read_satp(CPURISCVState *env, int csrno,
|
|||
static RISCVException write_satp(CPURISCVState *env, int csrno,
|
||||
target_ulong val)
|
||||
{
|
||||
target_ulong vm, mask;
|
||||
target_ulong mask;
|
||||
bool vm;
|
||||
|
||||
if (!riscv_cpu_cfg(env)->mmu) {
|
||||
return RISCV_EXCP_NONE;
|
||||
|
|
|
@ -97,6 +97,11 @@ DEF_HELPER_FLAGS_2(fcvt_h_l, TCG_CALL_NO_RWG, i64, env, tl)
|
|||
DEF_HELPER_FLAGS_2(fcvt_h_lu, TCG_CALL_NO_RWG, i64, env, tl)
|
||||
DEF_HELPER_FLAGS_2(fclass_h, TCG_CALL_NO_RWG_SE, tl, env, i64)
|
||||
|
||||
/* Cache-block operations */
|
||||
DEF_HELPER_2(cbo_clean_flush, void, env, tl)
|
||||
DEF_HELPER_2(cbo_inval, void, env, tl)
|
||||
DEF_HELPER_2(cbo_zero, void, env, tl)
|
||||
|
||||
/* Special functions */
|
||||
DEF_HELPER_2(csrr, tl, env, int)
|
||||
DEF_HELPER_3(csrw, void, env, int, tl)
|
||||
|
|
|
@ -134,6 +134,7 @@ addi ............ ..... 000 ..... 0010011 @i
|
|||
slti ............ ..... 010 ..... 0010011 @i
|
||||
sltiu ............ ..... 011 ..... 0010011 @i
|
||||
xori ............ ..... 100 ..... 0010011 @i
|
||||
# cbo.prefetch_{i,r,m} instructions are ori with rd=x0 and not decoded.
|
||||
ori ............ ..... 110 ..... 0010011 @i
|
||||
andi ............ ..... 111 ..... 0010011 @i
|
||||
slli 00000. ...... ..... 001 ..... 0010011 @sh
|
||||
|
@ -179,7 +180,20 @@ sraw 0100000 ..... ..... 101 ..... 0111011 @r
|
|||
|
||||
# *** RV128I Base Instruction Set (in addition to RV64I) ***
|
||||
ldu ............ ..... 111 ..... 0000011 @i
|
||||
lq ............ ..... 010 ..... 0001111 @i
|
||||
{
|
||||
[
|
||||
# *** RV32 Zicbom Standard Extension ***
|
||||
cbo_clean 0000000 00001 ..... 010 00000 0001111 @sfence_vm
|
||||
cbo_flush 0000000 00010 ..... 010 00000 0001111 @sfence_vm
|
||||
cbo_inval 0000000 00000 ..... 010 00000 0001111 @sfence_vm
|
||||
|
||||
# *** RV32 Zicboz Standard Extension ***
|
||||
cbo_zero 0000000 00100 ..... 010 00000 0001111 @sfence_vm
|
||||
]
|
||||
|
||||
# *** RVI128 lq ***
|
||||
lq ............ ..... 010 ..... 0001111 @i
|
||||
}
|
||||
sq ............ ..... 100 ..... 0100011 @s
|
||||
addid ............ ..... 000 ..... 1011011 @i
|
||||
sllid 000000 ...... ..... 001 ..... 1011011 @sh6
|
||||
|
|
57
target/riscv/insn_trans/trans_rvzicbo.c.inc
Normal file
57
target/riscv/insn_trans/trans_rvzicbo.c.inc
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* RISC-V translation routines for the RISC-V CBO Extension.
|
||||
*
|
||||
* Copyright (c) 2021 Philipp Tomsich, philipp.tomsich@vrull.eu
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2 or later, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define REQUIRE_ZICBOM(ctx) do { \
|
||||
if (!ctx->cfg_ptr->ext_icbom) { \
|
||||
return false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define REQUIRE_ZICBOZ(ctx) do { \
|
||||
if (!ctx->cfg_ptr->ext_icboz) { \
|
||||
return false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a)
|
||||
{
|
||||
REQUIRE_ZICBOM(ctx);
|
||||
gen_helper_cbo_clean_flush(cpu_env, cpu_gpr[a->rs1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a)
|
||||
{
|
||||
REQUIRE_ZICBOM(ctx);
|
||||
gen_helper_cbo_clean_flush(cpu_env, cpu_gpr[a->rs1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a)
|
||||
{
|
||||
REQUIRE_ZICBOM(ctx);
|
||||
gen_helper_cbo_inval(cpu_env, cpu_gpr[a->rs1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a)
|
||||
{
|
||||
REQUIRE_ZICBOZ(ctx);
|
||||
gen_helper_cbo_zero(cpu_env, cpu_gpr[a->rs1]);
|
||||
return true;
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
|
||||
* Copyright (c) 2017-2018 SiFive, Inc.
|
||||
* Copyright (c) 2022 VRULL GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -123,6 +124,140 @@ target_ulong helper_csrrw_i128(CPURISCVState *env, int csr,
|
|||
return int128_getlo(rv);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* check_zicbo_envcfg
|
||||
*
|
||||
* Raise virtual exceptions and illegal instruction exceptions for
|
||||
* Zicbo[mz] instructions based on the settings of [mhs]envcfg as
|
||||
* specified in section 2.5.1 of the CMO specification.
|
||||
*/
|
||||
static void check_zicbo_envcfg(CPURISCVState *env, target_ulong envbits,
|
||||
uintptr_t ra)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if ((env->priv < PRV_M) && !get_field(env->menvcfg, envbits)) {
|
||||
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, ra);
|
||||
}
|
||||
|
||||
if (riscv_cpu_virt_enabled(env) &&
|
||||
(((env->priv < PRV_H) && !get_field(env->henvcfg, envbits)) ||
|
||||
((env->priv < PRV_S) && !get_field(env->senvcfg, envbits)))) {
|
||||
riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, ra);
|
||||
}
|
||||
|
||||
if ((env->priv < PRV_S) && !get_field(env->senvcfg, envbits)) {
|
||||
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, ra);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void helper_cbo_zero(CPURISCVState *env, target_ulong address)
|
||||
{
|
||||
RISCVCPU *cpu = env_archcpu(env);
|
||||
uint16_t cbozlen = cpu->cfg.cboz_blocksize;
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
uintptr_t ra = GETPC();
|
||||
void *mem;
|
||||
|
||||
check_zicbo_envcfg(env, MENVCFG_CBZE, ra);
|
||||
|
||||
/* Mask off low-bits to align-down to the cache-block. */
|
||||
address &= ~(cbozlen - 1);
|
||||
|
||||
/*
|
||||
* cbo.zero requires MMU_DATA_STORE access. Do a probe_write()
|
||||
* to raise any exceptions, including PMP.
|
||||
*/
|
||||
mem = probe_write(env, address, cbozlen, mmu_idx, ra);
|
||||
|
||||
if (likely(mem)) {
|
||||
memset(mem, 0, cbozlen);
|
||||
} else {
|
||||
/*
|
||||
* This means that we're dealing with an I/O page. Section 4.2
|
||||
* of cmobase v1.0.1 says:
|
||||
*
|
||||
* "Cache-block zero instructions store zeros independently
|
||||
* of whether data from the underlying memory locations are
|
||||
* cacheable."
|
||||
*
|
||||
* Write zeros in address + cbozlen regardless of not being
|
||||
* a RAM page.
|
||||
*/
|
||||
for (int i = 0; i < cbozlen; i++) {
|
||||
cpu_stb_mmuidx_ra(env, address + i, 0, mmu_idx, ra);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check_zicbom_access
|
||||
*
|
||||
* Check access permissions (LOAD, STORE or FETCH as specified in
|
||||
* section 2.5.2 of the CMO specification) for Zicbom, raising
|
||||
* either store page-fault (non-virtualized) or store guest-page
|
||||
* fault (virtualized).
|
||||
*/
|
||||
static void check_zicbom_access(CPURISCVState *env,
|
||||
target_ulong address,
|
||||
uintptr_t ra)
|
||||
{
|
||||
RISCVCPU *cpu = env_archcpu(env);
|
||||
int mmu_idx = cpu_mmu_index(env, false);
|
||||
uint16_t cbomlen = cpu->cfg.cbom_blocksize;
|
||||
void *phost;
|
||||
int ret;
|
||||
|
||||
/* Mask off low-bits to align-down to the cache-block. */
|
||||
address &= ~(cbomlen - 1);
|
||||
|
||||
/*
|
||||
* Section 2.5.2 of cmobase v1.0.1:
|
||||
*
|
||||
* "A cache-block management instruction is permitted to
|
||||
* access the specified cache block whenever a load instruction
|
||||
* or store instruction is permitted to access the corresponding
|
||||
* physical addresses. If neither a load instruction nor store
|
||||
* instruction is permitted to access the physical addresses,
|
||||
* but an instruction fetch is permitted to access the physical
|
||||
* addresses, whether a cache-block management instruction is
|
||||
* permitted to access the cache block is UNSPECIFIED."
|
||||
*/
|
||||
ret = probe_access_flags(env, address, cbomlen, MMU_DATA_LOAD,
|
||||
mmu_idx, true, &phost, ra);
|
||||
if (ret != TLB_INVALID_MASK) {
|
||||
/* Success: readable */
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since not readable, must be writable. On failure, store
|
||||
* fault/store guest amo fault will be raised by
|
||||
* riscv_cpu_tlb_fill(). PMP exceptions will be caught
|
||||
* there as well.
|
||||
*/
|
||||
probe_write(env, address, cbomlen, mmu_idx, ra);
|
||||
}
|
||||
|
||||
void helper_cbo_clean_flush(CPURISCVState *env, target_ulong address)
|
||||
{
|
||||
uintptr_t ra = GETPC();
|
||||
check_zicbo_envcfg(env, MENVCFG_CBCFE, ra);
|
||||
check_zicbom_access(env, address, ra);
|
||||
|
||||
/* We don't emulate the cache-hierarchy, so we're done. */
|
||||
}
|
||||
|
||||
void helper_cbo_inval(CPURISCVState *env, target_ulong address)
|
||||
{
|
||||
uintptr_t ra = GETPC();
|
||||
check_zicbo_envcfg(env, MENVCFG_CBIE, ra);
|
||||
check_zicbom_access(env, address, ra);
|
||||
|
||||
/* We don't emulate the cache-hierarchy, so we're done. */
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
|
||||
target_ulong helper_sret(CPURISCVState *env)
|
||||
|
|
|
@ -1080,6 +1080,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
|
|||
#include "insn_trans/trans_rvb.c.inc"
|
||||
#include "insn_trans/trans_rvzicond.c.inc"
|
||||
#include "insn_trans/trans_rvzawrs.c.inc"
|
||||
#include "insn_trans/trans_rvzicbo.c.inc"
|
||||
#include "insn_trans/trans_rvzfh.c.inc"
|
||||
#include "insn_trans/trans_rvk.c.inc"
|
||||
#include "insn_trans/trans_privileged.c.inc"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue