Re: How does qemu detect the completion of interrupt execution?
On Mon, 6 Sept 2021 at 03:47, Duo jia wrote: > > Thank you for your explanation. > >> And finishing the execution of the interrupt routine will automatically >> allow a pending second interrupt to be taken immediately > > > I think this is a hardware feature. But how to achieve it with qemu That is what my explanation was trying to tell you how to do. In a bit more detail: * your interrupt controller device should assert the irq line to the CPU for as long as there is any pending interrupt (regardless of its priority). It should deassert it when there is no longer a pending interrupt (ie when the guest writes to the interrupt status register to clear the pending status of an interrupt, if that was the only pending interrupt then the interrupt controller should stop asserting the irq line). * your stm8_cpu_set_irq function should set and clear the CPU_INTERRUPT_HARD flag in interrupt_request so that it follows the irq line value * your .cpu_exec_interrupt function should only take the interrupt if the CCR.I1/I0 bits permit it. Otherwise it should return false (telling the QEMU core code that there was no interrupt taken). cpu_exec_interrupt should *not* clear the CPU_INTERRUPT_HARD flag, whether it decides to take an interrupt or not. * your do_interrupt function should set CCR.I1/I0 from the ITC_SPRx registers (as well as doing everything else that interrupt entry needs to do) * your implementation of iret should reload the CCR.I1/I0 bits, the way the spec describes There are other ways to structure this (mostly involving tying the interrupt controller model and the CPU model together more closely), but the above is the "classic" and probably simplest way of doing it. -- PMM
Re: How does qemu detect the completion of interrupt execution?
Thank you for your explanation. And finishing the execution of the interrupt routine will automatically > allow a pending second interrupt to be taken immediately > I think this is a hardware feature. But how to achieve it with qemu Peter Maydell 于2021年9月3日周五 下午7:20写道: > On Fri, 3 Sept 2021 at 11:54, Duo jia wrote: > > > > I do some support on STM8 arch, the reference manual link is: > >> > >> > https://www.st.com/resource/en/reference_manual/cd00218714-stm8l050j3-stm8l051f3-stm8l052c6-stm8l052r8-mcus-and-stm8l151l152-stm8l162-stm8al31-stm8al3l-lines-stmicroelectronics.pdf > > > > I don't kown when to check the "PENDING" because I can't get the when > interrrupt exec over. > > Is there a similar implementation in qemu? > > Thanks for the link. Looking at that spec, the condition > for "interrupt execution has finished" is "the guest executes an > IRET instruction". However, you don't need to do anything special > at that point (beyond making the IRET instruction do the things > it should do with restoring registers). > > If you look at the diagram, the check you need to make > is "do the I1:I0 bits for this pending interrupt specify a > higher priority than the values in CCR.I1 and I0?". That is > how you determine "interrupt has higher priority than current one" > to know whether to actually take the interrupt. > > On interrupt entry the CCR bits are set from the ITC_SPRx registers, > which means that taking an interrupt automatically sets the CPU > priority such that the interrupt cannot be nested. And > finishing the execution of the interrupt routine will automatically > allow a pending second interrupt to be taken immediately, because > the IRET instruction restores the old values of CCR.I1,I0, and > those old values then mean that the CPU is at a priority that > permits the pending interrupt to be taken. > > thanks > -- PMM >
Re: How does qemu detect the completion of interrupt execution?
On Fri, 3 Sept 2021 at 11:54, Duo jia wrote: > > I do some support on STM8 arch, the reference manual link is: >> >> https://www.st.com/resource/en/reference_manual/cd00218714-stm8l050j3-stm8l051f3-stm8l052c6-stm8l052r8-mcus-and-stm8l151l152-stm8l162-stm8al31-stm8al3l-lines-stmicroelectronics.pdf > > I don't kown when to check the "PENDING" because I can't get the when > interrrupt exec over. > Is there a similar implementation in qemu? Thanks for the link. Looking at that spec, the condition for "interrupt execution has finished" is "the guest executes an IRET instruction". However, you don't need to do anything special at that point (beyond making the IRET instruction do the things it should do with restoring registers). If you look at the diagram, the check you need to make is "do the I1:I0 bits for this pending interrupt specify a higher priority than the values in CCR.I1 and I0?". That is how you determine "interrupt has higher priority than current one" to know whether to actually take the interrupt. On interrupt entry the CCR bits are set from the ITC_SPRx registers, which means that taking an interrupt automatically sets the CPU priority such that the interrupt cannot be nested. And finishing the execution of the interrupt routine will automatically allow a pending second interrupt to be taken immediately, because the IRET instruction restores the old values of CCR.I1,I0, and those old values then mean that the CPU is at a priority that permits the pending interrupt to be taken. thanks -- PMM
Re: How does qemu detect the completion of interrupt execution?
I do some support on STM8 arch, the reference manual link is: > > > https://www.st.com/resource/en/reference_manual/cd00218714-stm8l050j3-stm8l051f3-stm8l052c6-stm8l052r8-mcus-and-stm8l151l152-stm8l162-stm8al31-stm8al3l-lines-stmicroelectronics.pdf Chapter 12 describes interrupts as blow: [image: image.png] I don't kown when to check the "PENDING" because I can't get the when interrrupt exec over. Is there a similar implementation in qemu? Peter Maydell 于2021年9月3日周五 下午6:25写道: > On Fri, 3 Sept 2021 at 09:33, Duo jia wrote: > > > > I understand the hardware,but How to achieve this function with qemu?, > > > > For example, this interrupt is not allowed to be nested. When the new > interrupt comes, how can I detect that the interrupt is executing? > > That depends on the hardware. I can't answer unless you tell > me what the hardware is and give me a URL for its specification > or reference manual... > > -- PMM >
Re: How does qemu detect the completion of interrupt execution?
On Fri, 3 Sept 2021 at 09:33, Duo jia wrote: > > I understand the hardware,but How to achieve this function with qemu?, > > For example, this interrupt is not allowed to be nested. When the new > interrupt comes, how can I detect that the interrupt is executing? That depends on the hardware. I can't answer unless you tell me what the hardware is and give me a URL for its specification or reference manual... -- PMM
Re: How does qemu detect the completion of interrupt execution?
I understand the hardware,but How to achieve this function with qemu?, For example, this interrupt is not allowed to be nested. When the new interrupt comes, how can I detect that the interrupt is executing? Peter Maydell 于2021年9月2日周四 下午3:43写道: > On Thu, 2 Sept 2021 at 03:18, Duo jia wrote: > > > > 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. > > There is always some way for the CPU to tell the system > that an interrupt has been dealt with. You don't say what > architecture you're working on, so it's impossible to > be more specific. But I think it is very likely that you > have misunderstood how the hardware works. Typically > you don't need to program the interrupt controller to > check for a second interrupt -- the hw specification > says that it does that automatically. > > > Also I found the new problem(maybe bug) , when first interrupt > > not over, the second interrupt may occur > > Whether this is permitted or not depends upon the > specification of the hardware. Some interrupt controllers > never allow preemption of interrupts like this. Some > do. Some allow it but only if the guest has programmed > it to permit it (eg by setting priority registers). > As always, you need to look at what the hardware > specification says each component in the system must do > (and at how they interact with each other). > > thanks > -- PMM >
Re: How does qemu detect the completion of interrupt execution?
On Thu, 2 Sept 2021 at 03:18, Duo jia wrote: > > 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. There is always some way for the CPU to tell the system that an interrupt has been dealt with. You don't say what architecture you're working on, so it's impossible to be more specific. But I think it is very likely that you have misunderstood how the hardware works. Typically you don't need to program the interrupt controller to check for a second interrupt -- the hw specification says that it does that automatically. > Also I found the new problem(maybe bug) , when first interrupt > not over, the second interrupt may occur Whether this is permitted or not depends upon the specification of the hardware. Some interrupt controllers never allow preemption of interrupts like this. Some do. Some allow it but only if the guest has programmed it to permit it (eg by setting priority registers). As always, you need to look at what the hardware specification says each component in the system must do (and at how they interact with each other). thanks -- PMM
Re: How does qemu detect the completion of interrupt execution?
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< > 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 于2021年8月6日周五 下午6:16写道: > On Fri, 6 Aug 2021 at 07:24, Duo jia 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
Re: How does qemu detect the completion of interrupt execution?
Thank you for the detailed explanation. Peter Maydell 于2021年8月6日周五 下午6:16写道: > > On Fri, 6 Aug 2021 at 07:24, Duo jia 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
Re: How does qemu detect the completion of interrupt execution?
On Fri, 6 Aug 2021 at 07:24, Duo jia 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
How does qemu detect the completion of interrupt execution?
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? thanks