qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] riscv: thead: Add th.sxstatus CSR emulation
@ 2024-03-29 12:04 Christoph Müllner
  2024-04-05  1:36 ` LIU Zhiwei
  0 siblings, 1 reply; 3+ messages in thread
From: Christoph Müllner @ 2024-03-29 12:04 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Cooper Qu,
	Zhiwei Liu, Huang Tao, Conor Dooley, Andrew Jones,
	Daniel Henrique Barboza, Vivian Wang, Qingfang Deng,
	Alexandre Ghiti
  Cc: Christoph Müllner, Weiwei Li

The th.sxstatus CSR can be used to identify available custom extension
on T-Head CPUs. The CSR is documented here:
  https://github.com/T-head-Semi/thead-extension-spec/pull/46

An important property of this patch is, that the th.sxstatus MAEE field
is not set (indicating that XTheadMaee is not available).
XTheadMaee is a memory attribute extension (similar to Svpbmt) which is
implemented in many T-Head CPUs (C906, C910, etc.) and utilizes bits
in PTEs that are marked as reserved. QEMU maintainers prefer to not
implement XTheadMaee, so we need give kernels a mechanism to identify
if XTheadMaee is available in a system or not. And this patch introduces
this mechanism in QEMU in a way that's compatible with real HW
(i.e., probing the th.sxstatus.MAEE bit).

Further context can be found on the list:
https://lists.gnu.org/archive/html/qemu-devel/2024-02/msg00775.html

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 target/riscv/cpu.c       |  1 +
 target/riscv/cpu.h       |  3 ++
 target/riscv/meson.build |  1 +
 target/riscv/th_csr.c    | 78 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 83 insertions(+)
 create mode 100644 target/riscv/th_csr.c

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 36e3e5fdaf..b82ba95ae6 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -545,6 +545,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)
     cpu->cfg.mvendorid = THEAD_VENDOR_ID;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_SV39);
+    th_register_custom_csrs(cpu);
 #endif
 
     /* inherited from parent obj via riscv_cpu_init() */
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3b1a02b944..c9f8f06751 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -824,4 +824,7 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
 uint8_t satp_mode_max_from_map(uint32_t map);
 const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
 
+/* Implemented in th_csr.c */
+void th_register_custom_csrs(RISCVCPU *cpu);
+
 #endif /* RISCV_CPU_H */
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index a5e0734e7f..a4bd61e52a 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -33,6 +33,7 @@ riscv_system_ss.add(files(
   'monitor.c',
   'machine.c',
   'pmu.c',
+  'th_csr.c',
   'time_helper.c',
   'riscv-qmp-cmds.c',
 ))
diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
new file mode 100644
index 0000000000..66d260cabd
--- /dev/null
+++ b/target/riscv/th_csr.c
@@ -0,0 +1,78 @@
+/*
+ * T-Head-specific CSRs.
+ *
+ * Copyright (c) 2024 VRULL GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * 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"
+#include "cpu.h"
+#include "cpu_vendorid.h"
+
+#define CSR_TH_SXSTATUS 0x5c0
+
+/* TH_SXSTATUS bits */
+#define TH_SXSTATUS_UCME        BIT(16)
+#define TH_SXSTATUS_MAEE        BIT(21)
+#define TH_SXSTATUS_THEADISAEE  BIT(22)
+
+typedef struct {
+    int csrno;
+    int (*insertion_test)(RISCVCPU *cpu);
+    riscv_csr_operations csr_ops;
+} riscv_csr;
+
+static RISCVException s_mode_csr(CPURISCVState *env, int csrno)
+{
+    if (env->debugger)
+        return RISCV_EXCP_NONE;
+
+    if (env->priv >= PRV_S)
+        return RISCV_EXCP_NONE;
+
+    return RISCV_EXCP_ILLEGAL_INST;
+}
+
+static int test_thead_mvendorid(RISCVCPU *cpu)
+{
+    if (cpu->cfg.mvendorid != THEAD_VENDOR_ID)
+        return -1;
+    return 0;
+}
+
+static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
+                                       target_ulong *val)
+{
+    /* We don't set MAEE here, because QEMU does not implement MAEE. */
+    *val = TH_SXSTATUS_UCME | TH_SXSTATUS_THEADISAEE;
+    return RISCV_EXCP_NONE;
+}
+
+static riscv_csr th_csr_list[] = {
+    {
+        .csrno = CSR_TH_SXSTATUS,
+        .insertion_test = test_thead_mvendorid,
+        .csr_ops = { "th.sxstatus", s_mode_csr, read_th_sxstatus }
+    }
+};
+
+void th_register_custom_csrs(RISCVCPU *cpu)
+{
+    for (size_t i = 0; i < ARRAY_SIZE(th_csr_list); i++) {
+        int csrno = th_csr_list[i].csrno;
+        riscv_csr_operations *csr_ops = &th_csr_list[i].csr_ops;
+        if (!th_csr_list[i].insertion_test(cpu))
+            riscv_set_csr_ops(csrno, csr_ops);
+    }
+}
-- 
2.44.0



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] riscv: thead: Add th.sxstatus CSR emulation
  2024-03-29 12:04 [PATCH v2] riscv: thead: Add th.sxstatus CSR emulation Christoph Müllner
@ 2024-04-05  1:36 ` LIU Zhiwei
  2024-04-17 22:54   ` Christoph Müllner
  0 siblings, 1 reply; 3+ messages in thread
From: LIU Zhiwei @ 2024-04-05  1:36 UTC (permalink / raw)
  To: Christoph Müllner, qemu-riscv, qemu-devel, Alistair Francis,
	Bin Meng, Philipp Tomsich, Palmer Dabbelt, Richard Henderson,
	Cooper Qu, Huang Tao, Conor Dooley, Andrew Jones,
	Daniel Henrique Barboza, Vivian Wang, Qingfang Deng,
	Alexandre Ghiti
  Cc: Weiwei Li


On 2024/3/29 20:04, Christoph Müllner wrote:
> The th.sxstatus CSR can be used to identify available custom extension
> on T-Head CPUs. The CSR is documented here:
>    https://github.com/T-head-Semi/thead-extension-spec/pull/46
>
> An important property of this patch is, that the th.sxstatus MAEE field
> is not set (indicating that XTheadMaee is not available).
> XTheadMaee is a memory attribute extension (similar to Svpbmt) which is
> implemented in many T-Head CPUs (C906, C910, etc.) and utilizes bits
> in PTEs that are marked as reserved. QEMU maintainers prefer to not
> implement XTheadMaee, so we need give kernels a mechanism to identify
> if XTheadMaee is available in a system or not. And this patch introduces
> this mechanism in QEMU in a way that's compatible with real HW
> (i.e., probing the th.sxstatus.MAEE bit).
>
> Further context can be found on the list:
> https://lists.gnu.org/archive/html/qemu-devel/2024-02/msg00775.html
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> ---
>   target/riscv/cpu.c       |  1 +
>   target/riscv/cpu.h       |  3 ++
>   target/riscv/meson.build |  1 +
>   target/riscv/th_csr.c    | 78 ++++++++++++++++++++++++++++++++++++++++
>   4 files changed, 83 insertions(+)
>   create mode 100644 target/riscv/th_csr.c
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 36e3e5fdaf..b82ba95ae6 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -545,6 +545,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)
>       cpu->cfg.mvendorid = THEAD_VENDOR_ID;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(cpu, VM_1_10_SV39);
> +    th_register_custom_csrs(cpu);
>   #endif
>   
>       /* inherited from parent obj via riscv_cpu_init() */
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 3b1a02b944..c9f8f06751 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -824,4 +824,7 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
>   uint8_t satp_mode_max_from_map(uint32_t map);
>   const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
>   
> +/* Implemented in th_csr.c */
> +void th_register_custom_csrs(RISCVCPU *cpu);
> +
>   #endif /* RISCV_CPU_H */
> diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> index a5e0734e7f..a4bd61e52a 100644
> --- a/target/riscv/meson.build
> +++ b/target/riscv/meson.build
> @@ -33,6 +33,7 @@ riscv_system_ss.add(files(
>     'monitor.c',
>     'machine.c',
>     'pmu.c',
> +  'th_csr.c',
>     'time_helper.c',
>     'riscv-qmp-cmds.c',
>   ))
> diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
> new file mode 100644
> index 0000000000..66d260cabd
> --- /dev/null
> +++ b/target/riscv/th_csr.c
> @@ -0,0 +1,78 @@
> +/*
> + * T-Head-specific CSRs.
> + *
> + * Copyright (c) 2024 VRULL GmbH
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * 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"
> +#include "cpu.h"
> +#include "cpu_vendorid.h"
> +
> +#define CSR_TH_SXSTATUS 0x5c0
> +
> +/* TH_SXSTATUS bits */
> +#define TH_SXSTATUS_UCME        BIT(16)
> +#define TH_SXSTATUS_MAEE        BIT(21)
> +#define TH_SXSTATUS_THEADISAEE  BIT(22)
> +
> +typedef struct {
> +    int csrno;
> +    int (*insertion_test)(RISCVCPU *cpu);
> +    riscv_csr_operations csr_ops;
> +} riscv_csr;
> +
> +static RISCVException s_mode_csr(CPURISCVState *env, int csrno)
> +{
> +    if (env->debugger)
> +        return RISCV_EXCP_NONE;
> +
> +    if (env->priv >= PRV_S)
> +        return RISCV_EXCP_NONE;
This will be checked by riscv_csrrw_check.
> +
> +    return RISCV_EXCP_ILLEGAL_INST;
> +}
Insteadly, reuse the smode in csr.c, where it checks iscv_has_ext(env, RVS).
> +
> +static int test_thead_mvendorid(RISCVCPU *cpu)
> +{
> +    if (cpu->cfg.mvendorid != THEAD_VENDOR_ID)
> +        return -1;
> +    return 0;
> +}
> +
> +static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
> +                                       target_ulong *val)
> +{
> +    /* We don't set MAEE here, because QEMU does not implement MAEE. */
> +    *val = TH_SXSTATUS_UCME | TH_SXSTATUS_THEADISAEE;
> +    return RISCV_EXCP_NONE;
> +}
> +
> +static riscv_csr th_csr_list[] = {
> +    {
> +        .csrno = CSR_TH_SXSTATUS,
> +        .insertion_test = test_thead_mvendorid,
> +        .csr_ops = { "th.sxstatus", s_mode_csr, read_th_sxstatus }
> +    }
> +};
> +
> +void th_register_custom_csrs(RISCVCPU *cpu)
> +{
> +    for (size_t i = 0; i < ARRAY_SIZE(th_csr_list); i++) {
> +        int csrno = th_csr_list[i].csrno;
> +        riscv_csr_operations *csr_ops = &th_csr_list[i].csr_ops;
> +        if (!th_csr_list[i].insertion_test(cpu))
> +            riscv_set_csr_ops(csrno, csr_ops);
> +    }
> +}

Otherwise,

Reviewed-by: LIU Zhiwei <zhiwe_liu@linux.alibaba.com>

Zhiwei



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] riscv: thead: Add th.sxstatus CSR emulation
  2024-04-05  1:36 ` LIU Zhiwei
