diff mbox series

[06/11,v2] target/riscv: Update CSR xtvec in CLIC mode

Message ID 20240819160742.27586-10-Ian.Brockbank@cirrus.com (mailing list archive)
State New, archived
Headers show
Series RISC-V: support CLIC v0.9 specification | expand

Commit Message

Ian Brockbank Aug. 19, 2024, 4:02 p.m. UTC
From: Ian Brockbank <ian.brockbank@cirrus.com>

The new CLIC interrupt-handling mode is encoded as a new state in the
existing WARL xtvec register, where the low two bits of are 11.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Signed-off-by: Ian Brockbank <ian.brockbank@cirrus.com>
---
 target/riscv/cpu.h      |  2 ++
 target/riscv/cpu_bits.h |  2 ++
 target/riscv/csr.c      | 63 ++++++++++++++++++++++++++++++++++++++---
 3 files changed, 63 insertions(+), 4 deletions(-)

--
2.46.0.windows.1
This message and any attachments may contain privileged and confidential information that is intended solely for the person(s) to whom it is addressed. If you are not an intended recipient you must not: read; copy; distribute; discuss; take any action in or make any reliance upon the contents of this message; nor open or read any attachment. If you have received this message in error, please notify us as soon as possible on the following telephone number and destroy this message including any attachments. Thank you. Cirrus Logic International (UK) Ltd and Cirrus Logic International Semiconductor Ltd are companies registered in Scotland, with registered numbers SC089839 and SC495735 respectively. Our registered office is at 7B Nightingale Way, Quartermile, Edinburgh, EH3 9EG, UK. Tel: +44 (0)131 272 7000. www.cirrus.com

Comments

