From: Alistair Francis <alistair23@gmail.com>
To: "Frédéric Pétrot" <frederic.petrot@univ-grenoble-alpes.fr>
Cc: "open list:RISC-V" <qemu-riscv@nongnu.org>,
"Bin Meng" <bin.meng@windriver.com>,
"Richard Henderson" <richard.henderson@linaro.org>,
"qemu-devel@nongnu.org Developers" <qemu-devel@nongnu.org>,
"Alistair Francis" <alistair.francis@wdc.com>,
"Fabien Portas" <fabien.portas@grenoble-inp.org>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
"Philippe Mathieu-Daudé" <philmd@redhat.com>
Subject: Re: [PATCH v7 18/18] target/riscv: actual functions to realize crs 128-bit insns
Date: Thu, 6 Jan 2022 16:48:08 +1000 [thread overview]
Message-ID: <CAKmqyKPqX0iGJ3T6+PDHvbF+MLHD=n4JqQt3Cs6ORd_sfQ5sxQ@mail.gmail.com> (raw)
In-Reply-To: <20211213163834.170504-19-frederic.petrot@univ-grenoble-alpes.fr>
On Tue, Dec 14, 2021 at 3:01 AM Frédéric Pétrot
<frederic.petrot@univ-grenoble-alpes.fr> wrote:
>
> The csrs are accessed through function pointers: we add 128-bit read
> operations in the table for three csrs (writes fallback to the
> 64-bit version as the upper 64-bit information is handled elsewhere):
> - misa, as mxl is needed for proper operation,
> - mstatus and sstatus, to return sd
> In addition, we also add read and write accesses to the machine and
> supervisor scratch registers.
>
> Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
> Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/cpu.h | 7 ++
> target/riscv/cpu_bits.h | 3 +
> target/riscv/csr.c | 195 +++++++++++++++++++++++++++++++++-------
> 3 files changed, 175 insertions(+), 30 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 00e5081598..3e770e3d03 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -486,12 +486,19 @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
> Int128 *ret_value,
> Int128 new_value, Int128 write_mask);
>
> +typedef RISCVException (*riscv_csr_read128_fn)(CPURISCVState *env, int csrno,
> + Int128 *ret_value);
> +typedef RISCVException (*riscv_csr_write128_fn)(CPURISCVState *env, int csrno,
> + Int128 new_value);
> +
> typedef struct {
> const char *name;
> riscv_csr_predicate_fn predicate;
> riscv_csr_read_fn read;
> riscv_csr_write_fn write;
> riscv_csr_op_fn op;
> + riscv_csr_read128_fn read128;
> + riscv_csr_write128_fn write128;
> } riscv_csr_operations;
>
> /* CSR function table constants */
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index 9913fa9f77..390ba0a52f 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -392,6 +392,7 @@
>
> #define MSTATUS32_SD 0x80000000
> #define MSTATUS64_SD 0x8000000000000000ULL
> +#define MSTATUSH128_SD 0x8000000000000000ULL
>
> #define MISA32_MXL 0xC0000000
> #define MISA64_MXL 0xC000000000000000ULL
> @@ -413,6 +414,8 @@ typedef enum {
> #define SSTATUS_SUM 0x00040000 /* since: priv-1.10 */
> #define SSTATUS_MXR 0x00080000
>
> +#define SSTATUS64_UXL 0x0000000300000000ULL
> +
> #define SSTATUS32_SD 0x80000000
> #define SSTATUS64_SD 0x8000000000000000ULL
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index dca9e19a64..404aa2f31d 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -453,7 +453,7 @@ static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS &
> (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)));
> static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
> SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
> - SSTATUS_SUM | SSTATUS_MXR;
> + SSTATUS_SUM | SSTATUS_MXR | (target_ulong)SSTATUS64_UXL;
> static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
> static const target_ulong hip_writable_mask = MIP_VSSIP;
> static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
> @@ -498,6 +498,8 @@ static uint64_t add_status_sd(RISCVMXL xl, uint64_t status)
> return status | MSTATUS32_SD;
> case MXL_RV64:
> return status | MSTATUS64_SD;
> + case MXL_RV128:
> + return MSTATUSH128_SD;
> default:
> g_assert_not_reached();
> }
> @@ -547,10 +549,11 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
>
> mstatus = (mstatus & ~mask) | (val & mask);
>
> - if (riscv_cpu_mxl(env) == MXL_RV64) {
> + RISCVMXL xl = riscv_cpu_mxl(env);
> + if (xl > MXL_RV32) {
> /* SXL and UXL fields are for now read only */
> - mstatus = set_field(mstatus, MSTATUS64_SXL, MXL_RV64);
> - mstatus = set_field(mstatus, MSTATUS64_UXL, MXL_RV64);
> + mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
> + mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
> }
> env->mstatus = mstatus;
>
> @@ -579,6 +582,20 @@ static RISCVException write_mstatush(CPURISCVState *env, int csrno,
> return RISCV_EXCP_NONE;
> }
>
> +static RISCVException read_mstatus_i128(CPURISCVState *env, int csrno,
> + Int128 *val)
> +{
> + *val = int128_make128(env->mstatus, add_status_sd(MXL_RV128, env->mstatus));
> + return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException read_misa_i128(CPURISCVState *env, int csrno,
> + Int128 *val)
> +{
> + *val = int128_make128(env->misa_ext, (uint64_t)MXL_RV128 << 62);
> + return RISCV_EXCP_NONE;
> +}
> +
> static RISCVException read_misa(CPURISCVState *env, int csrno,
> target_ulong *val)
> {
> @@ -736,6 +753,21 @@ static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
> }
>
> /* Machine Trap Handling */
> +static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno,
> + Int128 *val)
> +{
> + *val = int128_make128(env->mscratch, env->mscratchh);
> + return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_mscratch_i128(CPURISCVState *env, int csrno,
> + Int128 val)
> +{
> + env->mscratch = int128_getlo(val);
> + env->mscratchh = int128_gethi(val);
> + return RISCV_EXCP_NONE;
> +}
> +
> static RISCVException read_mscratch(CPURISCVState *env, int csrno,
> target_ulong *val)
> {
> @@ -815,6 +847,16 @@ static RISCVException rmw_mip(CPURISCVState *env, int csrno,
> }
>
> /* Supervisor Trap Setup */
> +static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
> + Int128 *val)
> +{
> + uint64_t mask = sstatus_v1_10_mask;
> + uint64_t sstatus = env->mstatus & mask;
> +
> + *val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus));
> + return RISCV_EXCP_NONE;
> +}
> +
> static RISCVException read_sstatus(CPURISCVState *env, int csrno,
> target_ulong *val)
> {
> @@ -908,6 +950,21 @@ static RISCVException write_scounteren(CPURISCVState *env, int csrno,
> }
>
> /* Supervisor Trap Handling */
> +static RISCVException read_sscratch_i128(CPURISCVState *env, int csrno,
> + Int128 *val)
> +{
> + *val = int128_make128(env->sscratch, env->sscratchh);
> + return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_sscratch_i128(CPURISCVState *env, int csrno,
> + Int128 val)
> +{
> + env->sscratch = int128_getlo(val);
> + env->sscratchh = int128_gethi(val);
> + return RISCV_EXCP_NONE;
> +}
> +
> static RISCVException read_sscratch(CPURISCVState *env, int csrno,
> target_ulong *val)
> {
> @@ -1708,16 +1765,13 @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
> * csrrc <-> riscv_csrrw(env, csrno, ret_value, 0, value);
> */
>
> -RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> - target_ulong *ret_value,
> - target_ulong new_value, target_ulong write_mask)
> +static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
> + int csrno,
> + bool write_mask,
> + RISCVCPU *cpu)
> {
> - RISCVException ret;
> - target_ulong old_value;
> - RISCVCPU *cpu = env_archcpu(env);
> - int read_only = get_field(csrno, 0xC00) == 3;
> -
> /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
> + int read_only = get_field(csrno, 0xC00) == 3;
> #if !defined(CONFIG_USER_ONLY)
> int effective_priv = env->priv;
>
> @@ -1749,10 +1803,17 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> if (!csr_ops[csrno].predicate) {
> return RISCV_EXCP_ILLEGAL_INST;
> }
> - ret = csr_ops[csrno].predicate(env, csrno);
> - if (ret != RISCV_EXCP_NONE) {
> - return ret;
> - }
> +
> + return csr_ops[csrno].predicate(env, csrno);
> +}
> +
> +static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
> + target_ulong *ret_value,
> + target_ulong new_value,
> + target_ulong write_mask)
> +{
> + RISCVException ret;
> + target_ulong old_value;
>
> /* execute combined read/write operation if it exists */
> if (csr_ops[csrno].op) {
> @@ -1788,20 +1849,89 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> return RISCV_EXCP_NONE;
> }
>
> +RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> + target_ulong *ret_value,
> + target_ulong new_value, target_ulong write_mask)
> +{
> + RISCVCPU *cpu = env_archcpu(env);
> +
> + RISCVException ret = riscv_csrrw_check(env, csrno, write_mask, cpu);
> + if (ret != RISCV_EXCP_NONE) {
> + return ret;
> + }
> +
> + return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask);
> +}
> +
> +static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
> + Int128 *ret_value,
> + Int128 new_value,
> + Int128 write_mask)
> +{
> + RISCVException ret;
> + Int128 old_value;
> +
> + /* read old value */
> + ret = csr_ops[csrno].read128(env, csrno, &old_value);
> + if (ret != RISCV_EXCP_NONE) {
> + return ret;
> + }
> +
> + /* write value if writable and write mask set, otherwise drop writes */
> + if (int128_nz(write_mask)) {
> + new_value = int128_or(int128_and(old_value, int128_not(write_mask)),
> + int128_and(new_value, write_mask));
> + if (csr_ops[csrno].write128) {
> + ret = csr_ops[csrno].write128(env, csrno, new_value);
> + if (ret != RISCV_EXCP_NONE) {
> + return ret;
> + }
> + } else if (csr_ops[csrno].write) {
> + /* avoids having to write wrappers for all registers */
> + ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value));
> + if (ret != RISCV_EXCP_NONE) {
> + return ret;
> + }
> + }
> + }
> +
> + /* return old value */
> + if (ret_value) {
> + *ret_value = old_value;
> + }
> +
> + return RISCV_EXCP_NONE;
> +}
> +
> RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
> - Int128 *ret_value,
> - Int128 new_value, Int128 write_mask)
> + Int128 *ret_value,
> + Int128 new_value, Int128 write_mask)
> {
> - /* fall back to 64-bit version for now */
> - target_ulong ret_64;
> - RISCVException ret = riscv_csrrw(env, csrno, &ret_64,
> - int128_getlo(new_value),
> - int128_getlo(write_mask));
> + RISCVException ret;
> + RISCVCPU *cpu = env_archcpu(env);
>
> - if (ret_value) {
> - *ret_value = int128_make64(ret_64);
> + ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask), cpu);
> + if (ret != RISCV_EXCP_NONE) {
> + return ret;
> }
>
> + if (csr_ops[csrno].read128) {
> + return riscv_csrrw_do128(env, csrno, ret_value, new_value, write_mask);
> + }
> +
> + /*
> + * Fall back to 64-bit version for now, if the 128-bit alternative isn't
> + * at all defined.
> + * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
> + * significant), for those, this fallback is correctly handling the accesses
> + */
> + target_ulong old_value;
> + ret = riscv_csrrw_do64(env, csrno, &old_value,
> + int128_getlo(new_value),
> + int128_getlo(write_mask));
> + if (ret == RISCV_EXCP_NONE && ret_value) {
> + *ret_value = int128_make64(old_value);
> + }
> return ret;
> }
>
> @@ -1864,8 +1994,10 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
> [CSR_MHARTID] = { "mhartid", any, read_mhartid },
>
> /* Machine Trap Setup */
> - [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus },
> - [CSR_MISA] = { "misa", any, read_misa, write_misa },
> + [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus, NULL,
> + read_mstatus_i128 },
> + [CSR_MISA] = { "misa", any, read_misa, write_misa, NULL,
> + read_misa_i128 },
> [CSR_MIDELEG] = { "mideleg", any, read_mideleg, write_mideleg },
> [CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg },
> [CSR_MIE] = { "mie", any, read_mie, write_mie },
> @@ -1875,20 +2007,23 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
> [CSR_MSTATUSH] = { "mstatush", any32, read_mstatush, write_mstatush },
>
> /* Machine Trap Handling */
> - [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch },
> + [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch, NULL,
> + read_mscratch_i128, write_mscratch_i128 },
> [CSR_MEPC] = { "mepc", any, read_mepc, write_mepc },
> [CSR_MCAUSE] = { "mcause", any, read_mcause, write_mcause },
> [CSR_MTVAL] = { "mtval", any, read_mtval, write_mtval },
> [CSR_MIP] = { "mip", any, NULL, NULL, rmw_mip },
>
> /* Supervisor Trap Setup */
> - [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus },
> + [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus, NULL,
> + read_sstatus_i128 },
> [CSR_SIE] = { "sie", smode, read_sie, write_sie },
> [CSR_STVEC] = { "stvec", smode, read_stvec, write_stvec },
> [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren, write_scounteren },
>
> /* Supervisor Trap Handling */
> - [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch },
> + [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch, NULL,
> + read_sscratch_i128, write_sscratch_i128 },
> [CSR_SEPC] = { "sepc", smode, read_sepc, write_sepc },
> [CSR_SCAUSE] = { "scause", smode, read_scause, write_scause },
> [CSR_STVAL] = { "stval", smode, read_stval, write_stval },
> --
> 2.34.1
>
>
next prev parent reply other threads:[~2022-01-06 7:09 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-13 16:38 [PATCH v7 00/18] Adding partial support for 128-bit riscv target Frédéric Pétrot
2021-12-13 16:38 ` [PATCH v7 01/18] exec/memop: Adding signedness to quad definitions Frédéric Pétrot
2021-12-13 16:38 ` [PATCH v7 02/18] exec/memop: Adding signed quad and octo defines Frédéric Pétrot
2021-12-13 16:38 ` [PATCH v7 03/18] qemu/int128: addition of div/rem 128-bit operations Frédéric Pétrot
2021-12-13 16:38 ` [PATCH v7 04/18] target/riscv: additional macros to check instruction support Frédéric Pétrot
2021-12-13 16:38 ` [PATCH v7 05/18] target/riscv: separation of bitwise logic and arithmetic helpers Frédéric Pétrot
2021-12-13 16:38 ` [PATCH v7 06/18] target/riscv: array for the 64 upper bits of 128-bit registers Frédéric Pétrot
2021-12-13 16:38 ` [PATCH v7 07/18] target/riscv: setup everything for rv64 to support rv128 execution Frédéric Pétrot
2021-12-13 16:38 ` [PATCH v7 08/18] target/riscv: moving some insns close to similar insns Frédéric Pétrot
2021-12-13 16:38 ` [PATCH v7 09/18] target/riscv: accessors to registers upper part and 128-bit load/store Frédéric Pétrot
2021-12-13 16:38 ` [PATCH v7 10/18] target/riscv: support for 128-bit bitwise instructions Frédéric Pétrot
2021-12-13 16:38 ` [PATCH v7 11/18] target/riscv: support for 128-bit U-type instructions Frédéric Pétrot
2021-12-13 16:38 ` [PATCH v7 12/18] target/riscv: support for 128-bit shift instructions Frédéric Pétrot
2021-12-21 6:55 ` Alistair Francis
2021-12-13 16:38 ` [PATCH v7 13/18] target/riscv: support for 128-bit arithmetic instructions Frédéric Pétrot
2022-01-06 1:17 ` Alistair Francis
2021-12-13 16:38 ` [PATCH v7 14/18] target/riscv: support for 128-bit M extension Frédéric Pétrot
2022-01-06 1:23 ` Alistair Francis
2021-12-13 16:38 ` [PATCH v7 15/18] target/riscv: adding high part of some csrs Frédéric Pétrot
2021-12-13 16:38 ` [PATCH v7 16/18] target/riscv: helper functions to wrap calls to 128-bit csr insns Frédéric Pétrot
2022-01-06 1:25 ` Alistair Francis
2021-12-13 16:38 ` [PATCH v7 17/18] target/riscv: modification of the trans_csrxx for 128-bit support Frédéric Pétrot
2022-01-06 1:58 ` Alistair Francis
2021-12-13 16:38 ` [PATCH v7 18/18] target/riscv: actual functions to realize crs 128-bit insns Frédéric Pétrot
2022-01-06 6:48 ` Alistair Francis [this message]
2022-01-06 8:33 ` [PATCH v7 00/18] Adding partial support for 128-bit riscv target Alistair Francis
2022-01-06 15:35 ` Frédéric Pétrot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAKmqyKPqX0iGJ3T6+PDHvbF+MLHD=n4JqQt3Cs6ORd_sfQ5sxQ@mail.gmail.com' \
--to=alistair23@gmail.com \
--cc=alistair.francis@wdc.com \
--cc=bin.meng@windriver.com \
--cc=fabien.portas@grenoble-inp.org \
--cc=frederic.petrot@univ-grenoble-alpes.fr \
--cc=palmer@dabbelt.com \
--cc=philmd@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-riscv@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).