2018-03-02 13:31:10 +01:00
|
|
|
/*
|
|
|
|
* QEMU RISC-V CPU
|
|
|
|
*
|
|
|
|
* Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
|
|
|
|
* Copyright (c) 2017-2018 SiFive, Inc.
|
|
|
|
*
|
|
|
|
* 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/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "qemu/osdep.h"
|
2019-04-17 21:17:57 +02:00
|
|
|
#include "qemu/qemu-print.h"
|
2019-05-23 16:35:06 +02:00
|
|
|
#include "qemu/ctype.h"
|
2018-03-02 13:31:10 +01:00
|
|
|
#include "qemu/log.h"
|
|
|
|
#include "cpu.h"
|
2023-01-31 21:20:11 +01:00
|
|
|
#include "cpu_vendorid.h"
|
2020-10-26 12:55:26 +01:00
|
|
|
#include "internals.h"
|
2018-03-02 13:31:10 +01:00
|
|
|
#include "exec/exec-all.h"
|
|
|
|
#include "qapi/error.h"
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
#include "qapi/visitor.h"
|
2019-05-07 00:49:53 +02:00
|
|
|
#include "qemu/error-report.h"
|
2019-04-20 04:24:01 +02:00
|
|
|
#include "hw/qdev-properties.h"
|
2024-01-06 00:05:37 +01:00
|
|
|
#include "hw/core/qdev-prop-internal.h"
|
2018-03-02 13:31:10 +01:00
|
|
|
#include "migration/vmstate.h"
|
2019-08-08 18:29:41 +02:00
|
|
|
#include "fpu/softfloat-helpers.h"
|
2022-01-12 09:13:22 +01:00
|
|
|
#include "sysemu/kvm.h"
|
2023-07-06 12:17:19 +02:00
|
|
|
#include "sysemu/tcg.h"
|
2023-09-25 19:57:02 +02:00
|
|
|
#include "kvm/kvm_riscv.h"
|
2023-10-18 21:56:35 +02:00
|
|
|
#include "tcg/tcg-cpu.h"
|
2023-02-27 14:51:52 +01:00
|
|
|
#include "tcg/tcg.h"
|
2018-03-02 13:31:10 +01:00
|
|
|
|
|
|
|
/* RISC-V CPU definitions */
|
2024-01-11 17:16:43 +01:00
|
|
|
static const char riscv_single_letter_exts[] = "IEMAFDQCBPVH";
|
2023-09-25 19:57:03 +02:00
|
|
|
const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV,
|
2024-01-11 17:16:43 +01:00
|
|
|
RVC, RVS, RVU, RVH, RVJ, RVG, RVB, 0};
|
2018-03-02 13:31:10 +01:00
|
|
|
|
2023-06-29 10:37:30 +02:00
|
|
|
/*
|
|
|
|
* From vector_helper.c
|
|
|
|
* Note that vector data is stored in host-endian 64-bit chunks,
|
|
|
|
* so addressing bytes needs a host-endian fixup.
|
|
|
|
*/
|
|
|
|
#if HOST_BIG_ENDIAN
|
|
|
|
#define BYTE(x) ((x) ^ 7)
|
|
|
|
#else
|
|
|
|
#define BYTE(x) (x)
|
|
|
|
#endif
|
|
|
|
|
2023-12-18 13:53:30 +01:00
|
|
|
bool riscv_cpu_is_32bit(RISCVCPU *cpu)
|
|
|
|
{
|
|
|
|
return riscv_cpu_mxl(&cpu->env) == MXL_RV32;
|
|
|
|
}
|
|
|
|
|
2024-01-06 00:05:32 +01:00
|
|
|
/* Hash that stores general user set numeric options */
|
|
|
|
static GHashTable *general_user_opts;
|
|
|
|
|
|
|
|
static void cpu_option_add_user_setting(const char *optname, uint32_t value)
|
|
|
|
{
|
|
|
|
g_hash_table_insert(general_user_opts, (gpointer)optname,
|
|
|
|
GUINT_TO_POINTER(value));
|
|
|
|
}
|
|
|
|
|
2024-01-12 15:01:54 +01:00
|
|
|
bool riscv_cpu_option_set(const char *optname)
|
|
|
|
{
|
|
|
|
return g_hash_table_contains(general_user_opts, optname);
|
|
|
|
}
|
|
|
|
|
2023-09-25 19:57:08 +02:00
|
|
|
#define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \
|
|
|
|
{#_name, _min_ver, CPU_CFG_OFFSET(_prop)}
|
|
|
|
|
2023-04-05 10:58:12 +02:00
|
|
|
/*
|
2022-06-30 08:11:50 +02:00
|
|
|
* Here are the ordering rules of extension naming defined by RISC-V
|
|
|
|
* specification :
|
|
|
|
* 1. All extensions should be separated from other multi-letter extensions
|
|
|
|
* by an underscore.
|
|
|
|
* 2. The first letter following the 'Z' conventionally indicates the most
|
|
|
|
* closely related alphabetical extension category, IMAFDQLCBKJTPVH.
|
|
|
|
* If multiple 'Z' extensions are named, they should be ordered first
|
|
|
|
* by category, then alphabetically within a category.
|
|
|
|
* 3. Standard supervisor-level extensions (starts with 'S') should be
|
|
|
|
* listed after standard unprivileged extensions. If multiple
|
|
|
|
* supervisor-level extensions are listed, they should be ordered
|
|
|
|
* alphabetically.
|
|
|
|
* 4. Non-standard extensions (starts with 'X') must be listed after all
|
|
|
|
* standard extensions. They must be separated from other multi-letter
|
|
|
|
* extensions by an underscore.
|
2023-04-06 20:03:33 +02:00
|
|
|
*
|
|
|
|
* Single letter extensions are checked in riscv_cpu_validate_misa_priv()
|
|
|
|
* instead.
|
2022-06-30 08:11:50 +02:00
|
|
|
*/
|
2023-09-25 19:57:08 +02:00
|
|
|
const RISCVIsaExtData isa_edata_arr[] = {
|
2023-10-12 18:46:03 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_zicbom),
|
2023-12-18 13:53:13 +01:00
|
|
|
ISA_EXT_DATA_ENTRY(zicbop, PRIV_VERSION_1_12_0, ext_zicbop),
|
2023-10-12 18:46:04 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_zicboz),
|
2023-04-06 20:03:34 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
|
target/riscv: add zicntr extension flag for TCG
zicntr is the Base Counters and Timers extension described in chapter 12
of the unprivileged spec. It describes support for RDCYCLE, RDTIME and
RDINSTRET.
QEMU already implements it in TCG way before it was a discrete
extension. zicntr is part of the RVA22 profile, so let's add it to QEMU
to make the future profile implementation flag complete. Given than it
represents an already existing feature, default it to 'true' for all
CPUs.
For TCG, we need a way to disable zicntr if the user wants to. This is
done by restricting access to the CYCLE, TIME, and INSTRET counters via
the 'ctr()' predicate when we're about to access them.
Disabling zicntr happens via the command line or if its dependency,
zicsr, happens to be disabled. We'll check for zicsr during realize()
and, in case it's absent, disable zicntr. However, if the user was
explicit about having zicntr support, error out instead of disabling it.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20231023153927.435083-2-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-10-23 17:39:24 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zicntr, PRIV_VERSION_1_12_0, ext_zicntr),
|
2023-10-12 18:46:02 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_zicsr),
|
2023-10-12 18:46:01 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_zifencei),
|
target/riscv: Add Zihintntl extension ISA string to DTS
RVA23 Profiles states:
The RVA23 profiles are intended to be used for 64-bit application
processors that will run rich OS stacks from standard binary OS
distributions and with a substantial number of third-party binary user
applications that will be supported over a considerable length of time
in the field.
The chapter 4 of the unprivileged spec introduces the Zihintntl extension
and Zihintntl is a mandatory extension presented in RVA23 Profiles, whose
purpose is to enable application and operating system portability across
different implementations. Thus the DTS should contain the Zihintntl ISA
string in order to pass to software.
The unprivileged spec states:
Like any HINTs, these instructions may be freely ignored. Hence, although
they are described in terms of cache-based memory hierarchies, they do not
mandate the provision of caches.
These instructions are encoded with non-used opcode, e.g. ADD x0, x0, x2,
which QEMU already supports, and QEMU does not emulate cache. Therefore
these instructions can be considered as a no-op, and we only need to add
a new property for the Zihintntl extension.
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Jason Chien <jason.chien@sifive.com>
Message-ID: <20230726074049.19505-2-jason.chien@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-07-26 09:40:46 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl),
|
2023-04-06 20:03:34 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
|
2023-10-23 17:39:26 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zihpm, PRIV_VERSION_1_12_0, ext_zihpm),
|
2023-07-20 15:24:23 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
|
2023-12-07 16:32:30 +01:00
|
|
|
ISA_EXT_DATA_ENTRY(zacas, PRIV_VERSION_1_12_0, ext_zacas),
|
2023-04-06 20:03:34 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
|
2023-07-10 09:12:43 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
|
2023-06-15 08:33:01 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
|
2023-04-06 20:03:34 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zfh, PRIV_VERSION_1_11_0, ext_zfh),
|
|
|
|
ISA_EXT_DATA_ENTRY(zfhmin, PRIV_VERSION_1_11_0, ext_zfhmin),
|
|
|
|
ISA_EXT_DATA_ENTRY(zfinx, PRIV_VERSION_1_12_0, ext_zfinx),
|
|
|
|
ISA_EXT_DATA_ENTRY(zdinx, PRIV_VERSION_1_12_0, ext_zdinx),
|
|
|
|
ISA_EXT_DATA_ENTRY(zca, PRIV_VERSION_1_12_0, ext_zca),
|
|
|
|
ISA_EXT_DATA_ENTRY(zcb, PRIV_VERSION_1_12_0, ext_zcb),
|
|
|
|
ISA_EXT_DATA_ENTRY(zcf, PRIV_VERSION_1_12_0, ext_zcf),
|
|
|
|
ISA_EXT_DATA_ENTRY(zcd, PRIV_VERSION_1_12_0, ext_zcd),
|
|
|
|
ISA_EXT_DATA_ENTRY(zce, PRIV_VERSION_1_12_0, ext_zce),
|
|
|
|
ISA_EXT_DATA_ENTRY(zcmp, PRIV_VERSION_1_12_0, ext_zcmp),
|
|
|
|
ISA_EXT_DATA_ENTRY(zcmt, PRIV_VERSION_1_12_0, ext_zcmt),
|
|
|
|
ISA_EXT_DATA_ENTRY(zba, PRIV_VERSION_1_12_0, ext_zba),
|
|
|
|
ISA_EXT_DATA_ENTRY(zbb, PRIV_VERSION_1_12_0, ext_zbb),
|
|
|
|
ISA_EXT_DATA_ENTRY(zbc, PRIV_VERSION_1_12_0, ext_zbc),
|
|
|
|
ISA_EXT_DATA_ENTRY(zbkb, PRIV_VERSION_1_12_0, ext_zbkb),
|
|
|
|
ISA_EXT_DATA_ENTRY(zbkc, PRIV_VERSION_1_12_0, ext_zbkc),
|
|
|
|
ISA_EXT_DATA_ENTRY(zbkx, PRIV_VERSION_1_12_0, ext_zbkx),
|
|
|
|
ISA_EXT_DATA_ENTRY(zbs, PRIV_VERSION_1_12_0, ext_zbs),
|
|
|
|
ISA_EXT_DATA_ENTRY(zk, PRIV_VERSION_1_12_0, ext_zk),
|
|
|
|
ISA_EXT_DATA_ENTRY(zkn, PRIV_VERSION_1_12_0, ext_zkn),
|
|
|
|
ISA_EXT_DATA_ENTRY(zknd, PRIV_VERSION_1_12_0, ext_zknd),
|
|
|
|
ISA_EXT_DATA_ENTRY(zkne, PRIV_VERSION_1_12_0, ext_zkne),
|
|
|
|
ISA_EXT_DATA_ENTRY(zknh, PRIV_VERSION_1_12_0, ext_zknh),
|
|
|
|
ISA_EXT_DATA_ENTRY(zkr, PRIV_VERSION_1_12_0, ext_zkr),
|
|
|
|
ISA_EXT_DATA_ENTRY(zks, PRIV_VERSION_1_12_0, ext_zks),
|
|
|
|
ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
|
|
|
|
ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
|
|
|
|
ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
|
2023-07-11 18:59:07 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
|
2023-07-11 18:59:03 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
|
2023-04-06 20:03:34 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
|
|
|
|
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
|
|
|
|
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
|
2023-06-15 08:33:01 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
|
|
|
|
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
|
2023-04-06 20:03:34 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
|
|
|
|
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
|
2023-10-26 17:18:12 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zvkb, PRIV_VERSION_1_12_0, ext_zvkb),
|
2023-07-11 18:59:11 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zvkg, PRIV_VERSION_1_12_0, ext_zvkg),
|
2023-10-26 17:18:14 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zvkn, PRIV_VERSION_1_12_0, ext_zvkn),
|
|
|
|
ISA_EXT_DATA_ENTRY(zvknc, PRIV_VERSION_1_12_0, ext_zvknc),
|
2023-07-11 18:59:08 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
|
2023-10-26 17:18:14 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zvkng, PRIV_VERSION_1_12_0, ext_zvkng),
|
2023-07-11 18:59:09 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
|
|
|
|
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
|
2023-10-26 17:18:16 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zvks, PRIV_VERSION_1_12_0, ext_zvks),
|
|
|
|
ISA_EXT_DATA_ENTRY(zvksc, PRIV_VERSION_1_12_0, ext_zvksc),
|
2023-07-11 18:59:14 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zvksed, PRIV_VERSION_1_12_0, ext_zvksed),
|
2023-10-26 17:18:16 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zvksg, PRIV_VERSION_1_12_0, ext_zvksg),
|
2023-07-11 18:59:10 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh),
|
2023-10-26 17:18:09 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zvkt, PRIV_VERSION_1_12_0, ext_zvkt),
|
2023-04-06 20:03:34 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
|
|
|
|
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
|
|
|
|
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
|
2023-10-19 08:55:46 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
|
2023-05-18 19:50:58 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
|
2023-04-06 20:03:34 +02:00
|
|
|
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
|
|
|
|
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
|
|
|
|
ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
|
|
|
|
ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu),
|
|
|
|
ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
|
|
|
|
ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot),
|
|
|
|
ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt),
|
|
|
|
ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba),
|
|
|
|
ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb),
|
|
|
|
ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs),
|
|
|
|
ISA_EXT_DATA_ENTRY(xtheadcmo, PRIV_VERSION_1_11_0, ext_xtheadcmo),
|
|
|
|
ISA_EXT_DATA_ENTRY(xtheadcondmov, PRIV_VERSION_1_11_0, ext_xtheadcondmov),
|
|
|
|
ISA_EXT_DATA_ENTRY(xtheadfmemidx, PRIV_VERSION_1_11_0, ext_xtheadfmemidx),
|
|
|
|
ISA_EXT_DATA_ENTRY(xtheadfmv, PRIV_VERSION_1_11_0, ext_xtheadfmv),
|
|
|
|
ISA_EXT_DATA_ENTRY(xtheadmac, PRIV_VERSION_1_11_0, ext_xtheadmac),
|
|
|
|
ISA_EXT_DATA_ENTRY(xtheadmemidx, PRIV_VERSION_1_11_0, ext_xtheadmemidx),
|
|
|
|
ISA_EXT_DATA_ENTRY(xtheadmempair, PRIV_VERSION_1_11_0, ext_xtheadmempair),
|
|
|
|
ISA_EXT_DATA_ENTRY(xtheadsync, PRIV_VERSION_1_11_0, ext_xtheadsync),
|
|
|
|
ISA_EXT_DATA_ENTRY(xventanacondops, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
|
2023-09-25 19:57:08 +02:00
|
|
|
|
|
|
|
DEFINE_PROP_END_OF_LIST(),
|
2022-06-30 08:11:50 +02:00
|
|
|
};
|
|
|
|
|
2023-09-25 19:56:53 +02:00
|
|
|
bool isa_ext_is_enabled(RISCVCPU *cpu, uint32_t ext_offset)
|
2022-06-30 08:11:50 +02:00
|
|
|
{
|
2023-09-12 15:24:16 +02:00
|
|
|
bool *ext_enabled = (void *)&cpu->cfg + ext_offset;
|
2022-06-30 08:11:50 +02:00
|
|
|
|
|
|
|
return *ext_enabled;
|
|
|
|
}
|
|
|
|
|
2023-09-25 19:56:53 +02:00
|
|
|
void isa_ext_update_enabled(RISCVCPU *cpu, uint32_t ext_offset, bool en)
|
2022-06-30 08:11:50 +02:00
|
|
|
{
|
2023-09-12 15:24:16 +02:00
|
|
|
bool *ext_enabled = (void *)&cpu->cfg + ext_offset;
|
2022-06-30 08:11:50 +02:00
|
|
|
|
|
|
|
*ext_enabled = en;
|
|
|
|
}
|
|
|
|
|
2024-01-06 00:05:31 +01:00
|
|
|
bool riscv_cpu_is_vendor(Object *cpu_obj)
|
|
|
|
{
|
|
|
|
return object_dynamic_cast(cpu_obj, TYPE_RISCV_VENDOR_CPU) != NULL;
|
|
|
|
}
|
|
|
|
|
2018-03-02 13:31:10 +01:00
|
|
|
const char * const riscv_int_regnames[] = {
|
2023-04-05 10:58:11 +02:00
|
|
|
"x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
|
|
|
|
"x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
|
|
|
|
"x14/a4", "x15/a5", "x16/a6", "x17/a7", "x18/s2", "x19/s3", "x20/s4",
|
|
|
|
"x21/s5", "x22/s6", "x23/s7", "x24/s8", "x25/s9", "x26/s10", "x27/s11",
|
|
|
|
"x28/t3", "x29/t4", "x30/t5", "x31/t6"
|
2018-03-02 13:31:10 +01:00
|
|
|
};
|
|
|
|
|
2022-01-06 22:00:56 +01:00
|
|
|
const char * const riscv_int_regnamesh[] = {
|
2023-04-05 10:58:11 +02:00
|
|
|
"x0h/zeroh", "x1h/rah", "x2h/sph", "x3h/gph", "x4h/tph", "x5h/t0h",
|
|
|
|
"x6h/t1h", "x7h/t2h", "x8h/s0h", "x9h/s1h", "x10h/a0h", "x11h/a1h",
|
|
|
|
"x12h/a2h", "x13h/a3h", "x14h/a4h", "x15h/a5h", "x16h/a6h", "x17h/a7h",
|
|
|
|
"x18h/s2h", "x19h/s3h", "x20h/s4h", "x21h/s5h", "x22h/s6h", "x23h/s7h",
|
|
|
|
"x24h/s8h", "x25h/s9h", "x26h/s10h", "x27h/s11h", "x28h/t3h", "x29h/t4h",
|
|
|
|
"x30h/t5h", "x31h/t6h"
|
2022-01-06 22:00:56 +01:00
|
|
|
};
|
|
|
|
|
2018-03-02 13:31:10 +01:00
|
|
|
const char * const riscv_fpr_regnames[] = {
|
2023-04-05 10:58:11 +02:00
|
|
|
"f0/ft0", "f1/ft1", "f2/ft2", "f3/ft3", "f4/ft4", "f5/ft5",
|
|
|
|
"f6/ft6", "f7/ft7", "f8/fs0", "f9/fs1", "f10/fa0", "f11/fa1",
|
|
|
|
"f12/fa2", "f13/fa3", "f14/fa4", "f15/fa5", "f16/fa6", "f17/fa7",
|
|
|
|
"f18/fs2", "f19/fs3", "f20/fs4", "f21/fs5", "f22/fs6", "f23/fs7",
|
|
|
|
"f24/fs8", "f25/fs9", "f26/fs10", "f27/fs11", "f28/ft8", "f29/ft9",
|
|
|
|
"f30/ft10", "f31/ft11"
|
2018-03-02 13:31:10 +01:00
|
|
|
};
|
|
|
|
|
2023-06-29 10:37:30 +02:00
|
|
|
const char * const riscv_rvv_regnames[] = {
|
|
|
|
"v0", "v1", "v2", "v3", "v4", "v5", "v6",
|
|
|
|
"v7", "v8", "v9", "v10", "v11", "v12", "v13",
|
|
|
|
"v14", "v15", "v16", "v17", "v18", "v19", "v20",
|
|
|
|
"v21", "v22", "v23", "v24", "v25", "v26", "v27",
|
|
|
|
"v28", "v29", "v30", "v31"
|
|
|
|
};
|
|
|
|
|
2021-05-14 07:24:35 +02:00
|
|
|
static const char * const riscv_excp_names[] = {
|
2018-03-02 13:31:10 +01:00
|
|
|
"misaligned_fetch",
|
|
|
|
"fault_fetch",
|
|
|
|
"illegal_instruction",
|
|
|
|
"breakpoint",
|
|
|
|
"misaligned_load",
|
|
|
|
"fault_load",
|
|
|
|
"misaligned_store",
|
|
|
|
"fault_store",
|
|
|
|
"user_ecall",
|
|
|
|
"supervisor_ecall",
|
|
|
|
"hypervisor_ecall",
|
|
|
|
"machine_ecall",
|
|
|
|
"exec_page_fault",
|
|
|
|
"load_page_fault",
|
|
|
|
"reserved",
|
2020-03-05 17:46:20 +01:00
|
|
|
"store_page_fault",
|
2020-02-01 02:01:46 +01:00
|
|
|
"reserved",
|
|
|
|
"reserved",
|
|
|
|
"reserved",
|
|
|
|
"reserved",
|
|
|
|
"guest_exec_page_fault",
|
|
|
|
"guest_load_page_fault",
|
|
|
|
"reserved",
|
2020-03-05 17:46:20 +01:00
|
|
|
"guest_store_page_fault",
|
2018-03-02 13:31:10 +01:00
|
|
|
};
|
|
|
|
|
2021-05-14 07:24:35 +02:00
|
|
|
static const char * const riscv_intr_names[] = {
|
2018-03-02 13:31:10 +01:00
|
|
|
"u_software",
|
|
|
|
"s_software",
|
2020-02-01 02:01:49 +01:00
|
|
|
"vs_software",
|
2018-03-02 13:31:10 +01:00
|
|
|
"m_software",
|
|
|
|
"u_timer",
|
|
|
|
"s_timer",
|
2020-02-01 02:01:49 +01:00
|
|
|
"vs_timer",
|
2018-03-02 13:31:10 +01:00
|
|
|
"m_timer",
|
|
|
|
"u_external",
|
2021-04-21 15:32:36 +02:00
|
|
|
"s_external",
|
2020-02-01 02:01:49 +01:00
|
|
|
"vs_external",
|
2018-03-02 13:31:10 +01:00
|
|
|
"m_external",
|
2018-03-05 22:51:53 +01:00
|
|
|
"reserved",
|
|
|
|
"reserved",
|
|
|
|
"reserved",
|
|
|
|
"reserved"
|
2018-03-02 13:31:10 +01:00
|
|
|
};
|
|
|
|
|
2020-08-14 05:58:19 +02:00
|
|
|
const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
|
|
|
|
{
|
|
|
|
if (async) {
|
|
|
|
return (cause < ARRAY_SIZE(riscv_intr_names)) ?
|
|
|
|
riscv_intr_names[cause] : "(unknown)";
|
|
|
|
} else {
|
|
|
|
return (cause < ARRAY_SIZE(riscv_excp_names)) ?
|
|
|
|
riscv_excp_names[cause] : "(unknown)";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-25 19:57:04 +02:00
|
|
|
void riscv_cpu_set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
|
2018-03-02 13:31:10 +01:00
|
|
|
{
|
2021-10-20 05:16:57 +02:00
|
|
|
env->misa_mxl_max = env->misa_mxl = mxl;
|
|
|
|
env->misa_ext_mask = env->misa_ext = ext;
|
2018-03-02 13:31:10 +01:00
|
|
|
}
|
|
|
|
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
#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)
|
|
|
|
{
|
target/riscv: fix satp_mode_finalize() when satp_mode.supported = 0
In the same emulated RISC-V host, the 'host' KVM CPU takes 4 times
longer to boot than the 'rv64' KVM CPU.
The reason is an unintended behavior of riscv_cpu_satp_mode_finalize()
when satp_mode.supported = 0, i.e. when cpu_init() does not set
satp_mode_max_supported(). satp_mode_max_from_map(map) does:
31 - __builtin_clz(map)
This means that, if satp_mode.supported = 0, satp_mode_supported_max
wil be '31 - 32'. But this is C, so satp_mode_supported_max will gladly
set it to UINT_MAX (4294967295). After that, if the user didn't set a
satp_mode, set_satp_mode_default_map(cpu) will make
cfg.satp_mode.map = cfg.satp_mode.supported
So satp_mode.map = 0. And then satp_mode_map_max will be set to
satp_mode_max_from_map(cpu->cfg.satp_mode.map), i.e. also UINT_MAX. The
guard "satp_mode_map_max > satp_mode_supported_max" doesn't protect us
here since both are UINT_MAX.
And finally we have 2 loops:
for (int i = satp_mode_map_max - 1; i >= 0; --i) {
Which are, in fact, 2 loops from UINT_MAX -1 to -1. This is where the
extra delay when booting the 'host' CPU is coming from.
Commit 43d1de32f8 already set a precedence for satp_mode.supported = 0
in a different manner. We're doing the same here. If supported == 0,
interpret as 'the CPU wants the OS to handle satp mode alone' and skip
satp_mode_finalize().
We'll also put a guard in satp_mode_max_from_map() to assert out if map
is 0 since the function is not ready to deal with it.
Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
Fixes: 6f23aaeb9b ("riscv: Allow user to set the satp mode")
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Message-ID: <20230817152903.694926-1-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-08-17 17:29:03 +02:00
|
|
|
/*
|
|
|
|
* 'map = 0' will make us return (31 - 32), which C will
|
|
|
|
* happily overflow to UINT_MAX. There's no good result to
|
|
|
|
* return if 'map = 0' (e.g. returning 0 will be ambiguous
|
|
|
|
* with the result for 'map = 1').
|
|
|
|
*
|
|
|
|
* Assert out if map = 0. Callers will have to deal with
|
|
|
|
* it outside of this function.
|
|
|
|
*/
|
|
|
|
g_assert(map > 0);
|
|
|
|
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
/* 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();
|
|
|
|
}
|
|
|
|
|
2023-03-03 14:12:51 +01:00
|
|
|
static void set_satp_mode_max_supported(RISCVCPU *cpu,
|
|
|
|
uint8_t satp_mode)
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
{
|
|
|
|
bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
|
2023-03-03 14:12:51 +01:00
|
|
|
const bool *valid_vm = rv32 ? valid_vm_1_10_32 : valid_vm_1_10_64;
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
|
2023-03-03 14:12:51 +01:00
|
|
|
for (int i = 0; i <= satp_mode; ++i) {
|
|
|
|
if (valid_vm[i]) {
|
|
|
|
cpu->cfg.satp_mode.supported |= (1 << i);
|
|
|
|
}
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
}
|
|
|
|
}
|
2023-03-03 14:12:51 +01:00
|
|
|
|
|
|
|
/* Set the satp mode to the max supported */
|
|
|
|
static void set_satp_mode_default_map(RISCVCPU *cpu)
|
|
|
|
{
|
target/riscv: add rv64i CPU
We don't have any form of a 'bare bones' CPU. rv64, our default CPUs,
comes with a lot of defaults. This is fine for most regular uses but
it's not suitable when more control of what is actually loaded in the
CPU is required.
A bare-bones CPU would be annoying to deal with if not by profile
support, a way to load a multitude of extensions with a single flag.
Profile support is going to be implemented shortly, so let's add a CPU
for it.
The new 'rv64i' CPU will have only RVI loaded. It is inspired in the
profile specification that dictates, for RVA22U64 [1]:
"RVA22U64 Mandatory Base
RV64I is the mandatory base ISA for RVA22U64"
And so it seems that RV64I is the mandatory base ISA for all profiles
listed in [1], making it an ideal CPU to use with profile support.
rv64i is a CPU of type TYPE_RISCV_BARE_CPU. It has a mix of features
from pre-existent CPUs:
- it allows extensions to be enabled, like generic CPUs;
- it will not inherit extension defaults, like vendor CPUs.
This is the minimum extension set to boot OpenSBI and buildroot using
rv64i:
./build/qemu-system-riscv64 -nographic -M virt \
-cpu rv64i,sv39=true,g=true,c=true,s=true,u=true
Our minimal riscv,isa in this case will be:
# cat /proc/device-tree/cpus/cpu@0/riscv,isa
rv64imafdc_zicntr_zicsr_zifencei_zihpm_zca_zcd#
[1] https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20231218125334.37184-5-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-12-18 13:53:12 +01:00
|
|
|
/*
|
|
|
|
* Bare CPUs do not default to the max available.
|
|
|
|
* Users must set a valid satp_mode in the command
|
|
|
|
* line.
|
|
|
|
*/
|
|
|
|
if (object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_BARE_CPU) != NULL) {
|
|
|
|
warn_report("No satp mode set. Defaulting to 'bare'");
|
|
|
|
cpu->cfg.satp_mode.map = (1 << VM_1_10_MBARE);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-03-03 14:12:51 +01:00
|
|
|
cpu->cfg.satp_mode.map = cpu->cfg.satp_mode.supported;
|
|
|
|
}
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
#endif
|
|
|
|
|
2018-03-02 13:31:10 +01:00
|
|
|
static void riscv_any_cpu_init(Object *obj)
|
|
|
|
{
|
2023-05-17 15:57:13 +02:00
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
CPURISCVState *env = &cpu->env;
|
2021-04-24 05:28:33 +02:00
|
|
|
#if defined(TARGET_RISCV32)
|
2023-09-25 19:57:04 +02:00
|
|
|
riscv_cpu_set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
|
2021-04-24 05:28:33 +02:00
|
|
|
#elif defined(TARGET_RISCV64)
|
2023-09-25 19:57:04 +02:00
|
|
|
riscv_cpu_set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
|
2021-04-24 05:28:33 +02:00
|
|
|
#endif
|
2023-03-03 14:12:51 +01:00
|
|
|
|
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
set_satp_mode_max_supported(RISCV_CPU(obj),
|
2023-04-05 10:58:11 +02:00
|
|
|
riscv_cpu_mxl(&RISCV_CPU(obj)->env) == MXL_RV32 ?
|
|
|
|
VM_1_10_SV32 : VM_1_10_SV57);
|
2023-03-03 14:12:51 +01:00
|
|
|
#endif
|
|
|
|
|
2023-05-17 15:57:07 +02:00
|
|
|
env->priv_ver = PRIV_VERSION_LATEST;
|
2023-05-17 15:57:13 +02:00
|
|
|
|
|
|
|
/* inherited from parent obj via riscv_cpu_init() */
|
2023-10-12 18:46:01 +02:00
|
|
|
cpu->cfg.ext_zifencei = true;
|
2023-10-12 18:46:02 +02:00
|
|
|
cpu->cfg.ext_zicsr = true;
|
2023-05-17 15:57:13 +02:00
|
|
|
cpu->cfg.mmu = true;
|
|
|
|
cpu->cfg.pmp = true;
|
2018-03-02 13:31:10 +01:00
|
|
|
}
|
|
|
|
|
2023-09-12 15:24:13 +02:00
|
|
|
static void riscv_max_cpu_init(Object *obj)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
CPURISCVState *env = &cpu->env;
|
|
|
|
RISCVMXL mlx = MXL_RV64;
|
|
|
|
|
2024-01-06 00:05:33 +01:00
|
|
|
cpu->cfg.mmu = true;
|
2024-01-06 00:05:34 +01:00
|
|
|
cpu->cfg.pmp = true;
|
2024-01-06 00:05:33 +01:00
|
|
|
|
2023-09-12 15:24:13 +02:00
|
|
|
#ifdef TARGET_RISCV32
|
|
|
|
mlx = MXL_RV32;
|
|
|
|
#endif
|
2023-09-25 19:57:04 +02:00
|
|
|
riscv_cpu_set_misa(env, mlx, 0);
|
2023-09-12 15:24:13 +02:00
|
|
|
env->priv_ver = PRIV_VERSION_LATEST;
|
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
set_satp_mode_max_supported(RISCV_CPU(obj), mlx == MXL_RV32 ?
|
|
|
|
VM_1_10_SV32 : VM_1_10_SV57);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2020-12-16 19:23:05 +01:00
|
|
|
#if defined(TARGET_RISCV64)
|
|
|
|
static void rv64_base_cpu_init(Object *obj)
|
2019-04-20 04:24:09 +02:00
|
|
|
{
|
2024-01-06 00:05:33 +01:00
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
CPURISCVState *env = &cpu->env;
|
|
|
|
|
|
|
|
cpu->cfg.mmu = true;
|
2024-01-06 00:05:34 +01:00
|
|
|
cpu->cfg.pmp = true;
|
2024-01-06 00:05:33 +01:00
|
|
|
|
2019-05-07 00:49:53 +02:00
|
|
|
/* We set this in the realise function */
|
2023-09-25 19:57:04 +02:00
|
|
|
riscv_cpu_set_misa(env, MXL_RV64, 0);
|
2022-06-11 10:01:04 +02:00
|
|
|
/* Set latest version of privileged specification */
|
2023-05-17 15:57:07 +02:00
|
|
|
env->priv_ver = PRIV_VERSION_LATEST;
|
2023-03-03 14:12:51 +01:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
|
|
|
|
#endif
|
2019-04-20 04:24:09 +02:00
|
|
|
}
|
|
|
|
|
2020-12-16 19:22:54 +01:00
|
|
|
static void rv64_sifive_u_cpu_init(Object *obj)
|
2018-03-02 13:31:10 +01:00
|
|
|
{
|
2023-05-17 15:57:13 +02:00
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
CPURISCVState *env = &cpu->env;
|
2023-09-25 19:57:04 +02:00
|
|
|
riscv_cpu_set_misa(env, MXL_RV64,
|
|
|
|
RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
|
2023-05-17 15:57:06 +02:00
|
|
|
env->priv_ver = PRIV_VERSION_1_10_0;
|
2023-03-03 14:12:51 +01:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
|
|
|
|
#endif
|
2023-05-17 15:57:13 +02:00
|
|
|
|
|
|
|
/* inherited from parent obj via riscv_cpu_init() */
|
2023-10-12 18:46:01 +02:00
|
|
|
cpu->cfg.ext_zifencei = true;
|
2023-10-12 18:46:02 +02:00
|
|
|
cpu->cfg.ext_zicsr = true;
|
2023-05-17 15:57:13 +02:00
|
|
|
cpu->cfg.mmu = true;
|
|
|
|
cpu->cfg.pmp = true;
|
2018-03-02 13:31:10 +01:00
|
|
|
}
|
|
|
|
|
2020-12-16 19:22:54 +01:00
|
|
|
static void rv64_sifive_e_cpu_init(Object *obj)
|
2020-04-23 19:50:09 +02:00
|
|
|
{
|
|
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
2022-06-08 08:14:37 +02:00
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
|
2023-09-25 19:57:04 +02:00
|
|
|
riscv_cpu_set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
|
2023-05-17 15:57:06 +02:00
|
|
|
env->priv_ver = PRIV_VERSION_1_10_0;
|
2023-03-03 14:12:51 +01:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
|
|
|
|
#endif
|
2023-05-17 15:57:13 +02:00
|
|
|
|
|
|
|
/* inherited from parent obj via riscv_cpu_init() */
|
2023-10-12 18:46:01 +02:00
|
|
|
cpu->cfg.ext_zifencei = true;
|
2023-10-12 18:46:02 +02:00
|
|
|
cpu->cfg.ext_zicsr = true;
|
2023-05-17 15:57:13 +02:00
|
|
|
cpu->cfg.pmp = true;
|
2020-04-23 19:50:09 +02:00
|
|
|
}
|
2022-01-06 22:00:57 +01:00
|
|
|
|
2023-01-31 21:20:11 +01:00
|
|
|
static void rv64_thead_c906_cpu_init(Object *obj)
|
|
|
|
{
|
|
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
|
2023-09-25 19:57:04 +02:00
|
|
|
riscv_cpu_set_misa(env, MXL_RV64, RVG | RVC | RVS | RVU);
|
2023-05-17 15:57:06 +02:00
|
|
|
env->priv_ver = PRIV_VERSION_1_11_0;
|
2023-01-31 21:20:11 +01:00
|
|
|
|
2023-07-10 09:12:43 +02:00
|
|
|
cpu->cfg.ext_zfa = true;
|
2023-01-31 21:20:11 +01:00
|
|
|
cpu->cfg.ext_zfh = true;
|
|
|
|
cpu->cfg.mmu = true;
|
|
|
|
cpu->cfg.ext_xtheadba = true;
|
|
|
|
cpu->cfg.ext_xtheadbb = true;
|
|
|
|
cpu->cfg.ext_xtheadbs = true;
|
|
|
|
cpu->cfg.ext_xtheadcmo = true;
|
|
|
|
cpu->cfg.ext_xtheadcondmov = true;
|
|
|
|
cpu->cfg.ext_xtheadfmemidx = true;
|
|
|
|
cpu->cfg.ext_xtheadmac = true;
|
|
|
|
cpu->cfg.ext_xtheadmemidx = true;
|
|
|
|
cpu->cfg.ext_xtheadmempair = true;
|
|
|
|
cpu->cfg.ext_xtheadsync = true;
|
|
|
|
|
|
|
|
cpu->cfg.mvendorid = THEAD_VENDOR_ID;
|
2023-03-03 14:12:51 +01:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
set_satp_mode_max_supported(cpu, VM_1_10_SV39);
|
|
|
|
#endif
|
2023-05-17 15:57:13 +02:00
|
|
|
|
|
|
|
/* inherited from parent obj via riscv_cpu_init() */
|
|
|
|
cpu->cfg.pmp = true;
|
2023-01-31 21:20:11 +01:00
|
|
|
}
|
|
|
|
|
2023-04-18 14:36:24 +02:00
|
|
|
static void rv64_veyron_v1_cpu_init(Object *obj)
|
|
|
|
{
|
|
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
|
2023-09-25 19:57:04 +02:00
|
|
|
riscv_cpu_set_misa(env, MXL_RV64, RVG | RVC | RVS | RVU | RVH);
|
2023-04-18 14:36:24 +02:00
|
|
|
env->priv_ver = PRIV_VERSION_1_12_0;
|
|
|
|
|
|
|
|
/* Enable ISA extensions */
|
|
|
|
cpu->cfg.mmu = true;
|
2023-10-12 18:46:01 +02:00
|
|
|
cpu->cfg.ext_zifencei = true;
|
2023-10-12 18:46:02 +02:00
|
|
|
cpu->cfg.ext_zicsr = true;
|
target/riscv/cpu.c: fix veyron-v1 CPU properties
Commit 7f0bdfb5bfc2 ("target/riscv/cpu.c: remove cfg setup from
riscv_cpu_init()") removed code that was enabling mmu, pmp, ext_ifencei
and ext_icsr from riscv_cpu_init(), the init() function of
TYPE_RISCV_CPU, parent type of all RISC-V CPUss. This was done to force
CPUs to explictly enable all extensions and features it requires,
without any 'magic values' that were inherited by the parent type.
This commit failed to make appropriate changes in the 'veyron-v1' CPU,
added earlier by commit e1d084a8524a. The result is that the veyron-v1
CPU has ext_ifencei, ext_icsr and pmp set to 'false', which is not the
case.
The reason why it took this long to notice (thanks LIU Zhiwei for
reporting it) is because Linux doesn't mind 'ifencei' and 'icsr' being
absent in the 'riscv,isa' DT, implying that they're both present if the
'i' extension is enabled. OpenSBI also doesn't error out or warns about
the lack of 'pmp', it'll just not protect memory pages.
Fix it by setting them to 'true' in rv64_veyron_v1_cpu_init() like
7f0bdfb5bfc2 already did with other CPUs.
Reported-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Fixes: 7f0bdfb5bfc2 ("target/riscv/cpu.c: remove cfg setup from riscv_cpu_init()")
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Message-Id: <20230620152443.137079-1-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-06-20 17:24:43 +02:00
|
|
|
cpu->cfg.pmp = true;
|
2023-10-12 18:46:03 +02:00
|
|
|
cpu->cfg.ext_zicbom = true;
|
2023-04-18 14:36:24 +02:00
|
|
|
cpu->cfg.cbom_blocksize = 64;
|
|
|
|
cpu->cfg.cboz_blocksize = 64;
|
2023-10-12 18:46:04 +02:00
|
|
|
cpu->cfg.ext_zicboz = true;
|
2023-04-18 14:36:24 +02:00
|
|
|
cpu->cfg.ext_smaia = true;
|
|
|
|
cpu->cfg.ext_ssaia = true;
|
|
|
|
cpu->cfg.ext_sscofpmf = true;
|
|
|
|
cpu->cfg.ext_sstc = true;
|
|
|
|
cpu->cfg.ext_svinval = true;
|
|
|
|
cpu->cfg.ext_svnapot = true;
|
|
|
|
cpu->cfg.ext_svpbmt = true;
|
|
|
|
cpu->cfg.ext_smstateen = true;
|
|
|
|
cpu->cfg.ext_zba = true;
|
|
|
|
cpu->cfg.ext_zbb = true;
|
|
|
|
cpu->cfg.ext_zbc = true;
|
|
|
|
cpu->cfg.ext_zbs = true;
|
|
|
|
cpu->cfg.ext_XVentanaCondOps = true;
|
|
|
|
|
|
|
|
cpu->cfg.mvendorid = VEYRON_V1_MVENDORID;
|
|
|
|
cpu->cfg.marchid = VEYRON_V1_MARCHID;
|
|
|
|
cpu->cfg.mimpid = VEYRON_V1_MIMPID;
|
|
|
|
|
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
set_satp_mode_max_supported(cpu, VM_1_10_SV48);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2022-01-06 22:00:57 +01:00
|
|
|
static void rv128_base_cpu_init(Object *obj)
|
|
|
|
{
|
2024-01-06 00:05:33 +01:00
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
CPURISCVState *env = &cpu->env;
|
|
|
|
|
2022-01-06 22:00:57 +01:00
|
|
|
if (qemu_tcg_mttcg_enabled()) {
|
|
|
|
/* Missing 128-bit aligned atomics */
|
|
|
|
error_report("128-bit RISC-V currently does not work with Multi "
|
|
|
|
"Threaded TCG. Please use: -accel tcg,thread=single");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2024-01-06 00:05:33 +01:00
|
|
|
|
|
|
|
cpu->cfg.mmu = true;
|
2024-01-06 00:05:34 +01:00
|
|
|
cpu->cfg.pmp = true;
|
2024-01-06 00:05:33 +01:00
|
|
|
|
2022-01-06 22:00:57 +01:00
|
|
|
/* We set this in the realise function */
|
2023-09-25 19:57:04 +02:00
|
|
|
riscv_cpu_set_misa(env, MXL_RV128, 0);
|
2022-06-11 10:01:04 +02:00
|
|
|
/* Set latest version of privileged specification */
|
2023-05-17 15:57:07 +02:00
|
|
|
env->priv_ver = PRIV_VERSION_LATEST;
|
2023-03-03 14:12:51 +01:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
|
|
|
|
#endif
|
2022-01-06 22:00:57 +01:00
|
|
|
}
|
target/riscv: add rv64i CPU
We don't have any form of a 'bare bones' CPU. rv64, our default CPUs,
comes with a lot of defaults. This is fine for most regular uses but
it's not suitable when more control of what is actually loaded in the
CPU is required.
A bare-bones CPU would be annoying to deal with if not by profile
support, a way to load a multitude of extensions with a single flag.
Profile support is going to be implemented shortly, so let's add a CPU
for it.
The new 'rv64i' CPU will have only RVI loaded. It is inspired in the
profile specification that dictates, for RVA22U64 [1]:
"RVA22U64 Mandatory Base
RV64I is the mandatory base ISA for RVA22U64"
And so it seems that RV64I is the mandatory base ISA for all profiles
listed in [1], making it an ideal CPU to use with profile support.
rv64i is a CPU of type TYPE_RISCV_BARE_CPU. It has a mix of features
from pre-existent CPUs:
- it allows extensions to be enabled, like generic CPUs;
- it will not inherit extension defaults, like vendor CPUs.
This is the minimum extension set to boot OpenSBI and buildroot using
rv64i:
./build/qemu-system-riscv64 -nographic -M virt \
-cpu rv64i,sv39=true,g=true,c=true,s=true,u=true
Our minimal riscv,isa in this case will be:
# cat /proc/device-tree/cpus/cpu@0/riscv,isa
rv64imafdc_zicntr_zicsr_zifencei_zihpm_zca_zcd#
[1] https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20231218125334.37184-5-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-12-18 13:53:12 +01:00
|
|
|
|
|
|
|
static void rv64i_bare_cpu_init(Object *obj)
|
|
|
|
{
|
|
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
|
|
|
riscv_cpu_set_misa(env, MXL_RV64, RVI);
|
|
|
|
|
|
|
|
/* Remove the defaults from the parent class */
|
|
|
|
RISCV_CPU(obj)->cfg.ext_zicntr = false;
|
|
|
|
RISCV_CPU(obj)->cfg.ext_zihpm = false;
|
|
|
|
|
|
|
|
/* Set to QEMU's first supported priv version */
|
|
|
|
env->priv_ver = PRIV_VERSION_1_10_0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Support all available satp_mode settings. The default
|
|
|
|
* value will be set to MBARE if the user doesn't set
|
|
|
|
* satp_mode manually (see set_satp_mode_default()).
|
|
|
|
*/
|
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV64);
|
|
|
|
#endif
|
|
|
|
}
|
2020-12-16 19:22:54 +01:00
|
|
|
#else
|
2020-12-16 19:23:05 +01:00
|
|
|
static void rv32_base_cpu_init(Object *obj)
|
|
|
|
{
|
2024-01-06 00:05:33 +01:00
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
CPURISCVState *env = &cpu->env;
|
|
|
|
|
|
|
|
cpu->cfg.mmu = true;
|
2024-01-06 00:05:34 +01:00
|
|
|
cpu->cfg.pmp = true;
|
2024-01-06 00:05:33 +01:00
|
|
|
|
2020-12-16 19:23:05 +01:00
|
|
|
/* We set this in the realise function */
|
2023-09-25 19:57:04 +02:00
|
|
|
riscv_cpu_set_misa(env, MXL_RV32, 0);
|
2022-06-11 10:01:04 +02:00
|
|
|
/* Set latest version of privileged specification */
|
2023-05-17 15:57:07 +02:00
|
|
|
env->priv_ver = PRIV_VERSION_LATEST;
|
2023-03-03 14:12:51 +01:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
|
|
|
|
#endif
|
2020-12-16 19:23:05 +01:00
|
|
|
}
|
|
|
|
|
2020-12-16 19:22:54 +01:00
|
|
|
static void rv32_sifive_u_cpu_init(Object *obj)
|
|
|
|
{
|
2023-05-17 15:57:13 +02:00
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
CPURISCVState *env = &cpu->env;
|
2023-09-25 19:57:04 +02:00
|
|
|
riscv_cpu_set_misa(env, MXL_RV32,
|
|
|
|
RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
|
2023-05-17 15:57:06 +02:00
|
|
|
env->priv_ver = PRIV_VERSION_1_10_0;
|
2023-03-03 14:12:51 +01:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
|
|
|
|
#endif
|
2023-05-17 15:57:13 +02:00
|
|
|
|
|
|
|
/* inherited from parent obj via riscv_cpu_init() */
|
2023-10-12 18:46:01 +02:00
|
|
|
cpu->cfg.ext_zifencei = true;
|
2023-10-12 18:46:02 +02:00
|
|
|
cpu->cfg.ext_zicsr = true;
|
2023-05-17 15:57:13 +02:00
|
|
|
cpu->cfg.mmu = true;
|
|
|
|
cpu->cfg.pmp = true;
|
2020-12-16 19:22:54 +01:00
|
|
|
}
|
2020-04-23 19:50:09 +02:00
|
|
|
|
2020-12-16 19:22:54 +01:00
|
|
|
static void rv32_sifive_e_cpu_init(Object *obj)
|
|
|
|
{
|
|
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
2022-06-08 08:14:37 +02:00
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
|
2023-09-25 19:57:04 +02:00
|
|
|
riscv_cpu_set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
|
2023-05-17 15:57:06 +02:00
|
|
|
env->priv_ver = PRIV_VERSION_1_10_0;
|
2023-03-03 14:12:51 +01:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
|
|
|
|
#endif
|
2023-05-17 15:57:13 +02:00
|
|
|
|
|
|
|
/* inherited from parent obj via riscv_cpu_init() */
|
2023-10-12 18:46:01 +02:00
|
|
|
cpu->cfg.ext_zifencei = true;
|
2023-10-12 18:46:02 +02:00
|
|
|
cpu->cfg.ext_zicsr = true;
|
2023-05-17 15:57:13 +02:00
|
|
|
cpu->cfg.pmp = true;
|
2020-12-16 19:22:54 +01:00
|
|
|
}
|
2020-06-11 03:08:48 +02:00
|
|
|
|
2020-06-16 02:50:37 +02:00
|
|
|
static void rv32_ibex_cpu_init(Object *obj)
|
2018-03-02 13:31:10 +01:00
|
|
|
{
|
|
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
2022-06-08 08:14:37 +02:00
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
|
2023-09-25 19:57:04 +02:00
|
|
|
riscv_cpu_set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
|
2023-11-02 01:34:24 +01:00
|
|
|
env->priv_ver = PRIV_VERSION_1_12_0;
|
2023-03-03 14:12:51 +01:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
|
|
|
|
#endif
|
2023-05-17 15:57:13 +02:00
|
|
|
/* inherited from parent obj via riscv_cpu_init() */
|
2023-10-12 18:46:01 +02:00
|
|
|
cpu->cfg.ext_zifencei = true;
|
2023-10-12 18:46:02 +02:00
|
|
|
cpu->cfg.ext_zicsr = true;
|
2023-05-17 15:57:13 +02:00
|
|
|
cpu->cfg.pmp = true;
|
2023-10-19 08:55:46 +02:00
|
|
|
cpu->cfg.ext_smepmp = true;
|
2018-03-02 13:31:10 +01:00
|
|
|
}
|
|
|
|
|
2020-06-11 03:08:49 +02:00
|
|
|
static void rv32_imafcu_nommu_cpu_init(Object *obj)
|
2020-03-13 20:34:29 +01:00
|
|
|
{
|
|
|
|
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
2022-06-08 08:14:37 +02:00
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
|
2023-09-25 19:57:04 +02:00
|
|
|
riscv_cpu_set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
|
2023-05-17 15:57:06 +02:00
|
|
|
env->priv_ver = PRIV_VERSION_1_10_0;
|
2023-03-03 14:12:51 +01:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
|
|
|
|
#endif
|
2023-05-17 15:57:13 +02:00
|
|
|
|
|
|
|
/* inherited from parent obj via riscv_cpu_init() */
|
2023-10-12 18:46:01 +02:00
|
|
|
cpu->cfg.ext_zifencei = true;
|
2023-10-12 18:46:02 +02:00
|
|
|
cpu->cfg.ext_zicsr = true;
|
2023-05-17 15:57:13 +02:00
|
|
|
cpu->cfg.pmp = true;
|
2020-03-13 20:34:29 +01:00
|
|
|
}
|
2018-03-08 23:12:31 +01:00
|
|
|
#endif
|
2018-03-02 13:31:10 +01:00
|
|
|
|
|
|
|
static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
|
|
|
|
{
|
|
|
|
ObjectClass *oc;
|
|
|
|
char *typename;
|
|
|
|
char **cpuname;
|
|
|
|
|
|
|
|
cpuname = g_strsplit(cpu_model, ",", 1);
|
|
|
|
typename = g_strdup_printf(RISCV_CPU_TYPE_NAME("%s"), cpuname[0]);
|
|
|
|
oc = object_class_by_name(typename);
|
|
|
|
g_strfreev(cpuname);
|
|
|
|
g_free(typename);
|
2023-09-08 10:09:23 +02:00
|
|
|
|
2018-03-02 13:31:10 +01:00
|
|
|
return oc;
|
|
|
|
}
|
|
|
|
|
2023-09-26 20:31:08 +02:00
|
|
|
char *riscv_cpu_get_name(RISCVCPU *cpu)
|
|
|
|
{
|
|
|
|
RISCVCPUClass *rcc = RISCV_CPU_GET_CLASS(cpu);
|
|
|
|
const char *typename = object_class_get_name(OBJECT_CLASS(rcc));
|
|
|
|
|
|
|
|
g_assert(g_str_has_suffix(typename, RISCV_CPU_TYPE_SUFFIX));
|
|
|
|
|
2023-11-15 00:56:19 +01:00
|
|
|
return cpu_model_from_type(typename);
|
2023-09-26 20:31:08 +02:00
|
|
|
}
|
|
|
|
|
2019-04-17 21:18:02 +02:00
|
|
|
static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
|
2018-03-02 13:31:10 +01:00
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(cs);
|
|
|
|
CPURISCVState *env = &cpu->env;
|
2023-06-29 10:37:30 +02:00
|
|
|
int i, j;
|
|
|
|
uint8_t *p;
|
2018-03-02 13:31:10 +01:00
|
|
|
|
2020-02-01 02:02:02 +01:00
|
|
|
#if !defined(CONFIG_USER_ONLY)
|
|
|
|
if (riscv_has_ext(env, RVH)) {
|
2023-04-05 10:58:10 +02:00
|
|
|
qemu_fprintf(f, " %s %d\n", "V = ", env->virt_enabled);
|
2020-02-01 02:02:02 +01:00
|
|
|
}
|
|
|
|
#endif
|
2019-04-17 21:18:02 +02:00
|
|
|
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc ", env->pc);
|
2018-03-02 13:31:10 +01:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
2021-10-20 05:17:08 +02:00
|
|
|
{
|
|
|
|
static const int dump_csrs[] = {
|
|
|
|
CSR_MHARTID,
|
|
|
|
CSR_MSTATUS,
|
|
|
|
CSR_MSTATUSH,
|
2022-11-25 06:03:54 +01:00
|
|
|
/*
|
|
|
|
* CSR_SSTATUS is intentionally omitted here as its value
|
|
|
|
* can be figured out by looking at CSR_MSTATUS
|
|
|
|
*/
|
2021-10-20 05:17:08 +02:00
|
|
|
CSR_HSTATUS,
|
|
|
|
CSR_VSSTATUS,
|
|
|
|
CSR_MIP,
|
|
|
|
CSR_MIE,
|
|
|
|
CSR_MIDELEG,
|
|
|
|
CSR_HIDELEG,
|
|
|
|
CSR_MEDELEG,
|
|
|
|
CSR_HEDELEG,
|
|
|
|
CSR_MTVEC,
|
|
|
|
CSR_STVEC,
|
|
|
|
CSR_VSTVEC,
|
|
|
|
CSR_MEPC,
|
|
|
|
CSR_SEPC,
|
|
|
|
CSR_VSEPC,
|
|
|
|
CSR_MCAUSE,
|
|
|
|
CSR_SCAUSE,
|
|
|
|
CSR_VSCAUSE,
|
|
|
|
CSR_MTVAL,
|
|
|
|
CSR_STVAL,
|
|
|
|
CSR_HTVAL,
|
|
|
|
CSR_MTVAL2,
|
|
|
|
CSR_MSCRATCH,
|
|
|
|
CSR_SSCRATCH,
|
|
|
|
CSR_SATP,
|
2021-10-25 19:36:06 +02:00
|
|
|
CSR_MMTE,
|
|
|
|
CSR_UPMBASE,
|
|
|
|
CSR_UPMMASK,
|
|
|
|
CSR_SPMBASE,
|
|
|
|
CSR_SPMMASK,
|
|
|
|
CSR_MPMBASE,
|
|
|
|
CSR_MPMMASK,
|
2021-10-20 05:17:08 +02:00
|
|
|
};
|
|
|
|
|
2023-09-25 06:30:21 +02:00
|
|
|
for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) {
|
2021-10-20 05:17:08 +02:00
|
|
|
int csrno = dump_csrs[i];
|
|
|
|
target_ulong val = 0;
|
|
|
|
RISCVException res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Rely on the smode, hmode, etc, predicates within csr.c
|
|
|
|
* to do the filtering of the registers that are present.
|
|
|
|
*/
|
|
|
|
if (res == RISCV_EXCP_NONE) {
|
|
|
|
qemu_fprintf(f, " %-8s " TARGET_FMT_lx "\n",
|
|
|
|
csr_ops[csrno].name, val);
|
|
|
|
}
|
|
|
|
}
|
2020-02-01 02:02:02 +01:00
|
|
|
}
|
2018-03-02 13:31:10 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
for (i = 0; i < 32; i++) {
|
2021-10-09 07:50:19 +02:00
|
|
|
qemu_fprintf(f, " %-8s " TARGET_FMT_lx,
|
2019-04-17 21:18:02 +02:00
|
|
|
riscv_int_regnames[i], env->gpr[i]);
|
2018-03-02 13:31:10 +01:00
|
|
|
if ((i & 3) == 3) {
|
2019-04-17 21:18:02 +02:00
|
|
|
qemu_fprintf(f, "\n");
|
2018-03-02 13:31:10 +01:00
|
|
|
}
|
|
|
|
}
|
2018-05-11 05:31:33 +02:00
|
|
|
if (flags & CPU_DUMP_FPU) {
|
|
|
|
for (i = 0; i < 32; i++) {
|
2021-10-09 07:50:19 +02:00
|
|
|
qemu_fprintf(f, " %-8s %016" PRIx64,
|
2019-04-17 21:18:02 +02:00
|
|
|
riscv_fpr_regnames[i], env->fpr[i]);
|
2018-05-11 05:31:33 +02:00
|
|
|
if ((i & 3) == 3) {
|
2019-04-17 21:18:02 +02:00
|
|
|
qemu_fprintf(f, "\n");
|
2018-05-11 05:31:33 +02:00
|
|
|
}
|
2018-03-02 13:31:10 +01:00
|
|
|
}
|
|
|
|
}
|
2023-06-29 10:37:30 +02:00
|
|
|
if (riscv_has_ext(env, RVV) && (flags & CPU_DUMP_VPU)) {
|
|
|
|
static const int dump_rvv_csrs[] = {
|
|
|
|
CSR_VSTART,
|
|
|
|
CSR_VXSAT,
|
|
|
|
CSR_VXRM,
|
|
|
|
CSR_VCSR,
|
|
|
|
CSR_VL,
|
|
|
|
CSR_VTYPE,
|
|
|
|
CSR_VLENB,
|
|
|
|
};
|
2023-09-25 06:30:21 +02:00
|
|
|
for (i = 0; i < ARRAY_SIZE(dump_rvv_csrs); ++i) {
|
2023-06-29 10:37:30 +02:00
|
|
|
int csrno = dump_rvv_csrs[i];
|
|
|
|
target_ulong val = 0;
|
|
|
|
RISCVException res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Rely on the smode, hmode, etc, predicates within csr.c
|
|
|
|
* to do the filtering of the registers that are present.
|
|
|
|
*/
|
|
|
|
if (res == RISCV_EXCP_NONE) {
|
|
|
|
qemu_fprintf(f, " %-8s " TARGET_FMT_lx "\n",
|
|
|
|
csr_ops[csrno].name, val);
|
|
|
|
}
|
|
|
|
}
|
2024-01-22 17:10:55 +01:00
|
|
|
uint16_t vlenb = cpu->cfg.vlenb;
|
2023-06-29 10:37:30 +02:00
|
|
|
|
|
|
|
for (i = 0; i < 32; i++) {
|
|
|
|
qemu_fprintf(f, " %-8s ", riscv_rvv_regnames[i]);
|
|
|
|
p = (uint8_t *)env->vreg;
|
|
|
|
for (j = vlenb - 1 ; j >= 0; j--) {
|
|
|
|
qemu_fprintf(f, "%02x", *(p + i * vlenb + BYTE(j)));
|
|
|
|
}
|
|
|
|
qemu_fprintf(f, "\n");
|
|
|
|
}
|
|
|
|
}
|
2018-03-02 13:31:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(cs);
|
|
|
|
CPURISCVState *env = &cpu->env;
|
2022-01-20 13:20:34 +01:00
|
|
|
|
|
|
|
if (env->xl == MXL_RV32) {
|
|
|
|
env->pc = (int32_t)value;
|
|
|
|
} else {
|
|
|
|
env->pc = value;
|
|
|
|
}
|
2018-03-02 13:31:10 +01:00
|
|
|
}
|
|
|
|
|
2022-09-30 19:31:21 +02:00
|
|
|
static vaddr riscv_cpu_get_pc(CPUState *cs)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(cs);
|
|
|
|
CPURISCVState *env = &cpu->env;
|
|
|
|
|
|
|
|
/* Match cpu_get_tb_cpu_state. */
|
|
|
|
if (env->xl == MXL_RV32) {
|
|
|
|
return env->pc & UINT32_MAX;
|
|
|
|
}
|
|
|
|
return env->pc;
|
|
|
|
}
|
|
|
|
|
2018-03-02 13:31:10 +01:00
|
|
|
static bool riscv_cpu_has_work(CPUState *cs)
|
|
|
|
{
|
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(cs);
|
|
|
|
CPURISCVState *env = &cpu->env;
|
|
|
|
/*
|
|
|
|
* Definition of the WFI instruction requires it to ignore the privilege
|
|
|
|
* mode and delegation registers, but respect individual enables
|
|
|
|
*/
|
2023-10-16 13:17:35 +02:00
|
|
|
return riscv_cpu_all_pending(env) != 0 ||
|
2023-10-16 13:17:36 +02:00
|
|
|
riscv_cpu_sirq_pending(env) != RISCV_EXCP_NONE ||
|
|
|
|
riscv_cpu_vsirq_pending(env) != RISCV_EXCP_NONE;
|
2018-03-02 13:31:10 +01:00
|
|
|
#else
|
|
|
|
return true;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2024-01-29 01:34:43 +01:00
|
|
|
static int riscv_cpu_mmu_index(CPUState *cs, bool ifetch)
|
|
|
|
{
|
|
|
|
return riscv_env_mmu_index(cpu_env(cs), ifetch);
|
|
|
|
}
|
|
|
|
|
2022-11-24 12:50:17 +01:00
|
|
|
static void riscv_cpu_reset_hold(Object *obj)
|
2018-03-02 13:31:10 +01:00
|
|
|
{
|
2022-02-04 18:46:45 +01:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
uint8_t iprio;
|
|
|
|
int i, irq, rdzero;
|
|
|
|
#endif
|
2022-11-24 12:50:17 +01:00
|
|
|
CPUState *cs = CPU(obj);
|
2018-03-02 13:31:10 +01:00
|
|
|
RISCVCPU *cpu = RISCV_CPU(cs);
|
|
|
|
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
|
|
|
|
CPURISCVState *env = &cpu->env;
|
|
|
|
|
2022-11-24 12:50:17 +01:00
|
|
|
if (mcc->parent_phases.hold) {
|
|
|
|
mcc->parent_phases.hold(obj);
|
|
|
|
}
|
2018-03-02 13:31:10 +01:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
2021-10-20 05:16:57 +02:00
|
|
|
env->misa_mxl = env->misa_mxl_max;
|
2018-03-02 13:31:10 +01:00
|
|
|
env->priv = PRV_M;
|
|
|
|
env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
|
2021-10-20 05:16:59 +02:00
|
|
|
if (env->misa_mxl > MXL_RV32) {
|
|
|
|
/*
|
|
|
|
* The reset status of SXL/UXL is undefined, but mstatus is WARL
|
|
|
|
* and we must ensure that the value after init is valid for read.
|
|
|
|
*/
|
|
|
|
env->mstatus = set_field(env->mstatus, MSTATUS64_SXL, env->misa_mxl);
|
|
|
|
env->mstatus = set_field(env->mstatus, MSTATUS64_UXL, env->misa_mxl);
|
2022-01-20 13:20:48 +01:00
|
|
|
if (riscv_has_ext(env, RVH)) {
|
|
|
|
env->vsstatus = set_field(env->vsstatus,
|
|
|
|
MSTATUS64_SXL, env->misa_mxl);
|
|
|
|
env->vsstatus = set_field(env->vsstatus,
|
|
|
|
MSTATUS64_UXL, env->misa_mxl);
|
|
|
|
env->mstatus_hs = set_field(env->mstatus_hs,
|
|
|
|
MSTATUS64_SXL, env->misa_mxl);
|
|
|
|
env->mstatus_hs = set_field(env->mstatus_hs,
|
|
|
|
MSTATUS64_UXL, env->misa_mxl);
|
|
|
|
}
|
2021-10-20 05:16:59 +02:00
|
|
|
}
|
2018-03-02 13:31:10 +01:00
|
|
|
env->mcause = 0;
|
2022-02-04 18:46:38 +01:00
|
|
|
env->miclaim = MIP_SGEIP;
|
2018-03-02 13:31:10 +01:00
|
|
|
env->pc = env->resetvec;
|
2022-05-11 16:45:23 +02:00
|
|
|
env->bins = 0;
|
2021-03-19 15:14:59 +01:00
|
|
|
env->two_stage_lookup = false;
|
2022-02-04 18:46:45 +01:00
|
|
|
|
2023-02-24 05:08:51 +01:00
|
|
|
env->menvcfg = (cpu->cfg.ext_svpbmt ? MENVCFG_PBMTE : 0) |
|
2023-08-16 16:19:16 +02:00
|
|
|
(cpu->cfg.ext_svadu ? MENVCFG_ADUE : 0);
|
2023-02-24 05:08:51 +01:00
|
|
|
env->henvcfg = (cpu->cfg.ext_svpbmt ? HENVCFG_PBMTE : 0) |
|
2023-08-16 16:19:16 +02:00
|
|
|
(cpu->cfg.ext_svadu ? HENVCFG_ADUE : 0);
|
2023-02-24 05:08:50 +01:00
|
|
|
|
2022-02-04 18:46:45 +01:00
|
|
|
/* Initialized default priorities of local interrupts. */
|
|
|
|
for (i = 0; i < ARRAY_SIZE(env->miprio); i++) {
|
|
|
|
iprio = riscv_cpu_default_priority(i);
|
|
|
|
env->miprio[i] = (i == IRQ_M_EXT) ? 0 : iprio;
|
|
|
|
env->siprio[i] = (i == IRQ_S_EXT) ? 0 : iprio;
|
|
|
|
env->hviprio[i] = 0;
|
|
|
|
}
|
|
|
|
i = 0;
|
|
|
|
while (!riscv_cpu_hviprio_index2irq(i, &irq, &rdzero)) {
|
|
|
|
if (!rdzero) {
|
|
|
|
env->hviprio[irq] = env->miprio[irq];
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
2021-10-25 19:36:04 +02:00
|
|
|
/* mmte is supposed to have pm.current hardwired to 1 */
|
2023-04-12 13:43:10 +02:00
|
|
|
env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT);
|
2023-10-19 08:56:44 +02:00
|
|
|
|
2024-01-08 01:13:28 +01:00
|
|
|
/*
|
|
|
|
* Bits 10, 6, 2 and 12 of mideleg are read only 1 when the Hypervisor
|
|
|
|
* extension is enabled.
|
|
|
|
*/
|
|
|
|
if (riscv_has_ext(env, RVH)) {
|
|
|
|
env->mideleg |= HS_MODE_INTERRUPTS;
|
|
|
|
}
|
|
|
|
|
2023-10-19 08:56:44 +02:00
|
|
|
/*
|
|
|
|
* Clear mseccfg and unlock all the PMP entries upon reset.
|
|
|
|
* This is allowed as per the priv and smepmp specifications
|
|
|
|
* and is needed to clear stale entries across reboots.
|
|
|
|
*/
|
|
|
|
if (riscv_cpu_cfg(env)->ext_smepmp) {
|
|
|
|
env->mseccfg = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
pmp_unlock_entries(env);
|
2018-03-02 13:31:10 +01:00
|
|
|
#endif
|
2022-01-20 13:20:32 +01:00
|
|
|
env->xl = riscv_cpu_mxl(env);
|
2022-01-20 13:20:38 +01:00
|
|
|
riscv_cpu_update_mask(env);
|
2021-04-01 17:17:29 +02:00
|
|
|
cs->exception_index = RISCV_EXCP_NONE;
|
2019-06-24 20:08:38 +02:00
|
|
|
env->load_res = -1;
|
2018-03-02 13:31:10 +01:00
|
|
|
set_default_nan_mode(1, &env->fp_status);
|
2022-01-12 09:13:22 +01:00
|
|
|
|
|
|
|
#ifndef CONFIG_USER_ONLY
|
2023-02-22 19:51:59 +01:00
|
|
|
if (cpu->cfg.debug) {
|
2023-08-18 05:40:58 +02:00
|
|
|
riscv_trigger_reset_hold(env);
|
2022-04-21 02:33:21 +02:00
|
|
|
}
|
|
|
|
|
2022-01-12 09:13:22 +01:00
|
|
|
if (kvm_enabled()) {
|
|
|
|
kvm_riscv_reset_vcpu(cpu);
|
|
|
|
}
|
|
|
|
#endif
|
2018-03-02 13:31:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
|
|
|
|
{
|
2020-12-16 19:22:56 +01:00
|
|
|
RISCVCPU *cpu = RISCV_CPU(s);
|
2023-06-12 13:10:27 +02:00
|
|
|
CPURISCVState *env = &cpu->env;
|
2023-05-23 11:35:34 +02:00
|
|
|
info->target_info = &cpu->cfg;
|
2021-10-20 05:16:58 +02:00
|
|
|
|
2023-06-12 13:10:27 +02:00
|
|
|
switch (env->xl) {
|
2021-10-20 05:16:58 +02:00
|
|
|
case MXL_RV32:
|
2020-12-16 19:22:56 +01:00
|
|
|
info->print_insn = print_insn_riscv32;
|
2021-10-20 05:16:58 +02:00
|
|
|
break;
|
|
|
|
case MXL_RV64:
|
2020-12-16 19:22:56 +01:00
|
|
|
info->print_insn = print_insn_riscv64;
|
2021-10-20 05:16:58 +02:00
|
|
|
break;
|
2022-01-06 22:00:57 +01:00
|
|
|
case MXL_RV128:
|
|
|
|
info->print_insn = print_insn_riscv128;
|
|
|
|
break;
|
2021-10-20 05:16:58 +02:00
|
|
|
default:
|
|
|
|
g_assert_not_reached();
|
2020-12-16 19:22:56 +01:00
|
|
|
}
|
2018-03-02 13:31:10 +01:00
|
|
|
}
|
|
|
|
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
|
|
|
|
{
|
2023-12-18 13:53:30 +01:00
|
|
|
bool rv32 = riscv_cpu_is_32bit(cpu);
|
target/riscv: fix satp_mode_finalize() when satp_mode.supported = 0
In the same emulated RISC-V host, the 'host' KVM CPU takes 4 times
longer to boot than the 'rv64' KVM CPU.
The reason is an unintended behavior of riscv_cpu_satp_mode_finalize()
when satp_mode.supported = 0, i.e. when cpu_init() does not set
satp_mode_max_supported(). satp_mode_max_from_map(map) does:
31 - __builtin_clz(map)
This means that, if satp_mode.supported = 0, satp_mode_supported_max
wil be '31 - 32'. But this is C, so satp_mode_supported_max will gladly
set it to UINT_MAX (4294967295). After that, if the user didn't set a
satp_mode, set_satp_mode_default_map(cpu) will make
cfg.satp_mode.map = cfg.satp_mode.supported
So satp_mode.map = 0. And then satp_mode_map_max will be set to
satp_mode_max_from_map(cpu->cfg.satp_mode.map), i.e. also UINT_MAX. The
guard "satp_mode_map_max > satp_mode_supported_max" doesn't protect us
here since both are UINT_MAX.
And finally we have 2 loops:
for (int i = satp_mode_map_max - 1; i >= 0; --i) {
Which are, in fact, 2 loops from UINT_MAX -1 to -1. This is where the
extra delay when booting the 'host' CPU is coming from.
Commit 43d1de32f8 already set a precedence for satp_mode.supported = 0
in a different manner. We're doing the same here. If supported == 0,
interpret as 'the CPU wants the OS to handle satp mode alone' and skip
satp_mode_finalize().
We'll also put a guard in satp_mode_max_from_map() to assert out if map
is 0 since the function is not ready to deal with it.
Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
Fixes: 6f23aaeb9b ("riscv: Allow user to set the satp mode")
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Message-ID: <20230817152903.694926-1-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-08-17 17:29:03 +02:00
|
|
|
uint8_t satp_mode_map_max, satp_mode_supported_max;
|
|
|
|
|
|
|
|
/* The CPU wants the OS to decide which satp mode to use */
|
|
|
|
if (cpu->cfg.satp_mode.supported == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
satp_mode_supported_max =
|
|
|
|
satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
|
|
|
|
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) {
|
2023-03-03 14:12:51 +01:00
|
|
|
if ((cpu->cfg.satp_mode.init & (1 << i)) &&
|
|
|
|
(cpu->cfg.satp_mode.supported & (1 << i))) {
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
for (int j = i - 1; j >= 0; --j) {
|
2023-03-03 14:12:51 +01:00
|
|
|
if (cpu->cfg.satp_mode.supported & (1 << j)) {
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
cpu->cfg.satp_mode.map |= (1 << j);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-03 14:12:51 +01:00
|
|
|
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;
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure the user did not ask for an invalid configuration as per
|
|
|
|
* the specification.
|
|
|
|
*/
|
|
|
|
if (!rv32) {
|
2023-03-03 14:12:51 +01:00
|
|
|
for (int i = satp_mode_map_max - 1; i >= 0; --i) {
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
if (!(cpu->cfg.satp_mode.map & (1 << i)) &&
|
|
|
|
(cpu->cfg.satp_mode.init & (1 << i)) &&
|
2023-03-03 14:12:51 +01:00
|
|
|
(cpu->cfg.satp_mode.supported & (1 << i))) {
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
error_setg(errp, "cannot disable %s satp mode if %s "
|
|
|
|
"is enabled", satp_mode_str(i, false),
|
2023-03-03 14:12:51 +01:00
|
|
|
satp_mode_str(satp_mode_map_max, false));
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Finally expand the map so that all valid modes are set */
|
2023-03-03 14:12:51 +01:00
|
|
|
for (int i = satp_mode_map_max - 1; i >= 0; --i) {
|
|
|
|
if (cpu->cfg.satp_mode.supported & (1 << i)) {
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
cpu->cfg.satp_mode.map |= (1 << i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2023-10-18 21:56:35 +02:00
|
|
|
void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
{
|
|
|
|
Error *local_err = NULL;
|
|
|
|
|
2023-12-18 13:53:29 +01:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
riscv_cpu_satp_mode_finalize(cpu, &local_err);
|
|
|
|
if (local_err != NULL) {
|
|
|
|
error_propagate(errp, local_err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2023-10-18 21:56:35 +02:00
|
|
|
if (tcg_enabled()) {
|
|
|
|
riscv_tcg_cpu_finalize_features(cpu, &local_err);
|
|
|
|
if (local_err != NULL) {
|
|
|
|
error_propagate(errp, local_err);
|
|
|
|
return;
|
|
|
|
}
|
2024-01-12 15:01:54 +01:00
|
|
|
} else if (kvm_enabled()) {
|
|
|
|
riscv_kvm_cpu_finalize_features(cpu, &local_err);
|
|
|
|
if (local_err != NULL) {
|
|
|
|
error_propagate(errp, local_err);
|
|
|
|
return;
|
|
|
|
}
|
2023-10-18 21:56:35 +02:00
|
|
|
}
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
}
|
|
|
|
|
2023-07-06 12:17:19 +02:00
|
|
|
static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
|
|
|
{
|
|
|
|
CPUState *cs = CPU(dev);
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(dev);
|
|
|
|
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
|
|
|
|
Error *local_err = NULL;
|
|
|
|
|
2023-09-12 15:24:15 +02:00
|
|
|
if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_CPU_ANY) != NULL) {
|
|
|
|
warn_report("The 'any' CPU is deprecated and will be "
|
|
|
|
"removed in the future.");
|
|
|
|
}
|
|
|
|
|
2023-07-06 12:17:19 +02:00
|
|
|
cpu_exec_realizefn(cs, &local_err);
|
|
|
|
if (local_err != NULL) {
|
|
|
|
error_propagate(errp, local_err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
riscv_cpu_finalize_features(cpu, &local_err);
|
|
|
|
if (local_err != NULL) {
|
|
|
|
error_propagate(errp, local_err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-03-15 11:26:59 +01:00
|
|
|
riscv_cpu_register_gdb_regs_for_features(cs);
|
|
|
|
|
2023-08-18 05:40:58 +02:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
if (cpu->cfg.debug) {
|
|
|
|
riscv_trigger_realize(&cpu->env);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2018-03-02 13:31:10 +01:00
|
|
|
qemu_init_vcpu(cs);
|
|
|
|
cpu_reset(cs);
|
|
|
|
|
|
|
|
mcc->parent_realize(dev, errp);
|
|
|
|
}
|
|
|
|
|
2023-10-18 21:56:37 +02:00
|
|
|
bool riscv_cpu_accelerator_compatible(RISCVCPU *cpu)
|
|
|
|
{
|
|
|
|
if (tcg_enabled()) {
|
|
|
|
return riscv_cpu_tcg_compatible(cpu);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-08-30 07:34:20 +02:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-09-25 19:56:59 +02:00
|
|
|
void riscv_add_satp_mode_properties(Object *obj)
|
riscv: Allow user to set the satp mode
RISC-V specifies multiple sizes for addressable memory and Linux probes for
the machine's support at startup via the satp CSR register (done in
csr.c:validate_vm).
As per the specification, sv64 must support sv57, which in turn must
support sv48...etc. So we can restrict machine support by simply setting the
"highest" supported mode and the bare mode is always supported.
You can set the satp mode using the new properties "sv32", "sv39", "sv48",
"sv57" and "sv64" as follows:
-cpu rv64,sv57=on # Linux will boot using sv57 scheme
-cpu rv64,sv39=on # Linux will boot using sv39 scheme
-cpu rv64,sv57=off # Linux will boot using sv48 scheme
-cpu rv64 # Linux will boot using sv57 scheme by default
We take the highest level set by the user:
-cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
We make sure that invalid configurations are rejected:
-cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
# enabled
We accept "redundant" configurations:
-cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
And contradictory configurations:
-cpu rv64,sv48=on,sv48=off # Linux will boot using sv39 scheme
Co-Developed-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Ludovic Henry <ludovic@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-ID: <20230303131252.892893-4-alexghiti@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-03-03 14:12:50 +01:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-30 07:34:20 +02:00
|
|
|
static void riscv_cpu_set_irq(void *opaque, int irq, int level)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(opaque);
|
2022-02-04 18:46:39 +01:00
|
|
|
CPURISCVState *env = &cpu->env;
|
2021-08-30 07:34:20 +02:00
|
|
|
|
2022-02-04 18:46:39 +01:00
|
|
|
if (irq < IRQ_LOCAL_MAX) {
|
|
|
|
switch (irq) {
|
|
|
|
case IRQ_U_SOFT:
|
|
|
|
case IRQ_S_SOFT:
|
|
|
|
case IRQ_VS_SOFT:
|
|
|
|
case IRQ_M_SOFT:
|
|
|
|
case IRQ_U_TIMER:
|
|
|
|
case IRQ_S_TIMER:
|
|
|
|
case IRQ_VS_TIMER:
|
|
|
|
case IRQ_M_TIMER:
|
|
|
|
case IRQ_U_EXT:
|
|
|
|
case IRQ_VS_EXT:
|
|
|
|
case IRQ_M_EXT:
|
2022-03-17 07:18:16 +01:00
|
|
|
if (kvm_enabled()) {
|
2022-02-04 18:46:39 +01:00
|
|
|
kvm_riscv_set_irq(cpu, irq, level);
|
2022-03-17 07:18:16 +01:00
|
|
|
} else {
|
2023-03-09 08:13:28 +01:00
|
|
|
riscv_cpu_update_mip(env, 1 << irq, BOOL_TO_MASK(level));
|
2022-03-17 07:18:16 +01:00
|
|
|
}
|
2022-02-04 18:46:39 +01:00
|
|
|
break;
|
2022-03-17 07:18:17 +01:00
|
|
|
case IRQ_S_EXT:
|
|
|
|
if (kvm_enabled()) {
|
|
|
|
kvm_riscv_set_irq(cpu, irq, level);
|
|
|
|
} else {
|
|
|
|
env->external_seip = level;
|
2023-03-09 08:13:28 +01:00
|
|
|
riscv_cpu_update_mip(env, 1 << irq,
|
2022-03-17 07:18:17 +01:00
|
|
|
BOOL_TO_MASK(level | env->software_seip));
|
|
|
|
}
|
|
|
|
break;
|
2022-02-04 18:46:39 +01:00
|
|
|
default:
|
|
|
|
g_assert_not_reached();
|
2022-01-12 09:13:23 +01:00
|
|
|
}
|
2022-02-04 18:46:39 +01:00
|
|
|
} else if (irq < (IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX)) {
|
|
|
|
/* Require H-extension for handling guest local interrupts */
|
|
|
|
if (!riscv_has_ext(env, RVH)) {
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compute bit position in HGEIP CSR */
|
|
|
|
irq = irq - IRQ_LOCAL_MAX + 1;
|
|
|
|
if (env->geilen < irq) {
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update HGEIP CSR */
|
|
|
|
env->hgeip &= ~((target_ulong)1 << irq);
|
|
|
|
if (level) {
|
|
|
|
env->hgeip |= (target_ulong)1 << irq;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update mip.SGEIP bit */
|
2023-03-09 08:13:28 +01:00
|
|
|
riscv_cpu_update_mip(env, MIP_SGEIP,
|
2022-02-04 18:46:39 +01:00
|
|
|
BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
|
|
|
|
} else {
|
2021-08-30 07:34:20 +02:00
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_USER_ONLY */
|
|
|
|
|
2023-09-25 19:56:55 +02:00
|
|
|
static bool riscv_cpu_is_dynamic(Object *cpu_obj)
|
|
|
|
{
|
|
|
|
return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void riscv_cpu_post_init(Object *obj)
|
|
|
|
{
|
2023-09-25 19:57:01 +02:00
|
|
|
accel_cpu_instance_init(CPU(obj));
|
2023-09-25 19:56:55 +02:00
|
|
|
}
|
|
|
|
|
2018-03-02 13:31:10 +01:00
|
|
|
static void riscv_cpu_init(Object *obj)
|
|
|
|
{
|
2024-01-06 00:05:32 +01:00
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
|
2021-08-30 07:34:20 +02:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
2023-09-14 02:36:27 +02:00
|
|
|
qdev_init_gpio_in(DEVICE(obj), riscv_cpu_set_irq,
|
2022-02-04 18:46:39 +01:00
|
|
|
IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
|
2021-08-30 07:34:20 +02:00
|
|
|
#endif /* CONFIG_USER_ONLY */
|
target/riscv: add zicntr extension flag for TCG
zicntr is the Base Counters and Timers extension described in chapter 12
of the unprivileged spec. It describes support for RDCYCLE, RDTIME and
RDINSTRET.
QEMU already implements it in TCG way before it was a discrete
extension. zicntr is part of the RVA22 profile, so let's add it to QEMU
to make the future profile implementation flag complete. Given than it
represents an already existing feature, default it to 'true' for all
CPUs.
For TCG, we need a way to disable zicntr if the user wants to. This is
done by restricting access to the CYCLE, TIME, and INSTRET counters via
the 'ctr()' predicate when we're about to access them.
Disabling zicntr happens via the command line or if its dependency,
zicsr, happens to be disabled. We'll check for zicsr during realize()
and, in case it's absent, disable zicntr. However, if the user was
explicit about having zicntr support, error out instead of disabling it.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20231023153927.435083-2-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-10-23 17:39:24 +02:00
|
|
|
|
2024-01-06 00:05:32 +01:00
|
|
|
general_user_opts = g_hash_table_new(g_str_hash, g_str_equal);
|
|
|
|
|
target/riscv: add zicntr extension flag for TCG
zicntr is the Base Counters and Timers extension described in chapter 12
of the unprivileged spec. It describes support for RDCYCLE, RDTIME and
RDINSTRET.
QEMU already implements it in TCG way before it was a discrete
extension. zicntr is part of the RVA22 profile, so let's add it to QEMU
to make the future profile implementation flag complete. Given than it
represents an already existing feature, default it to 'true' for all
CPUs.
For TCG, we need a way to disable zicntr if the user wants to. This is
done by restricting access to the CYCLE, TIME, and INSTRET counters via
the 'ctr()' predicate when we're about to access them.
Disabling zicntr happens via the command line or if its dependency,
zicsr, happens to be disabled. We'll check for zicsr during realize()
and, in case it's absent, disable zicntr. However, if the user was
explicit about having zicntr support, error out instead of disabling it.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20231023153927.435083-2-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-10-23 17:39:24 +02:00
|
|
|
/*
|
|
|
|
* The timer and performance counters extensions were supported
|
|
|
|
* in QEMU before they were added as discrete extensions in the
|
|
|
|
* ISA. To keep compatibility we'll always default them to 'true'
|
|
|
|
* for all CPUs. Each accelerator will decide what to do when
|
|
|
|
* users disable them.
|
|
|
|
*/
|
|
|
|
RISCV_CPU(obj)->cfg.ext_zicntr = true;
|
2023-10-23 17:39:26 +02:00
|
|
|
RISCV_CPU(obj)->cfg.ext_zihpm = true;
|
2024-01-06 00:05:32 +01:00
|
|
|
|
|
|
|
/* Default values for non-bool cpu properties */
|
|
|
|
cpu->cfg.pmu_mask = MAKE_64BIT_MASK(3, 16);
|
2024-01-06 00:05:37 +01:00
|
|
|
cpu->cfg.vlen = 128;
|
2024-01-22 17:10:55 +01:00
|
|
|
cpu->cfg.vlenb = 128 >> 3;
|
2024-01-06 00:05:38 +01:00
|
|
|
cpu->cfg.elen = 64;
|
2024-01-12 15:01:55 +01:00
|
|
|
cpu->cfg.cbom_blocksize = 64;
|
2024-01-12 15:01:56 +01:00
|
|
|
cpu->cfg.cbop_blocksize = 64;
|
2024-01-12 15:01:57 +01:00
|
|
|
cpu->cfg.cboz_blocksize = 64;
|
2024-01-06 00:05:36 +01:00
|
|
|
cpu->env.vext_ver = VEXT_VERSION_1_00_0;
|
2018-03-02 13:31:10 +01:00
|
|
|
}
|
|
|
|
|
2023-07-06 12:17:29 +02:00
|
|
|
typedef struct misa_ext_info {
|
|
|
|
const char *name;
|
|
|
|
const char *description;
|
|
|
|
} MISAExtInfo;
|
|
|
|
|
|
|
|
#define MISA_INFO_IDX(_bit) \
|
|
|
|
__builtin_ctz(_bit)
|
|
|
|
|
|
|
|
#define MISA_EXT_INFO(_bit, _propname, _descr) \
|
|
|
|
[MISA_INFO_IDX(_bit)] = {.name = _propname, .description = _descr}
|
|
|
|
|
|
|
|
static const MISAExtInfo misa_ext_info_arr[] = {
|
|
|
|
MISA_EXT_INFO(RVA, "a", "Atomic instructions"),
|
|
|
|
MISA_EXT_INFO(RVC, "c", "Compressed instructions"),
|
|
|
|
MISA_EXT_INFO(RVD, "d", "Double-precision float point"),
|
|
|
|
MISA_EXT_INFO(RVF, "f", "Single-precision float point"),
|
|
|
|
MISA_EXT_INFO(RVI, "i", "Base integer instruction set"),
|
|
|
|
MISA_EXT_INFO(RVE, "e", "Base integer instruction set (embedded)"),
|
|
|
|
MISA_EXT_INFO(RVM, "m", "Integer multiplication and division"),
|
|
|
|
MISA_EXT_INFO(RVS, "s", "Supervisor-level instructions"),
|
|
|
|
MISA_EXT_INFO(RVU, "u", "User-level instructions"),
|
|
|
|
MISA_EXT_INFO(RVH, "h", "Hypervisor"),
|
|
|
|
MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
|
|
|
|
MISA_EXT_INFO(RVV, "v", "Vector operations"),
|
|
|
|
MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
|
2024-01-11 17:16:43 +01:00
|
|
|
MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)")
|
2023-07-06 12:17:29 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static int riscv_validate_misa_info_idx(uint32_t bit)
|
|
|
|
{
|
|
|
|
int idx;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Our lowest valid input (RVA) is 1 and
|
|
|
|
* __builtin_ctz() is UB with zero.
|
|
|
|
*/
|
|
|
|
g_assert(bit != 0);
|
|
|
|
idx = MISA_INFO_IDX(bit);
|
|
|
|
|
|
|
|
g_assert(idx < ARRAY_SIZE(misa_ext_info_arr));
|
|
|
|
return idx;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *riscv_get_misa_ext_name(uint32_t bit)
|
|
|
|
{
|
|
|
|
int idx = riscv_validate_misa_info_idx(bit);
|
|
|
|
const char *val = misa_ext_info_arr[idx].name;
|
|
|
|
|
|
|
|
g_assert(val != NULL);
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *riscv_get_misa_ext_description(uint32_t bit)
|
|
|
|
{
|
|
|
|
int idx = riscv_validate_misa_info_idx(bit);
|
|
|
|
const char *val = misa_ext_info_arr[idx].description;
|
|
|
|
|
|
|
|
g_assert(val != NULL);
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2023-09-12 15:24:20 +02:00
|
|
|
#define MULTI_EXT_CFG_BOOL(_name, _prop, _defval) \
|
|
|
|
{.name = _name, .offset = CPU_CFG_OFFSET(_prop), \
|
|
|
|
.enabled = _defval}
|
|
|
|
|
2023-09-25 19:56:58 +02:00
|
|
|
const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
|
2021-10-18 06:32:15 +02:00
|
|
|
/* Defaults for standard extensions */
|
2023-09-12 15:24:20 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
|
2023-10-12 18:46:01 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("zifencei", ext_zifencei, true),
|
2023-10-12 18:46:02 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("zicsr", ext_zicsr, true),
|
target/riscv: deprecate capital 'Z' CPU properties
At this moment there are eleven CPU extension properties that starts
with capital 'Z': Zifencei, Zicsr, Zihintntl, Zihintpause, Zawrs, Zfa,
Zfh, Zfhmin, Zve32f, Zve64f and Zve64d. All other extensions are named
with lower-case letters.
We want all properties to be named with lower-case letters since it's
consistent with the riscv-isa string that we create in the FDT. Having
these 11 properties to be exceptions can be confusing.
Deprecate all of them. Create their lower-case counterpart to be used as
maintained CPU properties. When trying to use any deprecated property a
warning message will be displayed, recommending users to switch to the
lower-case variant:
./build/qemu-system-riscv64 -M virt -cpu rv64,Zifencei=true --nographic
qemu-system-riscv64: warning: CPU property 'Zifencei' is deprecated. Please use 'zifencei' instead
This will give users some time to change their scripts before we remove
the capital 'Z' properties entirely.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Message-ID: <20231009112817.8896-2-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-10-09 13:28:17 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true),
|
|
|
|
MULTI_EXT_CFG_BOOL("zihintpause", ext_zihintpause, true),
|
2023-12-07 16:32:30 +01:00
|
|
|
MULTI_EXT_CFG_BOOL("zacas", ext_zacas, false),
|
target/riscv: deprecate capital 'Z' CPU properties
At this moment there are eleven CPU extension properties that starts
with capital 'Z': Zifencei, Zicsr, Zihintntl, Zihintpause, Zawrs, Zfa,
Zfh, Zfhmin, Zve32f, Zve64f and Zve64d. All other extensions are named
with lower-case letters.
We want all properties to be named with lower-case letters since it's
consistent with the riscv-isa string that we create in the FDT. Having
these 11 properties to be exceptions can be confusing.
Deprecate all of them. Create their lower-case counterpart to be used as
maintained CPU properties. When trying to use any deprecated property a
warning message will be displayed, recommending users to switch to the
lower-case variant:
./build/qemu-system-riscv64 -M virt -cpu rv64,Zifencei=true --nographic
qemu-system-riscv64: warning: CPU property 'Zifencei' is deprecated. Please use 'zifencei' instead
This will give users some time to change their scripts before we remove
the capital 'Z' properties entirely.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Message-ID: <20231009112817.8896-2-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-10-09 13:28:17 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("zawrs", ext_zawrs, true),
|
|
|
|
MULTI_EXT_CFG_BOOL("zfa", ext_zfa, true),
|
|
|
|
MULTI_EXT_CFG_BOOL("zfh", ext_zfh, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zfhmin", ext_zfhmin, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zve32f", ext_zve32f, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
|
2023-09-12 15:24:20 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("sstc", ext_sstc, true),
|
|
|
|
|
2023-10-19 08:55:46 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("smepmp", ext_smepmp, false),
|
2023-09-12 15:24:20 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("smstateen", ext_smstateen, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("svadu", ext_svadu, true),
|
|
|
|
MULTI_EXT_CFG_BOOL("svinval", ext_svinval, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("svnapot", ext_svnapot, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("svpbmt", ext_svpbmt, false),
|
|
|
|
|
target/riscv: add zicntr extension flag for TCG
zicntr is the Base Counters and Timers extension described in chapter 12
of the unprivileged spec. It describes support for RDCYCLE, RDTIME and
RDINSTRET.
QEMU already implements it in TCG way before it was a discrete
extension. zicntr is part of the RVA22 profile, so let's add it to QEMU
to make the future profile implementation flag complete. Given than it
represents an already existing feature, default it to 'true' for all
CPUs.
For TCG, we need a way to disable zicntr if the user wants to. This is
done by restricting access to the CYCLE, TIME, and INSTRET counters via
the 'ctr()' predicate when we're about to access them.
Disabling zicntr happens via the command line or if its dependency,
zicsr, happens to be disabled. We'll check for zicsr during realize()
and, in case it's absent, disable zicntr. However, if the user was
explicit about having zicntr support, error out instead of disabling it.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20231023153927.435083-2-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-10-23 17:39:24 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("zicntr", ext_zicntr, true),
|
2023-10-23 17:39:26 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("zihpm", ext_zihpm, true),
|
target/riscv: add zicntr extension flag for TCG
zicntr is the Base Counters and Timers extension described in chapter 12
of the unprivileged spec. It describes support for RDCYCLE, RDTIME and
RDINSTRET.
QEMU already implements it in TCG way before it was a discrete
extension. zicntr is part of the RVA22 profile, so let's add it to QEMU
to make the future profile implementation flag complete. Given than it
represents an already existing feature, default it to 'true' for all
CPUs.
For TCG, we need a way to disable zicntr if the user wants to. This is
done by restricting access to the CYCLE, TIME, and INSTRET counters via
the 'ctr()' predicate when we're about to access them.
Disabling zicntr happens via the command line or if its dependency,
zicsr, happens to be disabled. We'll check for zicsr during realize()
and, in case it's absent, disable zicntr. However, if the user was
explicit about having zicntr support, error out instead of disabling it.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20231023153927.435083-2-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-10-23 17:39:24 +02:00
|
|
|
|
2023-09-12 15:24:20 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("zba", ext_zba, true),
|
|
|
|
MULTI_EXT_CFG_BOOL("zbb", ext_zbb, true),
|
|
|
|
MULTI_EXT_CFG_BOOL("zbc", ext_zbc, true),
|
|
|
|
MULTI_EXT_CFG_BOOL("zbkb", ext_zbkb, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zbkc", ext_zbkc, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zbkx", ext_zbkx, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zbs", ext_zbs, true),
|
|
|
|
MULTI_EXT_CFG_BOOL("zk", ext_zk, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zkn", ext_zkn, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zknd", ext_zknd, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zkne", ext_zkne, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zknh", ext_zknh, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zkr", ext_zkr, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zks", ext_zks, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zksed", ext_zksed, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zksh", ext_zksh, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zkt", ext_zkt, false),
|
|
|
|
|
|
|
|
MULTI_EXT_CFG_BOOL("zdinx", ext_zdinx, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zfinx", ext_zfinx, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zhinx", ext_zhinx, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zhinxmin", ext_zhinxmin, false),
|
|
|
|
|
2023-10-12 18:46:03 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("zicbom", ext_zicbom, true),
|
2023-12-18 13:53:13 +01:00
|
|
|
MULTI_EXT_CFG_BOOL("zicbop", ext_zicbop, true),
|
2023-10-12 18:46:04 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("zicboz", ext_zicboz, true),
|
2023-09-12 15:24:20 +02:00
|
|
|
|
|
|
|
MULTI_EXT_CFG_BOOL("zmmul", ext_zmmul, false),
|
|
|
|
|
|
|
|
MULTI_EXT_CFG_BOOL("zca", ext_zca, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zcb", ext_zcb, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zcd", ext_zcd, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zce", ext_zce, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zcf", ext_zcf, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zcmp", ext_zcmp, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zcmt", ext_zcmt, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zicond", ext_zicond, false),
|
2023-05-10 05:00:40 +02:00
|
|
|
|
2023-10-26 17:18:17 +02:00
|
|
|
/* Vector cryptography extensions */
|
|
|
|
MULTI_EXT_CFG_BOOL("zvbb", ext_zvbb, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zvbc", ext_zvbc, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zvkb", ext_zvkg, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zvkg", ext_zvkg, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zvkned", ext_zvkned, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zvknha", ext_zvknha, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zvknhb", ext_zvknhb, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zvksed", ext_zvksed, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zvksh", ext_zvksh, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zvkt", ext_zvkt, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zvkn", ext_zvkn, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zvknc", ext_zvknc, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zvkng", ext_zvkng, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zvks", ext_zvks, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zvksc", ext_zvksc, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("zvksg", ext_zvksg, false),
|
|
|
|
|
2023-09-12 15:24:09 +02:00
|
|
|
DEFINE_PROP_END_OF_LIST(),
|
|
|
|
};
|
|
|
|
|
2023-09-25 19:56:58 +02:00
|
|
|
const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
|
2023-09-12 15:24:20 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("xtheadba", ext_xtheadba, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("xtheadbb", ext_xtheadbb, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("xtheadbs", ext_xtheadbs, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("xtheadcmo", ext_xtheadcmo, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("xtheadcondmov", ext_xtheadcondmov, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("xtheadfmemidx", ext_xtheadfmemidx, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("xtheadfmv", ext_xtheadfmv, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("xtheadmac", ext_xtheadmac, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("xtheadmemidx", ext_xtheadmemidx, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("xtheadmempair", ext_xtheadmempair, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("xtheadsync", ext_xtheadsync, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("xventanacondops", ext_XVentanaCondOps, false),
|
2022-02-02 01:52:48 +01:00
|
|
|
|
2023-09-12 15:24:08 +02:00
|
|
|
DEFINE_PROP_END_OF_LIST(),
|
|
|
|
};
|
2023-03-07 09:14:01 +01:00
|
|
|
|
2023-09-12 15:24:08 +02:00
|
|
|
/* These are experimental so mark with 'x-' */
|
2023-09-25 19:56:58 +02:00
|
|
|
const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
|
2023-09-12 15:24:20 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("x-smaia", ext_smaia, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("x-ssaia", ext_ssaia, false),
|
2021-04-19 08:17:25 +02:00
|
|
|
|
2023-09-12 15:24:20 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("x-zvfh", ext_zvfh, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("x-zvfhmin", ext_zvfhmin, false),
|
2023-02-15 03:05:39 +01:00
|
|
|
|
2023-09-12 15:24:20 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("x-zfbfmin", ext_zfbfmin, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("x-zvfbfmin", ext_zvfbfmin, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("x-zvfbfwma", ext_zvfbfwma, false),
|
2023-06-15 08:33:01 +02:00
|
|
|
|
2022-06-08 08:14:37 +02:00
|
|
|
DEFINE_PROP_END_OF_LIST(),
|
|
|
|
};
|
|
|
|
|
2023-12-18 13:53:14 +01:00
|
|
|
const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = {
|
target/riscv: implement svade
'svade' is a RVA22S64 profile requirement, a profile we're going to add
shortly. It is a named feature (i.e. not a formal extension, not defined
in riscv,isa DT at this moment) defined in [1] as:
"Page-fault exceptions are raised when a page is accessed when A bit is
clear, or written when D bit is clear.".
As far as the spec goes, 'svade' is one of the two distinct modes of
handling PTE_A and PTE_D. The other way, i.e. update PTE_A/PTE_D when
they're cleared, is defined by the 'svadu' extension. Checking
cpu_helper.c, get_physical_address(), we can verify that QEMU is
compliant with that: we will update PTE_A/PTE_D if 'svadu' is enabled,
or throw a page-fault exception if 'svadu' isn't enabled.
So, as far as we're concerned, 'svade' translates to 'svadu must be
disabled'.
We'll implement it like 'zic64b': an internal flag that profiles can
enable. The flag will not be exposed to users.
[1] https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20231218125334.37184-20-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-12-18 13:53:27 +01:00
|
|
|
MULTI_EXT_CFG_BOOL("svade", svade, true),
|
2023-12-18 13:53:14 +01:00
|
|
|
MULTI_EXT_CFG_BOOL("zic64b", zic64b, true),
|
|
|
|
|
|
|
|
DEFINE_PROP_END_OF_LIST(),
|
|
|
|
};
|
|
|
|
|
target/riscv: deprecate capital 'Z' CPU properties
At this moment there are eleven CPU extension properties that starts
with capital 'Z': Zifencei, Zicsr, Zihintntl, Zihintpause, Zawrs, Zfa,
Zfh, Zfhmin, Zve32f, Zve64f and Zve64d. All other extensions are named
with lower-case letters.
We want all properties to be named with lower-case letters since it's
consistent with the riscv-isa string that we create in the FDT. Having
these 11 properties to be exceptions can be confusing.
Deprecate all of them. Create their lower-case counterpart to be used as
maintained CPU properties. When trying to use any deprecated property a
warning message will be displayed, recommending users to switch to the
lower-case variant:
./build/qemu-system-riscv64 -M virt -cpu rv64,Zifencei=true --nographic
qemu-system-riscv64: warning: CPU property 'Zifencei' is deprecated. Please use 'zifencei' instead
This will give users some time to change their scripts before we remove
the capital 'Z' properties entirely.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Message-ID: <20231009112817.8896-2-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-10-09 13:28:17 +02:00
|
|
|
/* Deprecated entries marked for future removal */
|
|
|
|
const RISCVCPUMultiExtConfig riscv_cpu_deprecated_exts[] = {
|
2023-10-12 18:46:01 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("Zifencei", ext_zifencei, true),
|
2023-10-12 18:46:02 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("Zicsr", ext_zicsr, true),
|
target/riscv: deprecate capital 'Z' CPU properties
At this moment there are eleven CPU extension properties that starts
with capital 'Z': Zifencei, Zicsr, Zihintntl, Zihintpause, Zawrs, Zfa,
Zfh, Zfhmin, Zve32f, Zve64f and Zve64d. All other extensions are named
with lower-case letters.
We want all properties to be named with lower-case letters since it's
consistent with the riscv-isa string that we create in the FDT. Having
these 11 properties to be exceptions can be confusing.
Deprecate all of them. Create their lower-case counterpart to be used as
maintained CPU properties. When trying to use any deprecated property a
warning message will be displayed, recommending users to switch to the
lower-case variant:
./build/qemu-system-riscv64 -M virt -cpu rv64,Zifencei=true --nographic
qemu-system-riscv64: warning: CPU property 'Zifencei' is deprecated. Please use 'zifencei' instead
This will give users some time to change their scripts before we remove
the capital 'Z' properties entirely.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Message-ID: <20231009112817.8896-2-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-10-09 13:28:17 +02:00
|
|
|
MULTI_EXT_CFG_BOOL("Zihintntl", ext_zihintntl, true),
|
|
|
|
MULTI_EXT_CFG_BOOL("Zihintpause", ext_zihintpause, true),
|
|
|
|
MULTI_EXT_CFG_BOOL("Zawrs", ext_zawrs, true),
|
|
|
|
MULTI_EXT_CFG_BOOL("Zfa", ext_zfa, true),
|
|
|
|
MULTI_EXT_CFG_BOOL("Zfh", ext_zfh, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("Zfhmin", ext_zfhmin, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("Zve32f", ext_zve32f, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("Zve64f", ext_zve64f, false),
|
|
|
|
MULTI_EXT_CFG_BOOL("Zve64d", ext_zve64d, false),
|
|
|
|
|
|
|
|
DEFINE_PROP_END_OF_LIST(),
|
|
|
|
};
|
|
|
|
|
2024-01-06 00:05:32 +01:00
|
|
|
static void cpu_set_prop_err(RISCVCPU *cpu, const char *propname,
|
|
|
|
Error **errp)
|
|
|
|
{
|
|
|
|
g_autofree char *cpuname = riscv_cpu_get_name(cpu);
|
|
|
|
error_setg(errp, "CPU '%s' does not allow changing the value of '%s'",
|
|
|
|
cpuname, propname);
|
|
|
|
}
|
|
|
|
|
2023-10-31 16:37:16 +01:00
|
|
|
static void prop_pmu_num_set(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
2024-01-06 00:05:32 +01:00
|
|
|
uint8_t pmu_num, curr_pmu_num;
|
|
|
|
uint32_t pmu_mask;
|
2023-10-31 16:37:16 +01:00
|
|
|
|
|
|
|
visit_type_uint8(v, name, &pmu_num, errp);
|
|
|
|
|
2024-01-06 00:05:32 +01:00
|
|
|
curr_pmu_num = ctpop32(cpu->cfg.pmu_mask);
|
|
|
|
|
|
|
|
if (pmu_num != curr_pmu_num && riscv_cpu_is_vendor(obj)) {
|
|
|
|
cpu_set_prop_err(cpu, name, errp);
|
|
|
|
error_append_hint(errp, "Current '%s' val: %u\n",
|
|
|
|
name, curr_pmu_num);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-10-31 16:37:16 +01:00
|
|
|
if (pmu_num > (RV_MAX_MHPMCOUNTERS - 3)) {
|
|
|
|
error_setg(errp, "Number of counters exceeds maximum available");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pmu_num == 0) {
|
2024-01-06 00:05:32 +01:00
|
|
|
pmu_mask = 0;
|
2023-10-31 16:37:16 +01:00
|
|
|
} else {
|
2024-01-06 00:05:32 +01:00
|
|
|
pmu_mask = MAKE_64BIT_MASK(3, pmu_num);
|
2023-10-31 16:37:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
warn_report("\"pmu-num\" property is deprecated; use \"pmu-mask\"");
|
2024-01-06 00:05:32 +01:00
|
|
|
cpu->cfg.pmu_mask = pmu_mask;
|
|
|
|
cpu_option_add_user_setting("pmu-mask", pmu_mask);
|
2023-10-31 16:37:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void prop_pmu_num_get(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
uint8_t pmu_num = ctpop32(cpu->cfg.pmu_mask);
|
|
|
|
|
|
|
|
visit_type_uint8(v, name, &pmu_num, errp);
|
|
|
|
}
|
|
|
|
|
2024-01-06 00:05:32 +01:00
|
|
|
static const PropertyInfo prop_pmu_num = {
|
2023-10-31 16:37:16 +01:00
|
|
|
.name = "pmu-num",
|
|
|
|
.get = prop_pmu_num_get,
|
|
|
|
.set = prop_pmu_num_set,
|
|
|
|
};
|
|
|
|
|
2024-01-06 00:05:32 +01:00
|
|
|
static void prop_pmu_mask_set(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
uint32_t value;
|
|
|
|
uint8_t pmu_num;
|
2023-09-12 15:24:04 +02:00
|
|
|
|
2024-01-06 00:05:32 +01:00
|
|
|
visit_type_uint32(v, name, &value, errp);
|
|
|
|
|
|
|
|
if (value != cpu->cfg.pmu_mask && riscv_cpu_is_vendor(obj)) {
|
|
|
|
cpu_set_prop_err(cpu, name, errp);
|
|
|
|
error_append_hint(errp, "Current '%s' val: %x\n",
|
|
|
|
name, cpu->cfg.pmu_mask);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pmu_num = ctpop32(value);
|
|
|
|
|
|
|
|
if (pmu_num > (RV_MAX_MHPMCOUNTERS - 3)) {
|
|
|
|
error_setg(errp, "Number of counters exceeds maximum available");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu_option_add_user_setting(name, value);
|
|
|
|
cpu->cfg.pmu_mask = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void prop_pmu_mask_get(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
uint8_t pmu_mask = RISCV_CPU(obj)->cfg.pmu_mask;
|
|
|
|
|
|
|
|
visit_type_uint8(v, name, &pmu_mask, errp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const PropertyInfo prop_pmu_mask = {
|
|
|
|
.name = "pmu-mask",
|
|
|
|
.get = prop_pmu_mask_get,
|
|
|
|
.set = prop_pmu_mask_set,
|
|
|
|
};
|
|
|
|
|
2024-01-06 00:05:33 +01:00
|
|
|
static void prop_mmu_set(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
bool value;
|
|
|
|
|
|
|
|
visit_type_bool(v, name, &value, errp);
|
|
|
|
|
|
|
|
if (cpu->cfg.mmu != value && riscv_cpu_is_vendor(obj)) {
|
|
|
|
cpu_set_prop_err(cpu, "mmu", errp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu_option_add_user_setting(name, value);
|
|
|
|
cpu->cfg.mmu = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void prop_mmu_get(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
bool value = RISCV_CPU(obj)->cfg.mmu;
|
|
|
|
|
|
|
|
visit_type_bool(v, name, &value, errp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const PropertyInfo prop_mmu = {
|
|
|
|
.name = "mmu",
|
|
|
|
.get = prop_mmu_get,
|
|
|
|
.set = prop_mmu_set,
|
|
|
|
};
|
|
|
|
|
2024-01-06 00:05:34 +01:00
|
|
|
static void prop_pmp_set(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
bool value;
|
|
|
|
|
|
|
|
visit_type_bool(v, name, &value, errp);
|
2023-09-12 15:24:04 +02:00
|
|
|
|
2024-01-06 00:05:34 +01:00
|
|
|
if (cpu->cfg.pmp != value && riscv_cpu_is_vendor(obj)) {
|
|
|
|
cpu_set_prop_err(cpu, name, errp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu_option_add_user_setting(name, value);
|
|
|
|
cpu->cfg.pmp = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void prop_pmp_get(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
bool value = RISCV_CPU(obj)->cfg.pmp;
|
|
|
|
|
|
|
|
visit_type_bool(v, name, &value, errp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const PropertyInfo prop_pmp = {
|
|
|
|
.name = "pmp",
|
|
|
|
.get = prop_pmp_get,
|
|
|
|
.set = prop_pmp_set,
|
|
|
|
};
|
|
|
|
|
target/riscv: rework 'priv_spec'
'priv_spec' and 'vext_spec' are two string options used as a fancy way
of setting integers in the CPU state (cpu->env.priv_ver and
cpu->env.vext_ver). It requires us to deal with string parsing and to
store them in cpu_cfg.
We must support these string options, but we don't need to store them.
We have a precedence for this kind of arrangement in target/ppc/compat.c,
ppc_compat_prop_get|set, getters and setters used for the
'max-cpu-compat' class property of the pseries ppc64 machine. We'll do
the same with both 'priv_spec' and 'vext_spec'.
For 'priv_spec', the validation from riscv_cpu_validate_priv_spec() will
be done by the prop_priv_spec_set() setter, while also preventing it to
be changed for vendor CPUs. Add two helpers that converts env->priv_ver
back and forth to its string representation. These helpers allow us to
get a string and set 'env->priv_ver' and return a string giving the
current env->priv_ver value. In other words, make the cpu->cfg.priv_spec
string obsolete.
Last but not the least, move the reworked 'priv_spec' option to
riscv_cpu_properties[].
After all said and done, we don't need to store the 'priv_spec' string in
the CPU state, and we're now protecting vendor CPUs from priv_ver
changes:
$ ./build/qemu-system-riscv64 -M virt -cpu sifive-e51,priv_spec="v1.12.0"
qemu-system-riscv64: can't apply global sifive-e51-riscv-cpu.priv_spec=v1.12.0:
CPU 'sifive-e51' does not allow changing the value of 'priv_spec'
Current 'priv_spec' val: v1.10.0
$
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Tested-by: Vladimir Isaev <vladimir.isaev@syntacore.com>
Message-ID: <20240105230546.265053-7-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2024-01-06 00:05:35 +01:00
|
|
|
static int priv_spec_from_str(const char *priv_spec_str)
|
|
|
|
{
|
|
|
|
int priv_version = -1;
|
|
|
|
|
|
|
|
if (!g_strcmp0(priv_spec_str, PRIV_VER_1_12_0_STR)) {
|
|
|
|
priv_version = PRIV_VERSION_1_12_0;
|
|
|
|
} else if (!g_strcmp0(priv_spec_str, PRIV_VER_1_11_0_STR)) {
|
|
|
|
priv_version = PRIV_VERSION_1_11_0;
|
|
|
|
} else if (!g_strcmp0(priv_spec_str, PRIV_VER_1_10_0_STR)) {
|
|
|
|
priv_version = PRIV_VERSION_1_10_0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return priv_version;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *priv_spec_to_str(int priv_version)
|
|
|
|
{
|
|
|
|
switch (priv_version) {
|
|
|
|
case PRIV_VERSION_1_10_0:
|
|
|
|
return PRIV_VER_1_10_0_STR;
|
|
|
|
case PRIV_VERSION_1_11_0:
|
|
|
|
return PRIV_VER_1_11_0_STR;
|
|
|
|
case PRIV_VERSION_1_12_0:
|
|
|
|
return PRIV_VER_1_12_0_STR;
|
|
|
|
default:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void prop_priv_spec_set(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
g_autofree char *value = NULL;
|
|
|
|
int priv_version = -1;
|
|
|
|
|
|
|
|
visit_type_str(v, name, &value, errp);
|
|
|
|
|
|
|
|
priv_version = priv_spec_from_str(value);
|
|
|
|
if (priv_version < 0) {
|
|
|
|
error_setg(errp, "Unsupported privilege spec version '%s'", value);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (priv_version != cpu->env.priv_ver && riscv_cpu_is_vendor(obj)) {
|
|
|
|
cpu_set_prop_err(cpu, name, errp);
|
|
|
|
error_append_hint(errp, "Current '%s' val: %s\n", name,
|
|
|
|
object_property_get_str(obj, name, NULL));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu_option_add_user_setting(name, priv_version);
|
|
|
|
cpu->env.priv_ver = priv_version;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void prop_priv_spec_get(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
const char *value = priv_spec_to_str(cpu->env.priv_ver);
|
|
|
|
|
|
|
|
visit_type_str(v, name, (char **)&value, errp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const PropertyInfo prop_priv_spec = {
|
|
|
|
.name = "priv_spec",
|
|
|
|
.get = prop_priv_spec_get,
|
|
|
|
.set = prop_priv_spec_set,
|
|
|
|
};
|
|
|
|
|
2024-01-06 00:05:36 +01:00
|
|
|
static void prop_vext_spec_set(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
g_autofree char *value = NULL;
|
2023-09-12 15:24:04 +02:00
|
|
|
|
2024-01-06 00:05:36 +01:00
|
|
|
visit_type_str(v, name, &value, errp);
|
|
|
|
|
|
|
|
if (g_strcmp0(value, VEXT_VER_1_00_0_STR) != 0) {
|
|
|
|
error_setg(errp, "Unsupported vector spec version '%s'", value);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu_option_add_user_setting(name, VEXT_VERSION_1_00_0);
|
|
|
|
cpu->env.vext_ver = VEXT_VERSION_1_00_0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void prop_vext_spec_get(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
const char *value = VEXT_VER_1_00_0_STR;
|
|
|
|
|
|
|
|
visit_type_str(v, name, (char **)&value, errp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const PropertyInfo prop_vext_spec = {
|
|
|
|
.name = "vext_spec",
|
|
|
|
.get = prop_vext_spec_get,
|
|
|
|
.set = prop_vext_spec_set,
|
|
|
|
};
|
|
|
|
|
2024-01-06 00:05:37 +01:00
|
|
|
static void prop_vlen_set(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
uint16_t value;
|
|
|
|
|
|
|
|
if (!visit_type_uint16(v, name, &value, errp)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!is_power_of_2(value)) {
|
|
|
|
error_setg(errp, "Vector extension VLEN must be power of 2");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (value != cpu->cfg.vlen && riscv_cpu_is_vendor(obj)) {
|
|
|
|
cpu_set_prop_err(cpu, name, errp);
|
|
|
|
error_append_hint(errp, "Current '%s' val: %u\n",
|
|
|
|
name, cpu->cfg.vlen);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu_option_add_user_setting(name, value);
|
|
|
|
cpu->cfg.vlen = value;
|
2024-01-22 17:10:55 +01:00
|
|
|
cpu->cfg.vlenb = value >> 3;
|
2024-01-06 00:05:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void prop_vlen_get(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
uint16_t value = RISCV_CPU(obj)->cfg.vlen;
|
|
|
|
|
|
|
|
visit_type_uint16(v, name, &value, errp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const PropertyInfo prop_vlen = {
|
|
|
|
.name = "vlen",
|
|
|
|
.get = prop_vlen_get,
|
|
|
|
.set = prop_vlen_set,
|
|
|
|
};
|
|
|
|
|
2024-01-06 00:05:38 +01:00
|
|
|
static void prop_elen_set(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
uint16_t value;
|
|
|
|
|
|
|
|
if (!visit_type_uint16(v, name, &value, errp)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!is_power_of_2(value)) {
|
|
|
|
error_setg(errp, "Vector extension ELEN must be power of 2");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (value != cpu->cfg.elen && riscv_cpu_is_vendor(obj)) {
|
|
|
|
cpu_set_prop_err(cpu, name, errp);
|
|
|
|
error_append_hint(errp, "Current '%s' val: %u\n",
|
|
|
|
name, cpu->cfg.elen);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu_option_add_user_setting(name, value);
|
|
|
|
cpu->cfg.elen = value;
|
|
|
|
}
|
2023-09-12 15:24:04 +02:00
|
|
|
|
2024-01-06 00:05:38 +01:00
|
|
|
static void prop_elen_get(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
uint16_t value = RISCV_CPU(obj)->cfg.elen;
|
|
|
|
|
|
|
|
visit_type_uint16(v, name, &value, errp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const PropertyInfo prop_elen = {
|
|
|
|
.name = "elen",
|
|
|
|
.get = prop_elen_get,
|
|
|
|
.set = prop_elen_set,
|
|
|
|
};
|
|
|
|
|
2024-01-12 15:01:55 +01:00
|
|
|
static void prop_cbom_blksize_set(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
uint16_t value;
|
|
|
|
|
|
|
|
if (!visit_type_uint16(v, name, &value, errp)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (value != cpu->cfg.cbom_blocksize && riscv_cpu_is_vendor(obj)) {
|
|
|
|
cpu_set_prop_err(cpu, name, errp);
|
|
|
|
error_append_hint(errp, "Current '%s' val: %u\n",
|
|
|
|
name, cpu->cfg.cbom_blocksize);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu_option_add_user_setting(name, value);
|
|
|
|
cpu->cfg.cbom_blocksize = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void prop_cbom_blksize_get(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
uint16_t value = RISCV_CPU(obj)->cfg.cbom_blocksize;
|
|
|
|
|
|
|
|
visit_type_uint16(v, name, &value, errp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const PropertyInfo prop_cbom_blksize = {
|
|
|
|
.name = "cbom_blocksize",
|
|
|
|
.get = prop_cbom_blksize_get,
|
|
|
|
.set = prop_cbom_blksize_set,
|
|
|
|
};
|
|
|
|
|
2024-01-12 15:01:56 +01:00
|
|
|
static void prop_cbop_blksize_set(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
uint16_t value;
|
|
|
|
|
|
|
|
if (!visit_type_uint16(v, name, &value, errp)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (value != cpu->cfg.cbop_blocksize && riscv_cpu_is_vendor(obj)) {
|
|
|
|
cpu_set_prop_err(cpu, name, errp);
|
|
|
|
error_append_hint(errp, "Current '%s' val: %u\n",
|
|
|
|
name, cpu->cfg.cbop_blocksize);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu_option_add_user_setting(name, value);
|
|
|
|
cpu->cfg.cbop_blocksize = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void prop_cbop_blksize_get(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
uint16_t value = RISCV_CPU(obj)->cfg.cbop_blocksize;
|
|
|
|
|
|
|
|
visit_type_uint16(v, name, &value, errp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const PropertyInfo prop_cbop_blksize = {
|
|
|
|
.name = "cbop_blocksize",
|
|
|
|
.get = prop_cbop_blksize_get,
|
|
|
|
.set = prop_cbop_blksize_set,
|
|
|
|
};
|
|
|
|
|
2024-01-12 15:01:57 +01:00
|
|
|
static void prop_cboz_blksize_set(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
uint16_t value;
|
|
|
|
|
|
|
|
if (!visit_type_uint16(v, name, &value, errp)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (value != cpu->cfg.cboz_blocksize && riscv_cpu_is_vendor(obj)) {
|
|
|
|
cpu_set_prop_err(cpu, name, errp);
|
|
|
|
error_append_hint(errp, "Current '%s' val: %u\n",
|
|
|
|
name, cpu->cfg.cboz_blocksize);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu_option_add_user_setting(name, value);
|
|
|
|
cpu->cfg.cboz_blocksize = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void prop_cboz_blksize_get(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
uint16_t value = RISCV_CPU(obj)->cfg.cboz_blocksize;
|
|
|
|
|
|
|
|
visit_type_uint16(v, name, &value, errp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const PropertyInfo prop_cboz_blksize = {
|
|
|
|
.name = "cboz_blocksize",
|
|
|
|
.get = prop_cboz_blksize_get,
|
|
|
|
.set = prop_cboz_blksize_set,
|
|
|
|
};
|
|
|
|
|
2024-01-12 15:01:59 +01:00
|
|
|
static void prop_mvendorid_set(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
bool dynamic_cpu = riscv_cpu_is_dynamic(obj);
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
uint32_t prev_val = cpu->cfg.mvendorid;
|
|
|
|
uint32_t value;
|
|
|
|
|
|
|
|
if (!visit_type_uint32(v, name, &value, errp)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dynamic_cpu && prev_val != value) {
|
|
|
|
error_setg(errp, "Unable to change %s mvendorid (0x%x)",
|
|
|
|
object_get_typename(obj), prev_val);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu->cfg.mvendorid = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void prop_mvendorid_get(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
uint32_t value = RISCV_CPU(obj)->cfg.mvendorid;
|
|
|
|
|
|
|
|
visit_type_uint32(v, name, &value, errp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const PropertyInfo prop_mvendorid = {
|
|
|
|
.name = "mvendorid",
|
|
|
|
.get = prop_mvendorid_get,
|
|
|
|
.set = prop_mvendorid_set,
|
|
|
|
};
|
|
|
|
|
2024-01-12 15:02:00 +01:00
|
|
|
static void prop_mimpid_set(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
bool dynamic_cpu = riscv_cpu_is_dynamic(obj);
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
uint64_t prev_val = cpu->cfg.mimpid;
|
|
|
|
uint64_t value;
|
|
|
|
|
|
|
|
if (!visit_type_uint64(v, name, &value, errp)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dynamic_cpu && prev_val != value) {
|
|
|
|
error_setg(errp, "Unable to change %s mimpid (0x%" PRIu64 ")",
|
|
|
|
object_get_typename(obj), prev_val);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu->cfg.mimpid = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void prop_mimpid_get(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
uint64_t value = RISCV_CPU(obj)->cfg.mimpid;
|
|
|
|
|
|
|
|
visit_type_uint64(v, name, &value, errp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const PropertyInfo prop_mimpid = {
|
|
|
|
.name = "mimpid",
|
|
|
|
.get = prop_mimpid_get,
|
|
|
|
.set = prop_mimpid_set,
|
|
|
|
};
|
|
|
|
|
2024-01-12 15:02:01 +01:00
|
|
|
static void prop_marchid_set(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
bool dynamic_cpu = riscv_cpu_is_dynamic(obj);
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
|
|
uint64_t prev_val = cpu->cfg.marchid;
|
|
|
|
uint64_t value, invalid_val;
|
|
|
|
uint32_t mxlen = 0;
|
|
|
|
|
|
|
|
if (!visit_type_uint64(v, name, &value, errp)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dynamic_cpu && prev_val != value) {
|
|
|
|
error_setg(errp, "Unable to change %s marchid (0x%" PRIu64 ")",
|
|
|
|
object_get_typename(obj), prev_val);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (riscv_cpu_mxl(&cpu->env)) {
|
|
|
|
case MXL_RV32:
|
|
|
|
mxlen = 32;
|
|
|
|
break;
|
|
|
|
case MXL_RV64:
|
|
|
|
case MXL_RV128:
|
|
|
|
mxlen = 64;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
|
|
|
|
|
|
|
invalid_val = 1LL << (mxlen - 1);
|
|
|
|
|
|
|
|
if (value == invalid_val) {
|
|
|
|
error_setg(errp, "Unable to set marchid with MSB (%u) bit set "
|
|
|
|
"and the remaining bits zero", mxlen);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu->cfg.marchid = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void prop_marchid_get(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
uint64_t value = RISCV_CPU(obj)->cfg.marchid;
|
|
|
|
|
|
|
|
visit_type_uint64(v, name, &value, errp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const PropertyInfo prop_marchid = {
|
|
|
|
.name = "marchid",
|
|
|
|
.get = prop_marchid_get,
|
|
|
|
.set = prop_marchid_set,
|
|
|
|
};
|
|
|
|
|
2023-12-18 13:53:16 +01:00
|
|
|
/*
|
|
|
|
* RVA22U64 defines some 'named features' or 'synthetic extensions'
|
|
|
|
* that are cache related: Za64rs, Zic64b, Ziccif, Ziccrse, Ziccamoa
|
|
|
|
* and Zicclsm. We do not implement caching in QEMU so we'll consider
|
|
|
|
* all these named features as always enabled.
|
|
|
|
*
|
|
|
|
* There's no riscv,isa update for them (nor for zic64b, despite it
|
|
|
|
* having a cfg offset) at this moment.
|
|
|
|
*/
|
|
|
|
static RISCVCPUProfile RVA22U64 = {
|
2023-12-18 13:53:32 +01:00
|
|
|
.parent = NULL,
|
2023-12-18 13:53:16 +01:00
|
|
|
.name = "rva22u64",
|
|
|
|
.misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVU,
|
2023-12-18 13:53:28 +01:00
|
|
|
.priv_spec = RISCV_PROFILE_ATTR_UNUSED,
|
2023-12-18 13:53:31 +01:00
|
|
|
.satp_mode = RISCV_PROFILE_ATTR_UNUSED,
|
2023-12-18 13:53:16 +01:00
|
|
|
.ext_offsets = {
|
|
|
|
CPU_CFG_OFFSET(ext_zicsr), CPU_CFG_OFFSET(ext_zihintpause),
|
|
|
|
CPU_CFG_OFFSET(ext_zba), CPU_CFG_OFFSET(ext_zbb),
|
|
|
|
CPU_CFG_OFFSET(ext_zbs), CPU_CFG_OFFSET(ext_zfhmin),
|
|
|
|
CPU_CFG_OFFSET(ext_zkt), CPU_CFG_OFFSET(ext_zicntr),
|
|
|
|
CPU_CFG_OFFSET(ext_zihpm), CPU_CFG_OFFSET(ext_zicbom),
|
|
|
|
CPU_CFG_OFFSET(ext_zicbop), CPU_CFG_OFFSET(ext_zicboz),
|
|
|
|
|
|
|
|
/* mandatory named features for this profile */
|
|
|
|
CPU_CFG_OFFSET(zic64b),
|
|
|
|
|
|
|
|
RISCV_PROFILE_EXT_LIST_END
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-12-18 13:53:33 +01:00
|
|
|
/*
|
|
|
|
* As with RVA22U64, RVA22S64 also defines 'named features'.
|
|
|
|
*
|
|
|
|
* Cache related features that we consider enabled since we don't
|
|
|
|
* implement cache: Ssccptr
|
|
|
|
*
|
|
|
|
* Other named features that we already implement: Sstvecd, Sstvala,
|
|
|
|
* Sscounterenw
|
|
|
|
*
|
|
|
|
* Named features that we need to enable: svade
|
|
|
|
*
|
|
|
|
* The remaining features/extensions comes from RVA22U64.
|
|
|
|
*/
|
|
|
|
static RISCVCPUProfile RVA22S64 = {
|
|
|
|
.parent = &RVA22U64,
|
|
|
|
.name = "rva22s64",
|
|
|
|
.misa_ext = RVS,
|
|
|
|
.priv_spec = PRIV_VERSION_1_12_0,
|
|
|
|
.satp_mode = VM_1_10_SV39,
|
|
|
|
.ext_offsets = {
|
|
|
|
/* rva22s64 exts */
|
|
|
|
CPU_CFG_OFFSET(ext_zifencei), CPU_CFG_OFFSET(ext_svpbmt),
|
|
|
|
CPU_CFG_OFFSET(ext_svinval),
|
|
|
|
|
|
|
|
/* rva22s64 named features */
|
|
|
|
CPU_CFG_OFFSET(svade),
|
|
|
|
|
|
|
|
RISCV_PROFILE_EXT_LIST_END
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-12-18 13:53:16 +01:00
|
|
|
RISCVCPUProfile *riscv_profiles[] = {
|
|
|
|
&RVA22U64,
|
2023-12-18 13:53:33 +01:00
|
|
|
&RVA22S64,
|
2023-12-18 13:53:16 +01:00
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
2022-06-08 08:14:37 +02:00
|
|
|
static Property riscv_cpu_properties[] = {
|
|
|
|
DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
|
|
|
|
|
2024-01-06 00:05:32 +01:00
|
|
|
{.name = "pmu-mask", .info = &prop_pmu_mask},
|
|
|
|
{.name = "pmu-num", .info = &prop_pmu_num}, /* Deprecated */
|
|
|
|
|
2024-01-06 00:05:33 +01:00
|
|
|
{.name = "mmu", .info = &prop_mmu},
|
2024-01-06 00:05:34 +01:00
|
|
|
{.name = "pmp", .info = &prop_pmp},
|
2024-01-06 00:05:33 +01:00
|
|
|
|
target/riscv: rework 'priv_spec'
'priv_spec' and 'vext_spec' are two string options used as a fancy way
of setting integers in the CPU state (cpu->env.priv_ver and
cpu->env.vext_ver). It requires us to deal with string parsing and to
store them in cpu_cfg.
We must support these string options, but we don't need to store them.
We have a precedence for this kind of arrangement in target/ppc/compat.c,
ppc_compat_prop_get|set, getters and setters used for the
'max-cpu-compat' class property of the pseries ppc64 machine. We'll do
the same with both 'priv_spec' and 'vext_spec'.
For 'priv_spec', the validation from riscv_cpu_validate_priv_spec() will
be done by the prop_priv_spec_set() setter, while also preventing it to
be changed for vendor CPUs. Add two helpers that converts env->priv_ver
back and forth to its string representation. These helpers allow us to
get a string and set 'env->priv_ver' and return a string giving the
current env->priv_ver value. In other words, make the cpu->cfg.priv_spec
string obsolete.
Last but not the least, move the reworked 'priv_spec' option to
riscv_cpu_properties[].
After all said and done, we don't need to store the 'priv_spec' string in
the CPU state, and we're now protecting vendor CPUs from priv_ver
changes:
$ ./build/qemu-system-riscv64 -M virt -cpu sifive-e51,priv_spec="v1.12.0"
qemu-system-riscv64: can't apply global sifive-e51-riscv-cpu.priv_spec=v1.12.0:
CPU 'sifive-e51' does not allow changing the value of 'priv_spec'
Current 'priv_spec' val: v1.10.0
$
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Tested-by: Vladimir Isaev <vladimir.isaev@syntacore.com>
Message-ID: <20240105230546.265053-7-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2024-01-06 00:05:35 +01:00
|
|
|
{.name = "priv_spec", .info = &prop_priv_spec},
|
2024-01-06 00:05:36 +01:00
|
|
|
{.name = "vext_spec", .info = &prop_vext_spec},
|
target/riscv: rework 'priv_spec'
'priv_spec' and 'vext_spec' are two string options used as a fancy way
of setting integers in the CPU state (cpu->env.priv_ver and
cpu->env.vext_ver). It requires us to deal with string parsing and to
store them in cpu_cfg.
We must support these string options, but we don't need to store them.
We have a precedence for this kind of arrangement in target/ppc/compat.c,
ppc_compat_prop_get|set, getters and setters used for the
'max-cpu-compat' class property of the pseries ppc64 machine. We'll do
the same with both 'priv_spec' and 'vext_spec'.
For 'priv_spec', the validation from riscv_cpu_validate_priv_spec() will
be done by the prop_priv_spec_set() setter, while also preventing it to
be changed for vendor CPUs. Add two helpers that converts env->priv_ver
back and forth to its string representation. These helpers allow us to
get a string and set 'env->priv_ver' and return a string giving the
current env->priv_ver value. In other words, make the cpu->cfg.priv_spec
string obsolete.
Last but not the least, move the reworked 'priv_spec' option to
riscv_cpu_properties[].
After all said and done, we don't need to store the 'priv_spec' string in
the CPU state, and we're now protecting vendor CPUs from priv_ver
changes:
$ ./build/qemu-system-riscv64 -M virt -cpu sifive-e51,priv_spec="v1.12.0"
qemu-system-riscv64: can't apply global sifive-e51-riscv-cpu.priv_spec=v1.12.0:
CPU 'sifive-e51' does not allow changing the value of 'priv_spec'
Current 'priv_spec' val: v1.10.0
$
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Tested-by: Vladimir Isaev <vladimir.isaev@syntacore.com>
Message-ID: <20240105230546.265053-7-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2024-01-06 00:05:35 +01:00
|
|
|
|
2024-01-06 00:05:37 +01:00
|
|
|
{.name = "vlen", .info = &prop_vlen},
|
2024-01-06 00:05:38 +01:00
|
|
|
{.name = "elen", .info = &prop_elen},
|
2024-01-06 00:05:37 +01:00
|
|
|
|
2024-01-12 15:01:55 +01:00
|
|
|
{.name = "cbom_blocksize", .info = &prop_cbom_blksize},
|
2024-01-12 15:01:56 +01:00
|
|
|
{.name = "cbop_blocksize", .info = &prop_cbop_blksize},
|
2024-01-12 15:01:57 +01:00
|
|
|
{.name = "cboz_blocksize", .info = &prop_cboz_blksize},
|
2024-01-12 15:01:55 +01:00
|
|
|
|
2024-01-12 15:01:59 +01:00
|
|
|
{.name = "mvendorid", .info = &prop_mvendorid},
|
2024-01-12 15:02:00 +01:00
|
|
|
{.name = "mimpid", .info = &prop_mimpid},
|
2024-01-12 15:02:01 +01:00
|
|
|
{.name = "marchid", .info = &prop_marchid},
|
2024-01-12 15:01:59 +01:00
|
|
|
|
2022-09-14 12:11:06 +02:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC),
|
|
|
|
#endif
|
2022-05-10 13:29:08 +02:00
|
|
|
|
|
|
|
DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, false),
|
2022-06-06 08:16:56 +02:00
|
|
|
|
|
|
|
DEFINE_PROP_BOOL("rvv_ta_all_1s", RISCVCPU, cfg.rvv_ta_all_1s, false),
|
2022-06-20 08:51:11 +02:00
|
|
|
DEFINE_PROP_BOOL("rvv_ma_all_1s", RISCVCPU, cfg.rvv_ma_all_1s, false),
|
target/riscv: allow MISA writes as experimental
At this moment, and apparently since ever, we have no way of enabling
RISCV_FEATURE_MISA. This means that all the code from write_misa(), all
the nuts and bolts that handles how to properly write this CSR, has
always been a no-op as well because write_misa() will always exit
earlier.
This seems to be benign in the majority of cases. Booting an Ubuntu
'virt' guest and logging all the calls to 'write_misa' shows that no
writes to MISA CSR was attempted. Writing MISA, i.e. enabling/disabling
RISC-V extensions after the machine is powered on, seems to be a niche
use.
After discussions in the mailing list, most notably in [1], we reached
the consensus that this code is not suited to be exposed to users
because it's not well tested, but at the same time removing it is a bit
extreme because we would like to fix it, and it's easier to do so with
the code available to use instead of fetching it from git log.
The approach taken here is to get rid of RISCV_FEATURE_MISA altogether
and use a new experimental flag called x-misa-w. The default value is
false, meaning that we're keeping the existing behavior of doing nothing
if a write_misa() is attempted. As with any existing experimental flag,
x-misa-w is also a temporary flag that we need to remove once we fix
write_misa().
[1] https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg05092.html
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Weiwei Li<liweiwei@iscas.ac.cn>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Message-ID: <20230222185205.355361-4-dbarboza@ventanamicro.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-02-22 19:51:58 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* write_misa() is marked as experimental for now so mark
|
|
|
|
* it with -x and default to 'false'.
|
|
|
|
*/
|
|
|
|
DEFINE_PROP_BOOL("x-misa-w", RISCVCPU, cfg.misa_w, false),
|
2019-04-20 04:24:01 +02:00
|
|
|
DEFINE_PROP_END_OF_LIST(),
|
|
|
|
};
|
|
|
|
|
2023-12-18 13:53:26 +01:00
|
|
|
#if defined(TARGET_RISCV64)
|
|
|
|
static void rva22u64_profile_cpu_init(Object *obj)
|
|
|
|
{
|
|
|
|
rv64i_bare_cpu_init(obj);
|
|
|
|
|
|
|
|
RVA22U64.enabled = true;
|
|
|
|
}
|
2023-12-18 13:53:34 +01:00
|
|
|
|
|
|
|
static void rva22s64_profile_cpu_init(Object *obj)
|
|
|
|
{
|
|
|
|
rv64i_bare_cpu_init(obj);
|
|
|
|
|
|
|
|
RVA22S64.enabled = true;
|
|
|
|
}
|
2023-12-18 13:53:26 +01:00
|
|
|
#endif
|
|
|
|
|
2023-10-09 18:40:53 +02:00
|
|
|
static const gchar *riscv_gdb_arch_name(CPUState *cs)
|
2021-01-06 21:41:41 +01:00
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(cs);
|
|
|
|
CPURISCVState *env = &cpu->env;
|
|
|
|
|
2021-10-20 05:16:58 +02:00
|
|
|
switch (riscv_cpu_mxl(env)) {
|
|
|
|
case MXL_RV32:
|
2023-10-09 18:40:53 +02:00
|
|
|
return "riscv:rv32";
|
2021-10-20 05:16:58 +02:00
|
|
|
case MXL_RV64:
|
2022-01-06 22:00:57 +01:00
|
|
|
case MXL_RV128:
|
2023-10-09 18:40:53 +02:00
|
|
|
return "riscv:rv64";
|
2021-10-20 05:16:58 +02:00
|
|
|
default:
|
|
|
|
g_assert_not_reached();
|
2021-01-06 21:41:41 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-16 06:41:22 +01:00
|
|
|
static const char *riscv_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(cs);
|
|
|
|
|
|
|
|
if (strcmp(xmlname, "riscv-csr.xml") == 0) {
|
|
|
|
return cpu->dyn_csr_xml;
|
2021-12-10 08:56:54 +01:00
|
|
|
} else if (strcmp(xmlname, "riscv-vector.xml") == 0) {
|
|
|
|
return cpu->dyn_vreg_xml;
|
2021-01-16 06:41:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-05-17 12:51:31 +02:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
2023-03-03 07:50:54 +01:00
|
|
|
static int64_t riscv_get_arch_id(CPUState *cs)
|
|
|
|
{
|
|
|
|
RISCVCPU *cpu = RISCV_CPU(cs);
|
|
|
|
|
|
|
|
return cpu->env.mhartid;
|
|
|
|
}
|
|
|
|
|
2021-05-17 12:51:31 +02:00
|
|
|
#include "hw/core/sysemu-cpu-ops.h"
|
|
|
|
|
|
|
|
static const struct SysemuCPUOps riscv_sysemu_ops = {
|
2021-05-17 12:51:37 +02:00
|
|
|
.get_phys_page_debug = riscv_cpu_get_phys_page_debug,
|
2021-05-17 12:51:35 +02:00
|
|
|
.write_elf64_note = riscv_cpu_write_elf64_note,
|
|
|
|
.write_elf32_note = riscv_cpu_write_elf32_note,
|
2021-05-17 12:51:32 +02:00
|
|
|
.legacy_vmsd = &vmstate_riscv_cpu,
|
2021-05-17 12:51:31 +02:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2018-03-02 13:31:10 +01:00
|
|
|
static void riscv_cpu_class_init(ObjectClass *c, void *data)
|
|
|
|
{
|
|
|
|
RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
|
|
|
|
CPUClass *cc = CPU_CLASS(c);
|
|
|
|
DeviceClass *dc = DEVICE_CLASS(c);
|
2022-11-24 12:50:17 +01:00
|
|
|
ResettableClass *rc = RESETTABLE_CLASS(c);
|
2018-03-02 13:31:10 +01:00
|
|
|
|
2018-11-26 04:20:38 +01:00
|
|
|
device_class_set_parent_realize(dc, riscv_cpu_realize,
|
|
|
|
&mcc->parent_realize);
|
2018-03-02 13:31:10 +01:00
|
|
|
|
2022-11-24 12:50:17 +01:00
|
|
|
resettable_class_set_parent_phases(rc, NULL, riscv_cpu_reset_hold, NULL,
|
|
|
|
&mcc->parent_phases);
|
2018-03-02 13:31:10 +01:00
|
|
|
|
|
|
|
cc->class_by_name = riscv_cpu_class_by_name;
|
|
|
|
cc->has_work = riscv_cpu_has_work;
|
2024-01-29 01:34:43 +01:00
|
|
|
cc->mmu_index = riscv_cpu_mmu_index;
|
2018-03-02 13:31:10 +01:00
|
|
|
cc->dump_state = riscv_cpu_dump_state;
|
|
|
|
cc->set_pc = riscv_cpu_set_pc;
|
2022-09-30 19:31:21 +02:00
|
|
|
cc->get_pc = riscv_cpu_get_pc;
|
2018-03-02 13:31:10 +01:00
|
|
|
cc->gdb_read_register = riscv_cpu_gdb_read_register;
|
|
|
|
cc->gdb_write_register = riscv_cpu_gdb_write_register;
|
2019-03-15 11:26:59 +01:00
|
|
|
cc->gdb_num_core_regs = 33;
|
2018-03-02 13:31:10 +01:00
|
|
|
cc->gdb_stop_before_watchpoint = true;
|
|
|
|
cc->disas_set_info = riscv_cpu_disas_set_info;
|
2019-04-02 12:12:38 +02:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
2021-05-17 12:51:31 +02:00
|
|
|
cc->sysemu_ops = &riscv_sysemu_ops;
|
2023-03-03 07:50:54 +01:00
|
|
|
cc->get_arch_id = riscv_get_arch_id;
|
2018-03-02 13:31:10 +01:00
|
|
|
#endif
|
2021-01-06 21:41:41 +01:00
|
|
|
cc->gdb_arch_name = riscv_gdb_arch_name;
|
2021-01-16 06:41:22 +01:00
|
|
|
cc->gdb_get_dynamic_xml = riscv_gdb_get_dynamic_xml;
|
2021-02-04 17:39:10 +01:00
|
|
|
|
2020-01-10 16:30:32 +01:00
|
|
|
device_class_set_props(dc, riscv_cpu_properties);
|
2018-03-02 13:31:10 +01:00
|
|
|
}
|
|
|
|
|
2023-04-05 10:58:13 +02:00
|
|
|
static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str,
|
|
|
|
int max_str_len)
|
2022-03-29 21:56:57 +02:00
|
|
|
{
|
2023-09-25 19:57:08 +02:00
|
|
|
const RISCVIsaExtData *edata;
|
2022-03-29 21:56:57 +02:00
|
|
|
char *old = *isa_str;
|
|
|
|
char *new = *isa_str;
|
|
|
|
|
2023-09-25 19:57:08 +02:00
|
|
|
for (edata = isa_edata_arr; edata && edata->name; edata++) {
|
|
|
|
if (isa_ext_is_enabled(cpu, edata->ext_enable_offset)) {
|
|
|
|
new = g_strconcat(old, "_", edata->name, NULL);
|
2022-03-29 21:56:57 +02:00
|
|
|
g_free(old);
|
|
|
|
old = new;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*isa_str = new;
|
|
|
|
}
|
|
|
|
|
2018-03-02 13:31:10 +01:00
|
|
|
char *riscv_isa_string(RISCVCPU *cpu)
|
|
|
|
{
|
|
|
|
int i;
|
2022-03-28 15:11:23 +02:00
|
|
|
const size_t maxlen = sizeof("rv128") + sizeof(riscv_single_letter_exts);
|
2018-03-19 22:18:49 +01:00
|
|
|
char *isa_str = g_new(char, maxlen);
|
|
|
|
char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS);
|
2022-03-28 15:11:23 +02:00
|
|
|
for (i = 0; i < sizeof(riscv_single_letter_exts) - 1; i++) {
|
|
|
|
if (cpu->env.misa_ext & RV(riscv_single_letter_exts[i])) {
|
|
|
|
*p++ = qemu_tolower(riscv_single_letter_exts[i]);
|
2018-03-02 13:31:10 +01:00
|
|
|
}
|
|
|
|
}
|
2018-03-19 22:18:49 +01:00
|
|
|
*p = '\0';
|
2022-05-10 13:29:08 +02:00
|
|
|
if (!cpu->cfg.short_isa_string) {
|
|
|
|
riscv_isa_string_ext(cpu, &isa_str, maxlen);
|
|
|
|
}
|
2018-03-19 22:18:49 +01:00
|
|
|
return isa_str;
|
2018-03-02 13:31:10 +01:00
|
|
|
}
|
|
|
|
|
2018-03-08 23:12:31 +01:00
|
|
|
#define DEFINE_CPU(type_name, initfn) \
|
|
|
|
{ \
|
|
|
|
.name = type_name, \
|
|
|
|
.parent = TYPE_RISCV_CPU, \
|
|
|
|
.instance_init = initfn \
|
|
|
|
}
|
|
|
|
|
target/riscv: add TYPE_RISCV_DYNAMIC_CPU
This new abstract type will be used to differentiate between static and
non-static CPUs in query-cpu-definitions.
All generic CPUs were changed to be of this type. Named CPUs are kept as
TYPE_RISCV_CPU and will still be considered static.
This is the output of query-cpu-definitions after this change for the
riscv64 target:
$ ./build/qemu-system-riscv64 -S -M virt -display none -qmp stdio
{"QMP": {"version": (...)}
{"execute": "qmp_capabilities", "arguments": {"enable": ["oob"]}}
{"return": {}}
{"execute": "query-cpu-definitions"}
{"return": [
{"name": "rv64", "typename": "rv64-riscv-cpu", "static": false, "deprecated": false},
{"name": "sifive-e51", "typename": "sifive-e51-riscv-cpu", "static": true, "deprecated": false},
{"name": "any", "typename": "any-riscv-cpu", "static": false, "deprecated": false},
{"name": "x-rv128", "typename": "x-rv128-riscv-cpu", "static": false, "deprecated": false},
{"name": "shakti-c", "typename": "shakti-c-riscv-cpu", "static": true, "deprecated": false},
{"name": "thead-c906", "typename": "thead-c906-riscv-cpu", "static": true, "deprecated": false},
{"name": "sifive-u54", "typename": "sifive-u54-riscv-cpu", "static": true, "deprecated": false}
]}
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230411183511.189632-4-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-04-11 20:35:11 +02:00
|
|
|
#define DEFINE_DYNAMIC_CPU(type_name, initfn) \
|
|
|
|
{ \
|
|
|
|
.name = type_name, \
|
|
|
|
.parent = TYPE_RISCV_DYNAMIC_CPU, \
|
|
|
|
.instance_init = initfn \
|
|
|
|
}
|
|
|
|
|
2023-12-18 13:53:09 +01:00
|
|
|
#define DEFINE_VENDOR_CPU(type_name, initfn) \
|
|
|
|
{ \
|
|
|
|
.name = type_name, \
|
|
|
|
.parent = TYPE_RISCV_VENDOR_CPU, \
|
|
|
|
.instance_init = initfn \
|
|
|
|
}
|
|
|
|
|
target/riscv: add rv64i CPU
We don't have any form of a 'bare bones' CPU. rv64, our default CPUs,
comes with a lot of defaults. This is fine for most regular uses but
it's not suitable when more control of what is actually loaded in the
CPU is required.
A bare-bones CPU would be annoying to deal with if not by profile
support, a way to load a multitude of extensions with a single flag.
Profile support is going to be implemented shortly, so let's add a CPU
for it.
The new 'rv64i' CPU will have only RVI loaded. It is inspired in the
profile specification that dictates, for RVA22U64 [1]:
"RVA22U64 Mandatory Base
RV64I is the mandatory base ISA for RVA22U64"
And so it seems that RV64I is the mandatory base ISA for all profiles
listed in [1], making it an ideal CPU to use with profile support.
rv64i is a CPU of type TYPE_RISCV_BARE_CPU. It has a mix of features
from pre-existent CPUs:
- it allows extensions to be enabled, like generic CPUs;
- it will not inherit extension defaults, like vendor CPUs.
This is the minimum extension set to boot OpenSBI and buildroot using
rv64i:
./build/qemu-system-riscv64 -nographic -M virt \
-cpu rv64i,sv39=true,g=true,c=true,s=true,u=true
Our minimal riscv,isa in this case will be:
# cat /proc/device-tree/cpus/cpu@0/riscv,isa
rv64imafdc_zicntr_zicsr_zifencei_zihpm_zca_zcd#
[1] https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20231218125334.37184-5-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-12-18 13:53:12 +01:00
|
|
|
#define DEFINE_BARE_CPU(type_name, initfn) \
|
|
|
|
{ \
|
|
|
|
.name = type_name, \
|
|
|
|
.parent = TYPE_RISCV_BARE_CPU, \
|
|
|
|
.instance_init = initfn \
|
|
|
|
}
|
|
|
|
|
2023-12-18 13:53:26 +01:00
|
|
|
#define DEFINE_PROFILE_CPU(type_name, initfn) \
|
|
|
|
{ \
|
|
|
|
.name = type_name, \
|
|
|
|
.parent = TYPE_RISCV_BARE_CPU, \
|
|
|
|
.instance_init = initfn \
|
|
|
|
}
|
|
|
|
|
2018-03-08 23:12:31 +01:00
|
|
|
static const TypeInfo riscv_cpu_type_infos[] = {
|
|
|
|
{
|
|
|
|
.name = TYPE_RISCV_CPU,
|
|
|
|
.parent = TYPE_CPU,
|
|
|
|
.instance_size = sizeof(RISCVCPU),
|
2023-09-14 00:06:21 +02:00
|
|
|
.instance_align = __alignof(RISCVCPU),
|
2018-03-08 23:12:31 +01:00
|
|
|
.instance_init = riscv_cpu_init,
|
2023-09-25 19:56:55 +02:00
|
|
|
.instance_post_init = riscv_cpu_post_init,
|
2018-03-08 23:12:31 +01:00
|
|
|
.abstract = true,
|
|
|
|
.class_size = sizeof(RISCVCPUClass),
|
|
|
|
.class_init = riscv_cpu_class_init,
|
|
|
|
},
|
target/riscv: add TYPE_RISCV_DYNAMIC_CPU
This new abstract type will be used to differentiate between static and
non-static CPUs in query-cpu-definitions.
All generic CPUs were changed to be of this type. Named CPUs are kept as
TYPE_RISCV_CPU and will still be considered static.
This is the output of query-cpu-definitions after this change for the
riscv64 target:
$ ./build/qemu-system-riscv64 -S -M virt -display none -qmp stdio
{"QMP": {"version": (...)}
{"execute": "qmp_capabilities", "arguments": {"enable": ["oob"]}}
{"return": {}}
{"execute": "query-cpu-definitions"}
{"return": [
{"name": "rv64", "typename": "rv64-riscv-cpu", "static": false, "deprecated": false},
{"name": "sifive-e51", "typename": "sifive-e51-riscv-cpu", "static": true, "deprecated": false},
{"name": "any", "typename": "any-riscv-cpu", "static": false, "deprecated": false},
{"name": "x-rv128", "typename": "x-rv128-riscv-cpu", "static": false, "deprecated": false},
{"name": "shakti-c", "typename": "shakti-c-riscv-cpu", "static": true, "deprecated": false},
{"name": "thead-c906", "typename": "thead-c906-riscv-cpu", "static": true, "deprecated": false},
{"name": "sifive-u54", "typename": "sifive-u54-riscv-cpu", "static": true, "deprecated": false}
]}
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230411183511.189632-4-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-04-11 20:35:11 +02:00
|
|
|
{
|
|
|
|
.name = TYPE_RISCV_DYNAMIC_CPU,
|
|
|
|
.parent = TYPE_RISCV_CPU,
|
|
|
|
.abstract = true,
|
|
|
|
},
|
2023-12-18 13:53:09 +01:00
|
|
|
{
|
|
|
|
.name = TYPE_RISCV_VENDOR_CPU,
|
|
|
|
.parent = TYPE_RISCV_CPU,
|
|
|
|
.abstract = true,
|
|
|
|
},
|
target/riscv: add rv64i CPU
We don't have any form of a 'bare bones' CPU. rv64, our default CPUs,
comes with a lot of defaults. This is fine for most regular uses but
it's not suitable when more control of what is actually loaded in the
CPU is required.
A bare-bones CPU would be annoying to deal with if not by profile
support, a way to load a multitude of extensions with a single flag.
Profile support is going to be implemented shortly, so let's add a CPU
for it.
The new 'rv64i' CPU will have only RVI loaded. It is inspired in the
profile specification that dictates, for RVA22U64 [1]:
"RVA22U64 Mandatory Base
RV64I is the mandatory base ISA for RVA22U64"
And so it seems that RV64I is the mandatory base ISA for all profiles
listed in [1], making it an ideal CPU to use with profile support.
rv64i is a CPU of type TYPE_RISCV_BARE_CPU. It has a mix of features
from pre-existent CPUs:
- it allows extensions to be enabled, like generic CPUs;
- it will not inherit extension defaults, like vendor CPUs.
This is the minimum extension set to boot OpenSBI and buildroot using
rv64i:
./build/qemu-system-riscv64 -nographic -M virt \
-cpu rv64i,sv39=true,g=true,c=true,s=true,u=true
Our minimal riscv,isa in this case will be:
# cat /proc/device-tree/cpus/cpu@0/riscv,isa
rv64imafdc_zicntr_zicsr_zifencei_zihpm_zca_zcd#
[1] https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20231218125334.37184-5-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-12-18 13:53:12 +01:00
|
|
|
{
|
|
|
|
.name = TYPE_RISCV_BARE_CPU,
|
|
|
|
.parent = TYPE_RISCV_CPU,
|
|
|
|
.abstract = true,
|
|
|
|
},
|
target/riscv: add TYPE_RISCV_DYNAMIC_CPU
This new abstract type will be used to differentiate between static and
non-static CPUs in query-cpu-definitions.
All generic CPUs were changed to be of this type. Named CPUs are kept as
TYPE_RISCV_CPU and will still be considered static.
This is the output of query-cpu-definitions after this change for the
riscv64 target:
$ ./build/qemu-system-riscv64 -S -M virt -display none -qmp stdio
{"QMP": {"version": (...)}
{"execute": "qmp_capabilities", "arguments": {"enable": ["oob"]}}
{"return": {}}
{"execute": "query-cpu-definitions"}
{"return": [
{"name": "rv64", "typename": "rv64-riscv-cpu", "static": false, "deprecated": false},
{"name": "sifive-e51", "typename": "sifive-e51-riscv-cpu", "static": true, "deprecated": false},
{"name": "any", "typename": "any-riscv-cpu", "static": false, "deprecated": false},
{"name": "x-rv128", "typename": "x-rv128-riscv-cpu", "static": false, "deprecated": false},
{"name": "shakti-c", "typename": "shakti-c-riscv-cpu", "static": true, "deprecated": false},
{"name": "thead-c906", "typename": "thead-c906-riscv-cpu", "static": true, "deprecated": false},
{"name": "sifive-u54", "typename": "sifive-u54-riscv-cpu", "static": true, "deprecated": false}
]}
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230411183511.189632-4-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-04-11 20:35:11 +02:00
|
|
|
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
|
2023-09-12 15:24:13 +02:00
|
|
|
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX, riscv_max_cpu_init),
|
2018-03-08 23:12:31 +01:00
|
|
|
#if defined(TARGET_RISCV32)
|
target/riscv: add TYPE_RISCV_DYNAMIC_CPU
This new abstract type will be used to differentiate between static and
non-static CPUs in query-cpu-definitions.
All generic CPUs were changed to be of this type. Named CPUs are kept as
TYPE_RISCV_CPU and will still be considered static.
This is the output of query-cpu-definitions after this change for the
riscv64 target:
$ ./build/qemu-system-riscv64 -S -M virt -display none -qmp stdio
{"QMP": {"version": (...)}
{"execute": "qmp_capabilities", "arguments": {"enable": ["oob"]}}
{"return": {}}
{"execute": "query-cpu-definitions"}
{"return": [
{"name": "rv64", "typename": "rv64-riscv-cpu", "static": false, "deprecated": false},
{"name": "sifive-e51", "typename": "sifive-e51-riscv-cpu", "static": true, "deprecated": false},
{"name": "any", "typename": "any-riscv-cpu", "static": false, "deprecated": false},
{"name": "x-rv128", "typename": "x-rv128-riscv-cpu", "static": false, "deprecated": false},
{"name": "shakti-c", "typename": "shakti-c-riscv-cpu", "static": true, "deprecated": false},
{"name": "thead-c906", "typename": "thead-c906-riscv-cpu", "static": true, "deprecated": false},
{"name": "sifive-u54", "typename": "sifive-u54-riscv-cpu", "static": true, "deprecated": false}
]}
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230411183511.189632-4-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-04-11 20:35:11 +02:00
|
|
|
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE32, rv32_base_cpu_init),
|
2023-12-18 13:53:09 +01:00
|
|
|
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
|
|
|
|
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32_sifive_e_cpu_init),
|
|
|
|
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
|
|
|
|
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32_sifive_u_cpu_init),
|
2018-03-08 23:12:31 +01:00
|
|
|
#elif defined(TARGET_RISCV64)
|
target/riscv: add TYPE_RISCV_DYNAMIC_CPU
This new abstract type will be used to differentiate between static and
non-static CPUs in query-cpu-definitions.
All generic CPUs were changed to be of this type. Named CPUs are kept as
TYPE_RISCV_CPU and will still be considered static.
This is the output of query-cpu-definitions after this change for the
riscv64 target:
$ ./build/qemu-system-riscv64 -S -M virt -display none -qmp stdio
{"QMP": {"version": (...)}
{"execute": "qmp_capabilities", "arguments": {"enable": ["oob"]}}
{"return": {}}
{"execute": "query-cpu-definitions"}
{"return": [
{"name": "rv64", "typename": "rv64-riscv-cpu", "static": false, "deprecated": false},
{"name": "sifive-e51", "typename": "sifive-e51-riscv-cpu", "static": true, "deprecated": false},
{"name": "any", "typename": "any-riscv-cpu", "static": false, "deprecated": false},
{"name": "x-rv128", "typename": "x-rv128-riscv-cpu", "static": false, "deprecated": false},
{"name": "shakti-c", "typename": "shakti-c-riscv-cpu", "static": true, "deprecated": false},
{"name": "thead-c906", "typename": "thead-c906-riscv-cpu", "static": true, "deprecated": false},
{"name": "sifive-u54", "typename": "sifive-u54-riscv-cpu", "static": true, "deprecated": false}
]}
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230411183511.189632-4-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-04-11 20:35:11 +02:00
|
|
|
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE64, rv64_base_cpu_init),
|
2023-12-18 13:53:09 +01:00
|
|
|
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init),
|
|
|
|
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init),
|
|
|
|
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init),
|
|
|
|
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906, rv64_thead_c906_cpu_init),
|
|
|
|
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1, rv64_veyron_v1_cpu_init),
|
target/riscv: add TYPE_RISCV_DYNAMIC_CPU
This new abstract type will be used to differentiate between static and
non-static CPUs in query-cpu-definitions.
All generic CPUs were changed to be of this type. Named CPUs are kept as
TYPE_RISCV_CPU and will still be considered static.
This is the output of query-cpu-definitions after this change for the
riscv64 target:
$ ./build/qemu-system-riscv64 -S -M virt -display none -qmp stdio
{"QMP": {"version": (...)}
{"execute": "qmp_capabilities", "arguments": {"enable": ["oob"]}}
{"return": {}}
{"execute": "query-cpu-definitions"}
{"return": [
{"name": "rv64", "typename": "rv64-riscv-cpu", "static": false, "deprecated": false},
{"name": "sifive-e51", "typename": "sifive-e51-riscv-cpu", "static": true, "deprecated": false},
{"name": "any", "typename": "any-riscv-cpu", "static": false, "deprecated": false},
{"name": "x-rv128", "typename": "x-rv128-riscv-cpu", "static": false, "deprecated": false},
{"name": "shakti-c", "typename": "shakti-c-riscv-cpu", "static": true, "deprecated": false},
{"name": "thead-c906", "typename": "thead-c906-riscv-cpu", "static": true, "deprecated": false},
{"name": "sifive-u54", "typename": "sifive-u54-riscv-cpu", "static": true, "deprecated": false}
]}
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230411183511.189632-4-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-04-11 20:35:11 +02:00
|
|
|
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, rv128_base_cpu_init),
|
target/riscv: add rv64i CPU
We don't have any form of a 'bare bones' CPU. rv64, our default CPUs,
comes with a lot of defaults. This is fine for most regular uses but
it's not suitable when more control of what is actually loaded in the
CPU is required.
A bare-bones CPU would be annoying to deal with if not by profile
support, a way to load a multitude of extensions with a single flag.
Profile support is going to be implemented shortly, so let's add a CPU
for it.
The new 'rv64i' CPU will have only RVI loaded. It is inspired in the
profile specification that dictates, for RVA22U64 [1]:
"RVA22U64 Mandatory Base
RV64I is the mandatory base ISA for RVA22U64"
And so it seems that RV64I is the mandatory base ISA for all profiles
listed in [1], making it an ideal CPU to use with profile support.
rv64i is a CPU of type TYPE_RISCV_BARE_CPU. It has a mix of features
from pre-existent CPUs:
- it allows extensions to be enabled, like generic CPUs;
- it will not inherit extension defaults, like vendor CPUs.
This is the minimum extension set to boot OpenSBI and buildroot using
rv64i:
./build/qemu-system-riscv64 -nographic -M virt \
-cpu rv64i,sv39=true,g=true,c=true,s=true,u=true
Our minimal riscv,isa in this case will be:
# cat /proc/device-tree/cpus/cpu@0/riscv,isa
rv64imafdc_zicntr_zicsr_zifencei_zihpm_zca_zcd#
[1] https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20231218125334.37184-5-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2023-12-18 13:53:12 +01:00
|
|
|
DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64I, rv64i_bare_cpu_init),
|
2023-12-18 13:53:26 +01:00
|
|
|
DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22U64, rva22u64_profile_cpu_init),
|
2023-12-18 13:53:34 +01:00
|
|
|
DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22S64, rva22s64_profile_cpu_init),
|
2018-03-08 23:12:31 +01:00
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
DEFINE_TYPES(riscv_cpu_type_infos)
|