[PATCH 09/10] target/loongarch: loongarch CPU supoort avec irqs

Song Gao posted 10 patches 5 months, 1 week ago
Maintainers: Paolo Bonzini <pbonzini@redhat.com>, Song Gao <gaosong@loongson.cn>, Bibo Mao <maobibo@loongson.cn>, Jiaxun Yang <jiaxun.yang@flygoat.com>
There is a newer version of this series
[PATCH 09/10] target/loongarch: loongarch CPU supoort avec irqs
Posted by Song Gao 5 months, 1 week ago
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
 target/loongarch/cpu-csr.h |  1 +
 target/loongarch/cpu.c     | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index 0834e91f30..83f6cb081a 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -39,6 +39,7 @@ FIELD(CSR_ECFG, VS, 16, 3)
 
 #define LOONGARCH_CSR_ESTAT          0x5 /* Exception status */
 FIELD(CSR_ESTAT, IS, 0, 13)
+FIELD(CSR_ESTAT, MSGINT, 14, 1)
 FIELD(CSR_ESTAT, ECODE, 16, 6)
 FIELD(CSR_ESTAT, ESUBCODE, 22, 9)
 
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index bde9f917fc..207d11266f 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -127,6 +127,23 @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level)
         return;
     }
 
+    /* do INTC_AVEC irqs */
+    if (irq == INT_AVEC) {
+        for (int i = 256; i >= 0; i--) {
+            if (test_bit(i, &(env->CSR_MSGIS[i / 64]))) {
+                env->CSR_MSGIR = FIELD_DP64(env->CSR_MSGIR, CSR_MSGIR, INTNUM, i);
+                env->CSR_MSGIR = FIELD_DP64(env->CSR_MSGIR, CSR_MSGIR, ACTIVE, 0);
+                env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, MSGINT, 1);
+                cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+                clear_bit(i, &(env->CSR_MSGIS[i / 64]));
+            }
+        }
+    } else {
+       env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, MSGINT, 0);
+       env->CSR_MSGIR = FIELD_DP64(env->CSR_MSGIR, CSR_MSGIR, ACTIVE, 1);
+       return;
+    }
+
     if (kvm_enabled()) {
         kvm_loongarch_set_interrupt(cpu, irq, level);
     } else if (tcg_enabled()) {
-- 
2.34.1
Re: [PATCH 09/10] target/loongarch: loongarch CPU supoort avec irqs
Posted by Bibo Mao 5 months, 1 week ago

On 2025/6/9 下午6:48, Song Gao wrote:
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
>   target/loongarch/cpu-csr.h |  1 +
>   target/loongarch/cpu.c     | 17 +++++++++++++++++
>   2 files changed, 18 insertions(+)
> 
> diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
> index 0834e91f30..83f6cb081a 100644
> --- a/target/loongarch/cpu-csr.h
> +++ b/target/loongarch/cpu-csr.h
> @@ -39,6 +39,7 @@ FIELD(CSR_ECFG, VS, 16, 3)
>   
>   #define LOONGARCH_CSR_ESTAT          0x5 /* Exception status */
>   FIELD(CSR_ESTAT, IS, 0, 13)
> +FIELD(CSR_ESTAT, MSGINT, 14, 1)
>   FIELD(CSR_ESTAT, ECODE, 16, 6)
>   FIELD(CSR_ESTAT, ESUBCODE, 22, 9)
>   
> diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
> index bde9f917fc..207d11266f 100644
> --- a/target/loongarch/cpu.c
> +++ b/target/loongarch/cpu.c
> @@ -127,6 +127,23 @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level)
>           return;
>       }
>   
> +    /* do INTC_AVEC irqs */
> +    if (irq == INT_AVEC) {
> +        for (int i = 256; i >= 0; i--) {
> +            if (test_bit(i, &(env->CSR_MSGIS[i / 64]))) {
> +                env->CSR_MSGIR = FIELD_DP64(env->CSR_MSGIR, CSR_MSGIR, INTNUM, i);
> +                env->CSR_MSGIR = FIELD_DP64(env->CSR_MSGIR, CSR_MSGIR, ACTIVE, 0);
Modification with CSR_MSGIR should be moved to function avec_set_irq(), 
or there is extra sub_irq parameter in loongarch_cpu_set_irq()

> +                env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, MSGINT, 1);
> +                cpu_interrupt(cs, CPU_INTERRUPT_HARD);
it is unnecessary and there is such code in tcg_enabled() loop sentence.

> +                clear_bit(i, &(env->CSR_MSGIS[i / 64]));
CSR_MSGIS is unnecessary, it is pure software state.

> +            }
> +        }
> +    } else {
> +       env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, MSGINT, 0);
> +       env->CSR_MSGIR = FIELD_DP64(env->CSR_MSGIR, CSR_MSGIR, ACTIVE, 1);
> +       return;
> +    }
what is the use about else {} sentences? Does it change interrupt logic 
if AVEC is disabled?

Also I think it should be removed to the following (tcg_enabled().

Regards
Bibo Mao
> +
>       if (kvm_enabled()) {
>           kvm_loongarch_set_interrupt(cpu, irq, level);
>       } else if (tcg_enabled()) {
>