Hi,
   thank you for your response.
   As you say

>  "
> *End of interrupt handling is entirely dependent on what the*
> *guest hardware being emulated is. Usually the guest software*
> *will indicate "interrupt handled" back to the interrupt*
> *controller (perhaps by writing a register; depends on the*
> *interrupt controller), and the interrupt controller will*
> *then look at what the next highest priority pending interrupt*
> *is and signal that back to the CPU, or do nothing if there's*
> *no new interrupt. So the second interrupt will automatically*
> *be taken and handled once the first one has finished,*
> *as a result of this interrupt controller and guest OS**interaction*."

I agree with that. I has try some method, But Still have some problems.

Q1:
My guest(target) cpu seem don't have a  * "interrupt handled" , *And I
don't know How/When to program the  "* interrupt controller"   *to check
the second interrupt when the first over.

Q2:
Also I found the new problem(maybe bug) , when first interrupt  not over,
the second interrupt may occure, this case Interrupt nesting ,if I check
Interrupt flag in the code,the second interrupt losed。

I don't know the interrupt mechanism of qemu very well. If you have any
suggestions, I am very happy to receive them.

this is my code:

/* set irq for device */
> static void stm8_cpu_set_irq(void *opaque, int irq, int level)
> {
>     //printf("%s\n",__func__);
>     STM8CPU *cpu = opaque;
>     CPUSTM8State *env = &cpu->env;
>     CPUState *cs = CPU(cpu);
>     uint64_t mask = (1ull << irq);
>
>     //printf("irq:%d , level:%d\n",irq,level);
>     if (level) {
>         env->intsrc |= mask;
>         cpu_interrupt(cs, CPU_INTERRUPT_HARD);
>     } else {
>         env->intsrc &= ~mask;
>         if (env->intsrc == 0) {
>             cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
>         }
>     }
> }
>

bool stm8_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
> {
>     //printf("%s\n",__func__);
>     CPUClass *cpu_cc = CPU_GET_CLASS(cs);
>     STM8CPU *cpu = STM8_CPU(cs);
>     CPUSTM8State *env = &cpu->env;
>     int idx = -1;
>
>     /* Check interrupt */
>     if (!cpu_interrupts_enabled(env)){
>         qemu_log_mask(LOG_GUEST_ERROR,"[CPU] cpu_interrupts_enabled =
> false.\n");
>         //return false;
>     }
>     if (interrupt_request & CPU_INTERRUPT_RESET)
>     {
>         idx = 0;
>         cs->interrupt_request &= ~CPU_INTERRUPT_RESET;
>     }
>     if (interrupt_request & CPU_INTERRUPT_HARD) {
>         if(env->intsrc != 0){
>             idx = ctz32(env->intsrc);
>             env->intsrc &= ~(1<<idx);
>
>             cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
>             /* Map interrupt */
>             idx = EXCP_INT(idx);
>         }
>     }
>     if (idx >= 0) {
>         cs->exception_index = idx;
>         cpu_cc->do_interrupt(cs);
>         return true;
>     }
>     return false;
> }
>





Peter Maydell <peter.mayd...@linaro.org> 于2021年8月6日周五 下午6:16写道:

> On Fri, 6 Aug 2021 at 07:24, Duo jia <jiaduo19920...@gmail.com> wrote:
> > I am simulating a device. When an interrupt occurs, another interrupt
> > comes, and the second interrupt will not be triggered because the
> > first interrupt has not yet finished.
> >
> > I want to know whether qemu can detect whether the interrupt has been
> > executed, will there be a callback here?
> > Or how can I deal with this situation?
>
> End of interrupt handling is entirely dependent on what the
> guest hardware being emulated is. Usually the guest software
> will indicate "interrupt handled" back to the interrupt
> controller (perhaps by writing a register; depends on the
> interrupt controller), and the interrupt controller will
> then look at what the next highest priority pending interrupt
> is and signal that back to the CPU, or do nothing if there's
> no new interrupt. So the second interrupt will automatically
> be taken and handled once the first one has finished,
> as a result of this interrupt controller and guest OS
> interaction.
>
> The original device usually doesn't get told when this
> happens, and it doesn't need to know. For example, one common
> form of device interrupt is level-triggered. Here the device
> has some condition (perhaps "FIFO full") that causes an
> interrupt. So it raises its outbound IRQ line when the FIFO
> is full, and it doesn't lower it again until whatever the
> device specification says is the condition (eg when the
> guest reads from the FIFO, or if the guest writes to some
> 'clear interrupt' register on the device). It's the job of
> the guest software to make sure that when it gets an interrupt
> from the device that it handles it such that the device has
> been satisfied and lowered the interrupt.
>
> More rarely, some devices are specified to pulse their interrupt
> line when a condition occurs.
>
> In summary, you need to look at the specification of the device
> you're emulating to find out when and how it is supposed to
> raise or lower its interrupt line. ("I didn't get a second
> interrupt" bugs might also be caused by bugs in the interrupt
> controller or in the guest software device driver -- if you're
> just using an existing known-to-work QEMU interrupt controller
> model and a known-to-work device driver and OS, then the
> bug is very likely in your device model. If you're also
> writing the OS device driver at the same time then the bug
> could be there instead.)
>
> -- PMM
>

Reply via email to