Alistair Francis Sept. 6, 2024, 3:02 a.m. UTC | #1
On Tue, Aug 20, 2024 at 2:15 AM Ian Brockbank <Ian.Brockbank@cirrus.com> wrote:
>
> From: Ian Brockbank <ian.brockbank@cirrus.com>
>
> The new CLIC interrupt-handling mode is encoded as a new state in the
> existing WARL xtvec register, where the low two bits of are 11.
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> Signed-off-by: Ian Brockbank <ian.brockbank@cirrus.com>
> ---
>  target/riscv/cpu.h      |  2 ++
>  target/riscv/cpu_bits.h |  2 ++
>  target/riscv/csr.c      | 63 ++++++++++++++++++++++++++++++++++++++---
>  3 files changed, 63 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 12aa8cf6b1..05a014db03 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -283,11 +283,13 @@ struct CPUArchState {
>      target_ulong medeleg;
>
>      target_ulong stvec;
> +    target_ulong stvt; /* clic-spec */
>      target_ulong sepc;
>      target_ulong scause;
>      target_ulong sintthresh; /* clic-spec */
>
>      target_ulong mtvec;
> +    target_ulong mtvt; /* clic-spec */
>      target_ulong mepc;
>      target_ulong mcause;
>      target_ulong mtval;  /* since: priv-1.10.0 */
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index 0ed44ec0a8..279a6f889b 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -153,6 +153,7 @@
>  #define CSR_MIE             0x304
>  #define CSR_MTVEC           0x305
>  #define CSR_MCOUNTEREN      0x306
> +#define CSR_MTVT            0x307 /* clic-spec-draft */
>
>  /* 32-bit only */
>  #define CSR_MSTATUSH        0x310
> @@ -192,6 +193,7 @@
>  #define CSR_SIE             0x104
>  #define CSR_STVEC           0x105
>  #define CSR_SCOUNTEREN      0x106
> +#define CSR_STVT            0x107 /* clic-spec-draft */
>
>  /* Supervisor Configuration CSRs */
>  #define CSR_SENVCFG         0x10A
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 276ef7856e..be0071fd25 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -2170,9 +2170,23 @@ static RISCVException read_mtvec(CPURISCVState *env, int csrno,
>  static RISCVException write_mtvec(CPURISCVState *env, int csrno,
>                                    target_ulong val)
>  {
> -    /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
> -    if ((val & 3) < 2) {
> +    /*
> +     * bits [1:0] encode mode; 0 = direct, 1 = vectored, 3 = CLIC,
> +     * others reserved

You aren't checking if the CLIC extension (smclic) is enabled though.

You need to guard these changes with a smclic extension check

Alistair

> +     */
> +    target_ulong mode = get_field(val, XTVEC_MODE);
> +    target_ulong fullmode = val & XTVEC_FULL_MODE;
> +    if (mode <= XTVEC_CLINT_VECTORED) {
>          env->mtvec = val;
> +    } else if (XTVEC_CLIC == fullmode && env->clic) {
> +        /*
> +         * CLIC mode hardwires xtvec bits 2-5 to zero.
> +         * Layout:
> +         *   XLEN-1:6   base (WARL)
> +         *   5:2        submode (WARL)  - 0000 for CLIC
> +         *   1:0        mode (WARL)     - 11 for CLIC
> +         */
> +        env->mtvec = (val & XTVEC_NBASE) | XTVEC_CLIC;
>      } else {
>          qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
>      }
> @@ -2271,6 +2285,18 @@ static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
>      return RISCV_EXCP_NONE;
>  }
>
> +static int read_mtvt(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    *val = env->mtvt;
> +    return RISCV_EXCP_NONE;
> +}
> +
> +static int write_mtvt(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +    env->mtvt = val & XTVEC_NBASE;
> +    return RISCV_EXCP_NONE;
> +}
> +
>  /* Machine Trap Handling */
>  static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno,
>                                           Int128 *val)
> @@ -3122,9 +3148,24 @@ static RISCVException read_stvec(CPURISCVState *env, int csrno,
>  static RISCVException write_stvec(CPURISCVState *env, int csrno,
>                                    target_ulong val)
>  {
> -    /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
> -    if ((val & 3) < 2) {
> +    /*
> +     * bits [1:0] encode mode; 0 = direct, 1 = vectored, 3 = CLIC,
> +     * others reserved
> +     */
> +    target_ulong mode = val & XTVEC_MODE;
> +    target_ulong fullmode = val & XTVEC_FULL_MODE;
> +    if (mode <= XTVEC_CLINT_VECTORED) {
>          env->stvec = val;
> +    } else if (XTVEC_CLIC == fullmode && env->clic) {
> +        /*
> +         * If only CLIC mode is supported, writes to bit 1 are also ignored and
> +         * it is always set to one. CLIC mode hardwires xtvec bits 2-5 to zero.
> +         * Layout:
> +         *   XLEN-1:6   base (WARL)
> +         *   5:2        submode (WARL)  - 0000 for CLIC
> +         *   1:0        mode (WARL)     - 11 for CLIC
> +         */
> +        env->stvec = (val & XTVEC_NBASE) | XTVEC_CLIC;
>      } else {
>          qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
>      }
> @@ -3149,6 +3190,18 @@ static RISCVException write_scounteren(CPURISCVState *env, int csrno,
>      return RISCV_EXCP_NONE;
>  }
>
> +static int read_stvt(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    *val = env->stvt;
> +    return RISCV_EXCP_NONE;
> +}
> +
> +static int write_stvt(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +    env->stvt = val & XTVEC_NBASE;
> +    return RISCV_EXCP_NONE;
> +}
> +
>  /* Supervisor Trap Handling */
>  static RISCVException read_sscratch_i128(CPURISCVState *env, int csrno,
>                                           Int128 *val)
> @@ -5666,11 +5719,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>                               write_mhpmcounterh                         },
>
>      /* Machine Mode Core Level Interrupt Controller */
> +    [CSR_MTVT]           = { "mtvt",       clic,  read_mtvt, write_mtvt },
>      [CSR_MINTSTATUS]     = { "mintstatus", clic,  read_mintstatus       },
>      [CSR_MINTTHRESH]     = { "mintthresh", clic,  read_mintthresh,
>                               write_mintthresh },
>
>      /* Supervisor Mode Core Level Interrupt Controller */
> +    [CSR_STVT]           = { "stvt",       clic,  read_stvt, write_stvt },
>      [CSR_SINTSTATUS]     = { "sintstatus", clic,  read_sintstatus       },
>      [CSR_SINTTHRESH]     = { "sintthresh", clic,  read_sintthresh,
>                               write_sintthresh },
> --
> 2.46.0.windows.1
> This message and any attachments may contain privileged and confidential information that is intended solely for the person(s) to whom it is addressed. If you are not an intended recipient you must not: read; copy; distribute; discuss; take any action in or make any reliance upon the contents of this message; nor open or read any attachment. If you have received this message in error, please notify us as soon as possible on the following telephone number and destroy this message including any attachments. Thank you. Cirrus Logic International (UK) Ltd and Cirrus Logic International Semiconductor Ltd are companies registered in Scotland, with registered numbers SC089839 and SC495735 respectively. Our registered office is at 7B Nightingale Way, Quartermile, Edinburgh, EH3 9EG, UK. Tel: +44 (0)131 272 7000. www.cirrus.com
>
diff mbox series

Patch

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 12aa8cf6b1..05a014db03 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -283,11 +283,13 @@  struct CPUArchState {
     target_ulong medeleg;

     target_ulong stvec;
+    target_ulong stvt; /* clic-spec */
     target_ulong sepc;
     target_ulong scause;
     target_ulong sintthresh; /* clic-spec */

     target_ulong mtvec;
+    target_ulong mtvt; /* clic-spec */
     target_ulong mepc;
     target_ulong mcause;
     target_ulong mtval;  /* since: priv-1.10.0 */
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 0ed44ec0a8..279a6f889b 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -153,6 +153,7 @@ 
 #define CSR_MIE             0x304
 #define CSR_MTVEC           0x305
 #define CSR_MCOUNTEREN      0x306
+#define CSR_MTVT            0x307 /* clic-spec-draft */

 /* 32-bit only */
 #define CSR_MSTATUSH        0x310
@@ -192,6 +193,7 @@ 
 #define CSR_SIE             0x104
 #define CSR_STVEC           0x105
 #define CSR_SCOUNTEREN      0x106
+#define CSR_STVT            0x107 /* clic-spec-draft */

 /* Supervisor Configuration CSRs */
 #define CSR_SENVCFG         0x10A
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 276ef7856e..be0071fd25 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -2170,9 +2170,23 @@  static RISCVException read_mtvec(CPURISCVState *env, int csrno,
 static RISCVException write_mtvec(CPURISCVState *env, int csrno,
                                   target_ulong val)
 {
-    /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
-    if ((val & 3) < 2) {
+    /*
+     * bits [1:0] encode mode; 0 = direct, 1 = vectored, 3 = CLIC,
+     * others reserved
+     */
+    target_ulong mode = get_field(val, XTVEC_MODE);
+    target_ulong fullmode = val & XTVEC_FULL_MODE;
+    if (mode <= XTVEC_CLINT_VECTORED) {
         env->mtvec = val;
+    } else if (XTVEC_CLIC == fullmode && env->clic) {
+        /*
+         * CLIC mode hardwires xtvec bits 2-5 to zero.
+         * Layout:
+         *   XLEN-1:6   base (WARL)
+         *   5:2        submode (WARL)  - 0000 for CLIC
+         *   1:0        mode (WARL)     - 11 for CLIC
+         */
+        env->mtvec = (val & XTVEC_NBASE) | XTVEC_CLIC;
     } else {
         qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
     }
@@ -2271,6 +2285,18 @@  static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
     return RISCV_EXCP_NONE;
 }

+static int read_mtvt(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    *val = env->mtvt;
+    return RISCV_EXCP_NONE;
+}
+
+static int write_mtvt(CPURISCVState *env, int csrno, target_ulong val)
+{
+    env->mtvt = val & XTVEC_NBASE;
+    return RISCV_EXCP_NONE;
+}
+
 /* Machine Trap Handling */
 static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno,
                                          Int128 *val)
@@ -3122,9 +3148,24 @@  static RISCVException read_stvec(CPURISCVState *env, int csrno,
 static RISCVException write_stvec(CPURISCVState *env, int csrno,
                                   target_ulong val)
 {
-    /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
-    if ((val & 3) < 2) {
+    /*
+     * bits [1:0] encode mode; 0 = direct, 1 = vectored, 3 = CLIC,
+     * others reserved
+     */
+    target_ulong mode = val & XTVEC_MODE;
+    target_ulong fullmode = val & XTVEC_FULL_MODE;
+    if (mode <= XTVEC_CLINT_VECTORED) {
         env->stvec = val;
+    } else if (XTVEC_CLIC == fullmode && env->clic) {
+        /*
+         * If only CLIC mode is supported, writes to bit 1 are also ignored and
+         * it is always set to one. CLIC mode hardwires xtvec bits 2-5 to zero.
+         * Layout:
+         *   XLEN-1:6   base (WARL)
+         *   5:2        submode (WARL)  - 0000 for CLIC
+         *   1:0        mode (WARL)     - 11 for CLIC
+         */
+        env->stvec = (val & XTVEC_NBASE) | XTVEC_CLIC;
     } else {
         qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
     }
@@ -3149,6 +3190,18 @@  static RISCVException write_scounteren(CPURISCVState *env, int csrno,
     return RISCV_EXCP_NONE;
 }

+static int read_stvt(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    *val = env->stvt;
+    return RISCV_EXCP_NONE;
+}
+
+static int write_stvt(CPURISCVState *env, int csrno, target_ulong val)
+{
+    env->stvt = val & XTVEC_NBASE;
+    return RISCV_EXCP_NONE;
+}
+
 /* Supervisor Trap Handling */
 static RISCVException read_sscratch_i128(CPURISCVState *env, int csrno,
                                          Int128 *val)
@@ -5666,11 +5719,13 @@  riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
                              write_mhpmcounterh                         },

     /* Machine Mode Core Level Interrupt Controller */
+    [CSR_MTVT]           = { "mtvt",       clic,  read_mtvt, write_mtvt },
     [CSR_MINTSTATUS]     = { "mintstatus", clic,  read_mintstatus       },
     [CSR_MINTTHRESH]     = { "mintthresh", clic,  read_mintthresh,
                              write_mintthresh },

     /* Supervisor Mode Core Level Interrupt Controller */
+    [CSR_STVT]           = { "stvt",       clic,  read_stvt, write_stvt },
     [CSR_SINTSTATUS]     = { "sintstatus", clic,  read_sintstatus       },
     [CSR_SINTTHRESH]     = { "sintthresh", clic,  read_sintthresh,
                              write_sintthresh },