diff mbox series

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

Message ID 20210409074857.166082-7-zhiwei_liu@c-sky.com
State New
Headers show
Series RISC-V: support clic v0.9 specification | expand

Commit Message

LIU Zhiwei April 9, 2021, 7:48 a.m. UTC
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>
---
 target/riscv/csr.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

Comments

Frank Chang June 27, 2021, 8:59 a.m. UTC | #1
LIU Zhiwei <zhiwei_liu@c-sky.com> 於 2021年4月9日 週五 下午3:51寫道:

> 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>
> ---
>  target/riscv/csr.c | 22 ++++++++++++++++++++--
>  1 file changed, 20 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index f6c84b9fe4..39ff72041a 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -637,9 +637,18 @@ static int read_mtvec(CPURISCVState *env, int csrno,
> target_ulong *val)
>
>  static int write_mtvec(CPURISCVState *env, int csrno, target_ulong val)
>  {
> -    /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
> +    /*
> +     * bits [1:0] encode mode; 0 = direct, 1 = vectored, 3 = CLIC,
> +     * others reserved
> +     */
>      if ((val & 3) < 2) {
>          env->mtvec = val;
> +    } else if ((val & 1) && 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.
> +         */
> +        env->mtvec = ((val & ~0x3f) << 6) | (0b000011);
>

Why do we need to left-shift the value 6 bits here?


>      } else {
>          qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not
> supported\n");
>      }
> @@ -837,9 +846,18 @@ static int read_stvec(CPURISCVState *env, int csrno,
> target_ulong *val)
>
>  static int write_stvec(CPURISCVState *env, int csrno, target_ulong val)
>  {
> -    /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
> +    /*
> +     * bits [1:0] encode mode; 0 = direct, 1 = vectored, 3 = CLIC,
> +     * others reserved
> +     */
>      if ((val & 3) < 2) {
>          env->stvec = val;
> +    } else if ((val & 1) && 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.
> +         */
> +        env->stvec = ((val & ~0x3f) << 6) | (0b000011);
>

Same here, why do we need to left-shift the value 6 bits here?

Also, CLIC v0.8 spec[1] doesn't include the change for stvec.
I'm not sure if it's the same as v0.9 to check stvec
when the interrupt is delegated to S-mode in CLIC-mode.

[1] https://github.com/riscv/riscv-fast-interrupt/blob/74f86c3858/clic.adoc

Regards,
Frank Chang

     } else {
>          qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not
> supported\n");
>      }
> --
> 2.25.1
>
>
>
Frank Chang July 10, 2021, 3:04 p.m. UTC | #2
LIU Zhiwei <zhiwei_liu@c-sky.com> 於 2021年4月9日 週五 下午3:51寫道:

> 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>
> ---
>  target/riscv/csr.c | 22 ++++++++++++++++++++--
>  1 file changed, 20 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index f6c84b9fe4..39ff72041a 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -637,9 +637,18 @@ static int read_mtvec(CPURISCVState *env, int csrno,
> target_ulong *val)
>
>  static int write_mtvec(CPURISCVState *env, int csrno, target_ulong val)
>  {
> -    /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
> +    /*
> +     * bits [1:0] encode mode; 0 = direct, 1 = vectored, 3 = CLIC,
> +     * others reserved
> +     */
>      if ((val & 3) < 2) {
>          env->mtvec = val;
>

We might need to zero new fields in mcause when set back to basic mode:

Section 4.7:
When basic mode is written to xtvec,
the new xcause state fields (mhinv and mpil) are zeroed.
The other new xcause fields, mpp and mpie, appear as zero in the xcause CSR
but the corresponding state bits in the mstatus register are not cleared.


> +    } else if ((val & 1) && 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.
> +         */
> +        env->mtvec = ((val & ~0x3f) << 6) | (0b000011);
>      } else {
>          qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not
> supported\n");
>      }
> @@ -837,9 +846,18 @@ static int read_stvec(CPURISCVState *env, int csrno,
> target_ulong *val)
>
>  static int write_stvec(CPURISCVState *env, int csrno, target_ulong val)
>  {
> -    /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
> +    /*
> +     * bits [1:0] encode mode; 0 = direct, 1 = vectored, 3 = CLIC,
> +     * others reserved
> +     */
>      if ((val & 3) < 2) {
>          env->stvec = val;
>

Same to write_mtvec()

Regards,
Frank Chang


> +    } else if ((val & 1) && 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.
> +         */
> +        env->stvec = ((val & ~0x3f) << 6) | (0b000011);
>      } else {
>          qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not
> supported\n");
>      }
> --
> 2.25.1
>
>
>
diff mbox series

Patch

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index f6c84b9fe4..39ff72041a 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -637,9 +637,18 @@  static int read_mtvec(CPURISCVState *env, int csrno, target_ulong *val)
 
 static int write_mtvec(CPURISCVState *env, int csrno, target_ulong val)
 {
-    /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
+    /*
+     * bits [1:0] encode mode; 0 = direct, 1 = vectored, 3 = CLIC,
+     * others reserved
+     */
     if ((val & 3) < 2) {
         env->mtvec = val;
+    } else if ((val & 1) && 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.
+         */
+        env->mtvec = ((val & ~0x3f) << 6) | (0b000011);
     } else {
         qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
     }
@@ -837,9 +846,18 @@  static int read_stvec(CPURISCVState *env, int csrno, target_ulong *val)
 
 static int write_stvec(CPURISCVState *env, int csrno, target_ulong val)
 {
-    /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
+    /*
+     * bits [1:0] encode mode; 0 = direct, 1 = vectored, 3 = CLIC,
+     * others reserved
+     */
     if ((val & 3) < 2) {
         env->stvec = val;
+    } else if ((val & 1) && 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.
+         */
+        env->stvec = ((val & ~0x3f) << 6) | (0b000011);
     } else {
         qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
     }