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 >