@ 2024-04-17 22:54   ` Christoph Müllner
  0 siblings, 0 replies; 3+ messages in thread
From: Christoph Müllner @ 2024-04-17 22:54 UTC (permalink / raw)
  To: LIU Zhiwei
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Cooper Qu,
	Huang Tao, Conor Dooley, Andrew Jones, Daniel Henrique Barboza,
	Vivian Wang, Qingfang Deng, Alexandre Ghiti, Weiwei Li

On Fri, Apr 5, 2024 at 3:36 AM LIU Zhiwei <zhiwei_liu@linux.alibaba.com> wrote:
>
>
> On 2024/3/29 20:04, Christoph Müllner wrote:
> > The th.sxstatus CSR can be used to identify available custom extension
> > on T-Head CPUs. The CSR is documented here:
> >    https://github.com/T-head-Semi/thead-extension-spec/pull/46
> >
> > An important property of this patch is, that the th.sxstatus MAEE field
> > is not set (indicating that XTheadMaee is not available).
> > XTheadMaee is a memory attribute extension (similar to Svpbmt) which is
> > implemented in many T-Head CPUs (C906, C910, etc.) and utilizes bits
> > in PTEs that are marked as reserved. QEMU maintainers prefer to not
> > implement XTheadMaee, so we need give kernels a mechanism to identify
> > if XTheadMaee is available in a system or not. And this patch introduces
> > this mechanism in QEMU in a way that's compatible with real HW
> > (i.e., probing the th.sxstatus.MAEE bit).
> >
> > Further context can be found on the list:
> > https://lists.gnu.org/archive/html/qemu-devel/2024-02/msg00775.html
> >
> > Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> > ---
> >   target/riscv/cpu.c       |  1 +
> >   target/riscv/cpu.h       |  3 ++
> >   target/riscv/meson.build |  1 +
> >   target/riscv/th_csr.c    | 78 ++++++++++++++++++++++++++++++++++++++++
> >   4 files changed, 83 insertions(+)
> >   create mode 100644 target/riscv/th_csr.c
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 36e3e5fdaf..b82ba95ae6 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -545,6 +545,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)
> >       cpu->cfg.mvendorid = THEAD_VENDOR_ID;
> >   #ifndef CONFIG_USER_ONLY
> >       set_satp_mode_max_supported(cpu, VM_1_10_SV39);
> > +    th_register_custom_csrs(cpu);
> >   #endif
> >
> >       /* inherited from parent obj via riscv_cpu_init() */
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 3b1a02b944..c9f8f06751 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -824,4 +824,7 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
> >   uint8_t satp_mode_max_from_map(uint32_t map);
> >   const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
> >
> > +/* Implemented in th_csr.c */
> > +void th_register_custom_csrs(RISCVCPU *cpu);
> > +
> >   #endif /* RISCV_CPU_H */
> > diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> > index a5e0734e7f..a4bd61e52a 100644
> > --- a/target/riscv/meson.build
> > +++ b/target/riscv/meson.build
> > @@ -33,6 +33,7 @@ riscv_system_ss.add(files(
> >     'monitor.c',
> >     'machine.c',
> >     'pmu.c',
> > +  'th_csr.c',
> >     'time_helper.c',
> >     'riscv-qmp-cmds.c',
> >   ))
> > diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
> > new file mode 100644
> > index 0000000000..66d260cabd
> > --- /dev/null
> > +++ b/target/riscv/th_csr.c
> > @@ -0,0 +1,78 @@
> > +/*
> > + * T-Head-specific CSRs.
> > + *
> > + * Copyright (c) 2024 VRULL GmbH
> > + *
> > + * This program is free software; you can redistribute it and/or modify it
> > + * under the terms and conditions of the GNU General Public License,
> > + * 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"
> > +#include "cpu.h"
> > +#include "cpu_vendorid.h"
> > +
> > +#define CSR_TH_SXSTATUS 0x5c0
> > +
> > +/* TH_SXSTATUS bits */
> > +#define TH_SXSTATUS_UCME        BIT(16)
> > +#define TH_SXSTATUS_MAEE        BIT(21)
> > +#define TH_SXSTATUS_THEADISAEE  BIT(22)
> > +
> > +typedef struct {
> > +    int csrno;
> > +    int (*insertion_test)(RISCVCPU *cpu);
> > +    riscv_csr_operations csr_ops;
> > +} riscv_csr;
> > +
> > +static RISCVException s_mode_csr(CPURISCVState *env, int csrno)
> > +{
> > +    if (env->debugger)
> > +        return RISCV_EXCP_NONE;
> > +
> > +    if (env->priv >= PRV_S)
> > +        return RISCV_EXCP_NONE;
> This will be checked by riscv_csrrw_check.

Indeed! I missed that.

> > +
> > +    return RISCV_EXCP_ILLEGAL_INST;
> > +}
> Insteadly, reuse the smode in csr.c, where it checks iscv_has_ext(env, RVS).

I saw that but preferred to not touch csr.c at all.
But you are right, removing the "static" from smode() is much better than
a useless duplication.

Thanks!

> > +
> > +static int test_thead_mvendorid(RISCVCPU *cpu)
> > +{
> > +    if (cpu->cfg.mvendorid != THEAD_VENDOR_ID)
> > +        return -1;
> > +    return 0;
> > +}
> > +
> > +static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
> > +                                       target_ulong *val)
> > +{
> > +    /* We don't set MAEE here, because QEMU does not implement MAEE. */
> > +    *val = TH_SXSTATUS_UCME | TH_SXSTATUS_THEADISAEE;
> > +    return RISCV_EXCP_NONE;
> > +}
> > +
> > +static riscv_csr th_csr_list[] = {
> > +    {
> > +        .csrno = CSR_TH_SXSTATUS,
> > +        .insertion_test = test_thead_mvendorid,
> > +        .csr_ops = { "th.sxstatus", s_mode_csr, read_th_sxstatus }
> > +    }
> > +};
> > +
> > +void th_register_custom_csrs(RISCVCPU *cpu)
> > +{
> > +    for (size_t i = 0; i < ARRAY_SIZE(th_csr_list); i++) {
> > +        int csrno = th_csr_list[i].csrno;
> > +        riscv_csr_operations *csr_ops = &th_csr_list[i].csr_ops;
> > +        if (!th_csr_list[i].insertion_test(cpu))
> > +            riscv_set_csr_ops(csrno, csr_ops);
> > +    }
> > +}
>
> Otherwise,
>
> Reviewed-by: LIU Zhiwei <zhiwe_liu@linux.alibaba.com>
>
> Zhiwei
>


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-04-17 22:55 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-29 12:04 [PATCH v2] riscv: thead: Add th.sxstatus CSR emulation Christoph Müllner
2024-04-05  1:36 ` LIU Zhiwei
2024-04-17 22:54   ` Christoph Müllner

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).