Message ID | 20240221130823.677762-9-ruanjinjie@huawei.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | target/arm: Implement FEAT_NMI and FEAT_GICv3_NMI | expand |
On 2/21/24 03:08, Jinjie Ruan via wrote: > Add IS and FS bit in ISR_EL1 and handle the read according to whether the > NMI is IRQ or FIQ. > > Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> > --- > target/arm/cpu.h | 2 ++ > target/arm/helper.c | 9 +++++++++ > 2 files changed, 11 insertions(+) > > diff --git a/target/arm/cpu.h b/target/arm/cpu.h > index 051e589e19..e2d07e3312 100644 > --- a/target/arm/cpu.h > +++ b/target/arm/cpu.h > @@ -1476,6 +1476,8 @@ FIELD(CPTR_EL3, TCPAC, 31, 1) > #define CPSR_N (1U << 31) > #define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V) > #define CPSR_AIF (CPSR_A | CPSR_I | CPSR_F) > +#define ISR_FS (1U << 9) > +#define ISR_IS (1U << 10) > > #define CPSR_IT (CPSR_IT_0_1 | CPSR_IT_2_7) > #define CACHED_CPSR_BITS (CPSR_T | CPSR_AIF | CPSR_GE | CPSR_IT | CPSR_Q \ > diff --git a/target/arm/helper.c b/target/arm/helper.c > index 0bd7a87e51..62c8e5d611 100644 > --- a/target/arm/helper.c > +++ b/target/arm/helper.c > @@ -2022,6 +2022,10 @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri) > if (cs->interrupt_request & CPU_INTERRUPT_HARD) { > ret |= CPSR_I; > } > + > + if ((cs->interrupt_request & CPU_INTERRUPT_NMI) && env->nmi_is_irq) { > + ret |= ISR_IS; > + } > } > > if (hcr_el2 & HCR_FMO) { > @@ -2032,6 +2036,11 @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri) > if (cs->interrupt_request & CPU_INTERRUPT_FIQ) { > ret |= CPSR_F; > } > + > + if ((cs->interrupt_request & CPU_INTERRUPT_NMI) && > + (!env->nmi_is_irq)) { > + ret |= ISR_FS; > + } > } The external CPU_INTERRUPT_NMI will never signal FIQ. With CPU_INTERRUPT_NMI, both CPSR_I and ISR_IS must be set. Missing is the handling of HCRX_EL2.{VFNMI,VINMI} to signal vFIQ and vIRQ with superpriority. Unless I missed it, I don't see HCRX_EL2 adjusted for FEAT_NMI at all. r~
On 2024/2/22 5:36, Richard Henderson wrote: > On 2/21/24 03:08, Jinjie Ruan via wrote: >> Add IS and FS bit in ISR_EL1 and handle the read according to whether the >> NMI is IRQ or FIQ. >> >> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> >> --- >> target/arm/cpu.h | 2 ++ >> target/arm/helper.c | 9 +++++++++ >> 2 files changed, 11 insertions(+) >> >> diff --git a/target/arm/cpu.h b/target/arm/cpu.h >> index 051e589e19..e2d07e3312 100644 >> --- a/target/arm/cpu.h >> +++ b/target/arm/cpu.h >> @@ -1476,6 +1476,8 @@ FIELD(CPTR_EL3, TCPAC, 31, 1) >> #define CPSR_N (1U << 31) >> #define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V) >> #define CPSR_AIF (CPSR_A | CPSR_I | CPSR_F) >> +#define ISR_FS (1U << 9) >> +#define ISR_IS (1U << 10) >> #define CPSR_IT (CPSR_IT_0_1 | CPSR_IT_2_7) >> #define CACHED_CPSR_BITS (CPSR_T | CPSR_AIF | CPSR_GE | CPSR_IT | >> CPSR_Q \ >> diff --git a/target/arm/helper.c b/target/arm/helper.c >> index 0bd7a87e51..62c8e5d611 100644 >> --- a/target/arm/helper.c >> +++ b/target/arm/helper.c >> @@ -2022,6 +2022,10 @@ static uint64_t isr_read(CPUARMState *env, >> const ARMCPRegInfo *ri) >> if (cs->interrupt_request & CPU_INTERRUPT_HARD) { >> ret |= CPSR_I; >> } >> + >> + if ((cs->interrupt_request & CPU_INTERRUPT_NMI) && >> env->nmi_is_irq) { >> + ret |= ISR_IS; >> + } >> } >> if (hcr_el2 & HCR_FMO) { >> @@ -2032,6 +2036,11 @@ static uint64_t isr_read(CPUARMState *env, >> const ARMCPRegInfo *ri) >> if (cs->interrupt_request & CPU_INTERRUPT_FIQ) { >> ret |= CPSR_F; >> } >> + >> + if ((cs->interrupt_request & CPU_INTERRUPT_NMI) && >> + (!env->nmi_is_irq)) { >> + ret |= ISR_FS; >> + } >> } > > The external CPU_INTERRUPT_NMI will never signal FIQ. > > With CPU_INTERRUPT_NMI, both CPSR_I and ISR_IS must be set. Right! The IRQ and NMI signal are both set when it is a NMI. > > Missing is the handling of HCRX_EL2.{VFNMI,VINMI} to signal vFIQ and > vIRQ with superpriority. Unless I missed it, I don't see HCRX_EL2 > adjusted for FEAT_NMI at all. Sorry! The vNMI has not yet been implemented. The HCRX_EL2.TALLINT has yet been handled. > > > r~ >
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 051e589e19..e2d07e3312 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1476,6 +1476,8 @@ FIELD(CPTR_EL3, TCPAC, 31, 1) #define CPSR_N (1U << 31) #define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V) #define CPSR_AIF (CPSR_A | CPSR_I | CPSR_F) +#define ISR_FS (1U << 9) +#define ISR_IS (1U << 10) #define CPSR_IT (CPSR_IT_0_1 | CPSR_IT_2_7) #define CACHED_CPSR_BITS (CPSR_T | CPSR_AIF | CPSR_GE | CPSR_IT | CPSR_Q \ diff --git a/target/arm/helper.c b/target/arm/helper.c index 0bd7a87e51..62c8e5d611 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -2022,6 +2022,10 @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri) if (cs->interrupt_request & CPU_INTERRUPT_HARD) { ret |= CPSR_I; } + + if ((cs->interrupt_request & CPU_INTERRUPT_NMI) && env->nmi_is_irq) { + ret |= ISR_IS; + } } if (hcr_el2 & HCR_FMO) { @@ -2032,6 +2036,11 @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri) if (cs->interrupt_request & CPU_INTERRUPT_FIQ) { ret |= CPSR_F; } + + if ((cs->interrupt_request & CPU_INTERRUPT_NMI) && + (!env->nmi_is_irq)) { + ret |= ISR_FS; + } } if (hcr_el2 & HCR_AMO) {
Add IS and FS bit in ISR_EL1 and handle the read according to whether the NMI is IRQ or FIQ. Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> --- target/arm/cpu.h | 2 ++ target/arm/helper.c | 9 +++++++++ 2 files changed, 11 insertions(+)