From: Rajnesh Kanwal <rkanwal@rivosinc.com>
To: Alistair Francis <alistair23@gmail.com>
Cc: qemu-riscv@nongnu.org, qemu-devel@nongnu.org,
alistair.francis@wdc.com, bin.meng@windriver.com,
liweiwei@iscas.ac.cn, dbarboza@ventanamicro.com,
zhiwei_liu@linux.alibaba.com, atishp@rivosinc.com,
apatel@ventanamicro.com, beeman@rivosinc.com,
jason.chien@sifive.com, frank.chang@sifive.com,
richard.henderson@linaro.org
Subject: Re: [PATCH v5 6/7] target/riscv: Add support to access ctrsource, ctrtarget, ctrdata regs.
Date: Tue, 4 Feb 2025 13:51:08 +0000 [thread overview]
Message-ID: <CAECbVCvdSAnuL2YDZ2kPGCaEVTvxcATfHM=PtmovVWYkS5Hk5Q@mail.gmail.com> (raw)
In-Reply-To: <CAKmqyKM1hnbUhVwZeKa6Qrsk0tQdF5=D50gsDMk9TUNjJJUHkg@mail.gmail.com>
On Mon, Feb 3, 2025 at 2:58 AM Alistair Francis <alistair23@gmail.com> wrote:
>
> On Thu, Dec 5, 2024 at 9:36 PM Rajnesh Kanwal <rkanwal@rivosinc.com> wrote:
> >
> > CTR entries are accessed using ctrsource, ctrtarget and ctrdata
> > registers using smcsrind/sscsrind extension. This commits extends
> > the csrind extension to support CTR registers.
> >
> > ctrsource is accessible through xireg CSR, ctrtarget is accessible
> > through xireg1 and ctrdata is accessible through xireg2 CSR.
> >
> > CTR supports maximum depth of 256 entries which are accessed using
> > xiselect range 0x200 to 0x2ff.
> >
> > This commits also adds properties to enable CTR extension. CTR can be
> > enabled using smctr=true and ssctr=true now.
> >
> > Signed-off-by: Rajnesh Kanwal <rkanwal@rivosinc.com>
> > ---
> > target/riscv/cpu.c | 26 +++++++-
> > target/riscv/csr.c | 150 ++++++++++++++++++++++++++++++++++++++++++++-
> > target/riscv/tcg/tcg-cpu.c | 11 ++++
> > 3 files changed, 185 insertions(+), 2 deletions(-)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 2a4f285a974ffc62e7f3e938691dbffe376a7e46..751029e924d4690aaa5de65456fd5a5ec25b916a 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -199,6 +199,8 @@ const RISCVIsaExtData isa_edata_arr[] = {
> > ISA_EXT_DATA_ENTRY(sstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
> > ISA_EXT_DATA_ENTRY(sstvecd, PRIV_VERSION_1_12_0, has_priv_1_12),
> > ISA_EXT_DATA_ENTRY(svade, PRIV_VERSION_1_11_0, ext_svade),
> > + ISA_EXT_DATA_ENTRY(smctr, PRIV_VERSION_1_12_0, ext_smctr),
> > + ISA_EXT_DATA_ENTRY(ssctr, PRIV_VERSION_1_12_0, ext_ssctr),
> > 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),
> > @@ -1481,6 +1483,8 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
> > MULTI_EXT_CFG_BOOL("smcdeleg", ext_smcdeleg, false),
> > MULTI_EXT_CFG_BOOL("sscsrind", ext_sscsrind, false),
> > MULTI_EXT_CFG_BOOL("ssccfg", ext_ssccfg, false),
> > + MULTI_EXT_CFG_BOOL("smctr", ext_smctr, false),
> > + MULTI_EXT_CFG_BOOL("ssctr", ext_ssctr, false),
>
> This should be the very last patch (once everything is supported)
>
> Otherwise
>
> Acked-by: Alistair Francis <alistair.francis@wdc.com>
>
> Alistair
I am sending v6 as I will have to rebase this series on the latest
riscv-to-apply.for-upstream. I will fix the order of patches in that.
Thanks
Rajnesh
>
> > MULTI_EXT_CFG_BOOL("zifencei", ext_zifencei, true),
> > MULTI_EXT_CFG_BOOL("zicfilp", ext_zicfilp, false),
> > MULTI_EXT_CFG_BOOL("zicfiss", ext_zicfiss, false),
> > @@ -2656,6 +2660,26 @@ static RISCVCPUImpliedExtsRule SSCFG_IMPLIED = {
> > },
> > };
> >
> > +static RISCVCPUImpliedExtsRule SMCTR_IMPLIED = {
> > + .ext = CPU_CFG_OFFSET(ext_smctr),
> > + .implied_misa_exts = RVS,
> > + .implied_multi_exts = {
> > + CPU_CFG_OFFSET(ext_sscsrind),
> > +
> > + RISCV_IMPLIED_EXTS_RULE_END
> > + },
> > +};
> > +
> > +static RISCVCPUImpliedExtsRule SSCTR_IMPLIED = {
> > + .ext = CPU_CFG_OFFSET(ext_ssctr),
> > + .implied_misa_exts = RVS,
> > + .implied_multi_exts = {
> > + CPU_CFG_OFFSET(ext_sscsrind),
> > +
> > + RISCV_IMPLIED_EXTS_RULE_END
> > + },
> > +};
> > +
> > RISCVCPUImpliedExtsRule *riscv_misa_ext_implied_rules[] = {
> > &RVA_IMPLIED, &RVD_IMPLIED, &RVF_IMPLIED,
> > &RVM_IMPLIED, &RVV_IMPLIED, NULL
> > @@ -2674,7 +2698,7 @@ RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[] = {
> > &ZVFH_IMPLIED, &ZVFHMIN_IMPLIED, &ZVKN_IMPLIED,
> > &ZVKNC_IMPLIED, &ZVKNG_IMPLIED, &ZVKNHB_IMPLIED,
> > &ZVKS_IMPLIED, &ZVKSC_IMPLIED, &ZVKSG_IMPLIED, &SSCFG_IMPLIED,
> > - NULL
> > + &SMCTR_IMPLIED, &SSCTR_IMPLIED, NULL
> > };
> >
> > static Property riscv_cpu_properties[] = {
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index a399d55740c7259cd1c1d893687541e23ea3ce52..d7b520099563d3a680c5b75dc987881caab95407 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -2399,6 +2399,13 @@ static bool xiselect_cd_range(target_ulong isel)
> > return (ISELECT_CD_FIRST <= isel && isel <= ISELECT_CD_LAST);
> > }
> >
> > +static bool xiselect_ctr_range(int csrno, target_ulong isel)
> > +{
> > + /* MIREG-MIREG6 for the range 0x200-0x2ff are not used by CTR. */
> > + return CTR_ENTRIES_FIRST <= isel && isel <= CTR_ENTRIES_LAST &&
> > + csrno < CSR_MIREG;
> > +}
> > +
> > static int rmw_iprio(target_ulong xlen,
> > target_ulong iselect, uint8_t *iprio,
> > target_ulong *val, target_ulong new_val,
> > @@ -2444,6 +2451,124 @@ static int rmw_iprio(target_ulong xlen,
> > return 0;
> > }
> >
> > +static int rmw_ctrsource(CPURISCVState *env, int isel, target_ulong *val,
> > + target_ulong new_val, target_ulong wr_mask)
> > +{
> > + /*
> > + * CTR arrays are treated as circular buffers and TOS always points to next
> > + * empty slot, keeping TOS - 1 always pointing to latest entry. Given entry
> > + * 0 is always the latest one, traversal is a bit different here. See the
> > + * below example.
> > + *
> > + * Depth = 16.
> > + *
> > + * idx [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [A] [B] [C] [D] [E] [F]
> > + * TOS H
> > + * entry 6 5 4 3 2 1 0 F E D C B A 9 8 7
> > + */
> > + const uint64_t entry = isel - CTR_ENTRIES_FIRST;
> > + const uint64_t depth = 16 << get_field(env->sctrdepth, SCTRDEPTH_MASK);
> > + uint64_t idx;
> > +
> > + /* Entry greater than depth-1 is read-only zero */
> > + if (entry >= depth) {
> > + if (val) {
> > + *val = 0;
> > + }
> > + return 0;
> > + }
> > +
> > + idx = get_field(env->sctrstatus, SCTRSTATUS_WRPTR_MASK);
> > + idx = (idx - entry - 1) & (depth - 1);
> > +
> > + if (val) {
> > + *val = env->ctr_src[idx];
> > + }
> > +
> > + env->ctr_src[idx] = (env->ctr_src[idx] & ~wr_mask) | (new_val & wr_mask);
> > +
> > + return 0;
> > +}
> > +
> > +static int rmw_ctrtarget(CPURISCVState *env, int isel, target_ulong *val,
> > + target_ulong new_val, target_ulong wr_mask)
> > +{
> > + /*
> > + * CTR arrays are treated as circular buffers and TOS always points to next
> > + * empty slot, keeping TOS - 1 always pointing to latest entry. Given entry
> > + * 0 is always the latest one, traversal is a bit different here. See the
> > + * below example.
> > + *
> > + * Depth = 16.
> > + *
> > + * idx [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [A] [B] [C] [D] [E] [F]
> > + * head H
> > + * entry 6 5 4 3 2 1 0 F E D C B A 9 8 7
> > + */
> > + const uint64_t entry = isel - CTR_ENTRIES_FIRST;
> > + const uint64_t depth = 16 << get_field(env->sctrdepth, SCTRDEPTH_MASK);
> > + uint64_t idx;
> > +
> > + /* Entry greater than depth-1 is read-only zero */
> > + if (entry >= depth) {
> > + if (val) {
> > + *val = 0;
> > + }
> > + return 0;
> > + }
> > +
> > + idx = get_field(env->sctrstatus, SCTRSTATUS_WRPTR_MASK);
> > + idx = (idx - entry - 1) & (depth - 1);
> > +
> > + if (val) {
> > + *val = env->ctr_dst[idx];
> > + }
> > +
> > + env->ctr_dst[idx] = (env->ctr_dst[idx] & ~wr_mask) | (new_val & wr_mask);
> > +
> > + return 0;
> > +}
> > +
> > +static int rmw_ctrdata(CPURISCVState *env, int isel, target_ulong *val,
> > + target_ulong new_val, target_ulong wr_mask)
> > +{
> > + /*
> > + * CTR arrays are treated as circular buffers and TOS always points to next
> > + * empty slot, keeping TOS - 1 always pointing to latest entry. Given entry
> > + * 0 is always the latest one, traversal is a bit different here. See the
> > + * below example.
> > + *
> > + * Depth = 16.
> > + *
> > + * idx [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [A] [B] [C] [D] [E] [F]
> > + * head H
> > + * entry 6 5 4 3 2 1 0 F E D C B A 9 8 7
> > + */
> > + const uint64_t entry = isel - CTR_ENTRIES_FIRST;
> > + const uint64_t mask = wr_mask & CTRDATA_MASK;
> > + const uint64_t depth = 16 << get_field(env->sctrdepth, SCTRDEPTH_MASK);
> > + uint64_t idx;
> > +
> > + /* Entry greater than depth-1 is read-only zero */
> > + if (entry >= depth) {
> > + if (val) {
> > + *val = 0;
> > + }
> > + return 0;
> > + }
> > +
> > + idx = get_field(env->sctrstatus, SCTRSTATUS_WRPTR_MASK);
> > + idx = (idx - entry - 1) & (depth - 1);
> > +
> > + if (val) {
> > + *val = env->ctr_data[idx];
> > + }
> > +
> > + env->ctr_data[idx] = (env->ctr_data[idx] & ~mask) | (new_val & mask);
> > +
> > + return 0;
> > +}
> > +
> > static RISCVException rmw_xireg_aia(CPURISCVState *env, int csrno,
> > target_ulong isel, target_ulong *val,
> > target_ulong new_val, target_ulong wr_mask)
> > @@ -2596,6 +2721,27 @@ done:
> > return ret;
> > }
> >
> > +static int rmw_xireg_ctr(CPURISCVState *env, int csrno,
> > + target_ulong isel, target_ulong *val,
> > + target_ulong new_val, target_ulong wr_mask)
> > +{
> > + if (!riscv_cpu_cfg(env)->ext_smctr && !riscv_cpu_cfg(env)->ext_ssctr) {
> > + return -EINVAL;
> > + }
> > +
> > + if (csrno == CSR_SIREG || csrno == CSR_VSIREG) {
> > + return rmw_ctrsource(env, isel, val, new_val, wr_mask);
> > + } else if (csrno == CSR_SIREG2 || csrno == CSR_VSIREG2) {
> > + return rmw_ctrtarget(env, isel, val, new_val, wr_mask);
> > + } else if (csrno == CSR_SIREG3 || csrno == CSR_VSIREG3) {
> > + return rmw_ctrdata(env, isel, val, new_val, wr_mask);
> > + } else if (val) {
> > + *val = 0;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > /*
> > * rmw_xireg_csrind: Perform indirect access to xireg and xireg2-xireg6
> > *
> > @@ -2607,11 +2753,13 @@ static int rmw_xireg_csrind(CPURISCVState *env, int csrno,
> > target_ulong isel, target_ulong *val,
> > target_ulong new_val, target_ulong wr_mask)
> > {
> > - int ret = -EINVAL;
> > bool virt = csrno == CSR_VSIREG ? true : false;
> > + int ret = -EINVAL;
> >
> > if (xiselect_cd_range(isel)) {
> > ret = rmw_xireg_cd(env, csrno, isel, val, new_val, wr_mask);
> > + } else if (xiselect_ctr_range(csrno, isel)) {
> > + ret = rmw_xireg_ctr(env, csrno, isel, val, new_val, wr_mask);
> > } else {
> > /*
> > * As per the specification, access to unimplented region is undefined
> > diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> > index 2b57aa4d1704b176f314dbe0b120cfcc943bf4f8..575b5692c7f68a5f6d37edbc17269e41f496f682 100644
> > --- a/target/riscv/tcg/tcg-cpu.c
> > +++ b/target/riscv/tcg/tcg-cpu.c
> > @@ -652,6 +652,17 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
> > return;
> > }
> >
> > + if ((cpu->cfg.ext_smctr || cpu->cfg.ext_ssctr) &&
> > + (!riscv_has_ext(env, RVS) || !cpu->cfg.ext_sscsrind)) {
> > + if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_smctr)) ||
> > + cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_ssctr))) {
> > + error_setg(errp, "Smctr and Ssctr require S-mode and Sscsrind");
> > + return;
> > + }
> > + cpu->cfg.ext_smctr = false;
> > + cpu->cfg.ext_ssctr = false;
> > + }
> > +
> > /*
> > * Disable isa extensions based on priv spec after we
> > * validated and set everything we need.
> >
> > --
> > 2.34.1
> >
> >
next prev parent reply other threads:[~2025-02-04 13:52 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-05 11:34 [PATCH v5 0/7] target/riscv: Add support for Control Transfer Records Ext Rajnesh Kanwal
2024-12-05 11:34 ` [PATCH v5 1/7] target/riscv: Remove obsolete sfence.vm instruction Rajnesh Kanwal
2024-12-05 11:34 ` [PATCH v5 2/7] target/riscv: Add Control Transfer Records CSR definitions Rajnesh Kanwal
2024-12-05 11:34 ` [PATCH v5 3/7] target/riscv: Add support for Control Transfer Records extension CSRs Rajnesh Kanwal
2025-02-03 1:41 ` Alistair Francis
2024-12-05 11:34 ` [PATCH v5 4/7] target/riscv: Add support to record CTR entries Rajnesh Kanwal
2025-02-03 2:51 ` Alistair Francis
2024-12-05 11:34 ` [PATCH v5 5/7] target/riscv: Add CTR sctrclr instruction Rajnesh Kanwal
2025-02-03 2:53 ` Alistair Francis
2024-12-05 11:34 ` [PATCH v5 6/7] target/riscv: Add support to access ctrsource, ctrtarget, ctrdata regs Rajnesh Kanwal
2025-02-03 2:57 ` Alistair Francis
2025-02-04 13:51 ` Rajnesh Kanwal [this message]
2024-12-05 11:34 ` [PATCH v5 7/7] target/riscv: machine: Add Control Transfer Record state description Rajnesh Kanwal
2025-02-03 2:58 ` Alistair Francis
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='CAECbVCvdSAnuL2YDZ2kPGCaEVTvxcATfHM=PtmovVWYkS5Hk5Q@mail.gmail.com' \
--to=rkanwal@rivosinc.com \
--cc=alistair.francis@wdc.com \
--cc=alistair23@gmail.com \
--cc=apatel@ventanamicro.com \
--cc=atishp@rivosinc.com \
--cc=beeman@rivosinc.com \
--cc=bin.meng@windriver.com \
--cc=dbarboza@ventanamicro.com \
--cc=frank.chang@sifive.com \
--cc=jason.chien@sifive.com \
--cc=liweiwei@iscas.ac.cn \
--cc=qemu-devel@nongnu.org \
--cc=qemu-riscv@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=zhiwei_liu@linux.alibaba.com \
/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).