How can a spurious interrupt be unhandled? - interrupt-handling

I'm struggling to understand the notion of an "Unhandled" spurious interrupt. From my understanding a spurious interrupt occurs when the interrupt line was asserted, but when the PIC goes back to check for the interrupt source, it's no longer asserted. This is likely caused by noise on the interrupt line.
The PIC will then tell the CPU "there's an interrupt, but [warning] it was spurious". By this point, whatever process is handling the interrupt will either (1) run the entire ISR, or will (2) realize it's spurious and do nothing. Both of those cases, in my opinion, constitute "handling" the interrupt. Conversely, if (2) is considered unhandled, I don't see anything wrong with an unhandled spurious interrupt. In fact, it's a good thing.
Am I off base on my understanding of spurious interrupts? I really don't understand how an interrupt can possibly be unhandled.

Related

exceptions vs interrupts in RiscV?

I read that exceptions are raised by instructions and interrupts are raised by external events.
But I couldn't understand few things:
In which type we stop immediately and in which we let the current line of code finish?
In both cases and after doing 1 we run the next program, is that right?
The terminology is used differently by different authors.
The hardware exception mechanism is used by both software caused exceptions, and by external interrupts.
In which type we stop immediately and in which we let the current line of code finish?
The processor can do what its designers want up to a point.
If there is an external interrupt, the processor may choose to finish some of the work in progress before taking the interrupt.
If there is a software caused interrupt, the processor simply cannot execute that instruction (or any instructions after) and must abort its execution, and take the exception without completing the offending instruction.
In both cases and after doing 1 we run the next program, is that right?
In the case of external interrupt, the most efficient is to resume the program that was interrupted, as the caches and page tables are hot for that process.  However, an external interrupt may change the runnable status of another higher priority process, or may end the timeslice of the interrupted process, indicating another process should now get CPU time instead of the one interrupted.
In the case of a software caused exception, it is could be a non-resumable situation (null pointer dereference), in which case, yes another process get the CPU after.  It could be a resumable situation, like I/O request or page fault.  If servicing the situation requires interfacing with peripherals, that may block the interrupted process, so another process would get some CPU time.

Control Flags in Interrupt Routine and NMI [8086]

I know how an interrupt routine is executed in 8086. The thing that isn't clear to me is how different types of interrupts (i.e hardware, software and exception) uses the control flags (Interrupt Flag and Trap Flag) in their execution.
And other thing is what is Non-mask-able Interrupts and its use?
So please help me with this, Thanks.
An interrupt handler doesn't "do" anything with the IF and TF flags. They are cleared so the interrupt handler can do its job properly and safely. You need to understand what those flags do, then it becomes obvious why they are cleared during an interrupt.
When the Interrupt Flag or IF is set, the processor will allow external hardware signals (usually from a Programmable Interrupt Controller or PIC) to trigger interrupts. When it's cleared, hardware interrupt signals are ignored.
(The NMI or Non-Maskable Interrupt is an exception, a special case intended for "emergency-type" or "real-time" events, and it will trigger even if the IF is cleared.)
The Trap Flag or TF is used by debuggers. When the flag is set, the processor will execute exactly one instruction, then trigger an INT 1. A debugger can use this to single-step machine code without having to temporarily modify it (e.g. to temporarily insert an INT 3 instruction), which is not always even possible (e.g. single-stepping code stored in ROM).
Now why are both flags cleared during interrupts?
The IF is cleared because Intel didn't want to impose the restriction that interrupt handlers be reentrant. Reentrant code is code that can be safely suspended at any time, and called again from the top. If you allow interrupts while an interrupt handler is running, it is quite possible for a second interrupt to trigger while in the middle of handling the first one, which would cause the handle to re-enter. Note that software interrupt handlers (like the DOS interrupt handler 21h) typically don't have this concern because they are not called by asynchronous hardware signals; therefore, just about the first thing they do is execute STI to re-enable interrupts.
The situation with TF is very similar but a bit trickier to understand. I don't have experience writing an x86 debugger, so I don't know the ins-and outs. The short version is that the TF is cleared during interrupts to avoid chaos. What follows is a speculative excercise of mine.
First of all, it should be obvious that at least the single-step interrupt (type-1 or INT 1 if you will) MUST clear the flag, otherwise the debugger's single-step handler itself would trigger single-step interrupts or not run at all. Second, let's imagine that the TF is not cleared for every interrupt: if a hardware interrupt triggers while the debugger is trying to use the TF, the interrupt handler itself might be the one triggering the single-step interrupt, instead of the code being debugged. Worse, now the interrupts are suspended (see IF above) and not only are you looking at the wrong code (or thoroughly confused the debugger), but your keyboard doesn't work anymore. (As I said, I'm speculating: I have no idea what happens if IF is cleared but TF is set).
Asynchronous hardware interrupts need to be handled without "bothering" the current running program, that is, they need to execute without the program being aware of them. That includes "not bothering" a single-stepping debugger.

What does an interrupt handler do?

I know that when a keyboard interrupt occurs, the handler has code to save the character that has been received. What about other events that create interrupts like stack overflows, arithmetic overflow, divide by zero, etc? What does the interrupt handler do when these events occur?
There are basicaly three types of interrupts:
Hardware interrupts happen when there is a signal from an external device, like for example the keyboard or a mouse. The interrupt handler for those will get the data from the device and then let the program continue as if nothing happened.
Software interrupts are triggered by the program itself, they are used to call subroutines in the operating system or in device drivers.
Exception interrupts are triggered by certain operations when there is an unexpected result or a condition where there can't be a normal result, for example a division by zero. What the handlers for those do differ a bit depending on what the error is, but generally they print out an error message and terminate the program.

What happens when an ISR is running and another interrupt happens?

What happens if an ISR is running, and another interrupt occurs? Does the first interrupt get interrupted? Will the second interrupt get ignored? Or will it fire when the first ISR is done?
EDIT
I forgot to include it in the question (but I included it in the tags) that I meant to ask how this worked on Atmel AVR's.
Normally, an interrupt service routine proceeds until it is complete without being interrupted itself in most of the systems. However, If we have a larger system, where several devices may interrupt the microprocessor, a priority problem may arise.
If you set the interrupt enable flag within the current interrupt as well, then you can allow further interrupts that are higher priority than the one being executed. This "interrupt of an interrupt" is called a nested interrupt. It is handled by stopping execution of the original service routine and storing another sequence of registers on the stack. This is similar to nested subroutines. Because of the automatic decrementing of the stack pointer by each interrupt and subsequent incrementing by the RETURN instruction, the first interrupt service routine is resumed after the second interrupt is completed, and the interrupts are serviced in the proper order. Interrupts can be nested to any depth, limited only by the amount of memory available for the stack.
For example, In the following diagram, Thread A is running. Interrupt IRQx causes interrupt handler Intx to run, which is preempted by IRQy and its handler Inty. Inty returns an event causing Thread B to run; Intx returns an event causing Thread C to run.
Image Ref
For hardware interrupts, Priority Interrupt Controller Chips (PIC's) are hardware chips designed to make the task of a device presenting its own address to the CPU simple. The PIC also assesses the priority of the devices connected to it. Modern PIC's can also be programmed to prevent the generation of interrupts which are lower than a desired level.
UPDATE: How Nested Interrupt Works on Atmel AVRs
The AVR hardware clears the global interrupt flag in SREG before entering an interrupt vector. Therefore, normally interrupts remain disabled inside the handler until the handler exits, where the RETI instruction (that is emitted by the compiler as part of the normal function epilogue for an interrupt handler) will eventually re-enable further interrupts. For that reason, interrupt handlers normally do not nest. For most interrupt handlers, this is the desired behaviour, for some it is even required in order to prevent infinitely recursive interrupts (like UART interrupts, or level-triggered external interrupts).
In rare circumstances though nested interrupts might be desired by re-enabling the global interrupt flag as early as possible in the interrupt handler, in order to not defer any other interrupt more than absolutely needed. This could be done using an sei() instruction right at the beginning of the interrupt handler, but this still leaves few instructions inside the compiler-generated function prologue to run with global interrupts disabled. The compiler can be instructed to insert an SEI instruction right at the beginning of an interrupt handler by declaring the handler the following way:
ISR(XXX_vect, ISR_NOBLOCK)
{
...
}
where XXX_vect is the name of a valid interrupt vector for the MCU type.
Also, have a look at this Application Note for more info on interrupts on Atmel AVRs.
The way interrupts work:
The code sets the "Global Interrupt Enable" bit; without it, no interrupts will occur.
When something happens to cause an interrupt, a flag is set.
When the interrupt flag is noticed, the "Global Interrupt Enable" bit is cleared.
The appropriate ISR is run.
The "Global Interrupt Enable" bit is re-set.
Things now go back to step 2, unless an interrupt flag is already set during the ISR; then things go back to step 3.
So to answer the question: When the first ISR is finished, the second ISR will be run.
Hope this helps!

What happens if another interrupt is raised before the first interrupt action is completed?

This question is from the interrupt handling topic.
Suppose an interrupt is being serviced. What happens if another interrupt is raised even before the first interrupt action is completed?
The following applies to the x86 architecture only, but other architectures might well follow the same pattern:
There is a processor flag called IF (Interrupt Flag) that controls whether hardware interrupts can be processed, or have to be put on hold. When IF = 0, interrupts will be postponed until the flag is reenabled (Except for the NMI, the Non-Maskable Interrupt, which is intended as an 'emergency only' interrupt that cannot be blocked).
The IF is automatically cleared by the processor before an interrupt servicing routine is called. This is necessary to prevent interrupt calls to become reentrant out of control. Note that the interrupt servicing code itself could not do this on its own, because if IF were not disabled before entering the routine, it would be possible for more interrupts to occur before the servicing code has time to execute even a single instruction. Then, a "firehose" of interrupts would immediately result in (of all things) a stack overflow.
So, in answer to your direct question: typically, when a second hardware interrupt occurs while an initial one is being serviced, that interrupt will be put on hold until the first one has finished.
As usual, the full story is a bit more complicated. The Intel Architecture Software Developer’s Manual at Intel's web site gives a more complete description starting on page 10-4.
It depends on the system. Normally, if the new interrupt is a higher priority than the first, then it is responded to, suspending the handler for the first interrupt. When its handler finishes, then the original interrupt handler resumes. Finally, assuming no more interrupts, the original handler finishes and normal service resumes. Sometimes, the resumed process will be the process that was interrupted; sometimes, it will no longer be the most eligible process and some other one will resume.
Similarly, if a second or subsequent instance of the original interrupt occurs before the first handler completes, or if a lower or equal priority interrupt occurs, it will be held up until the first handler completes. Before normal processing is resumed, the kernel checks for outstanding interrupts that should have been handled but were blocked.
An interrupt handler may block other interrupts.
Well, if interrupts were not disabled after the first interrupt, the second will cause your interrupt service routine to be called again. You must make sure interrupts get disabled to avoid this decidedly undesirable behavior.
So, if your interrupt service routine is doing its thing, and then another interrupt occurs, it will be just as if you were doing anything else: the corresponding interrupt routine will be called.
On the Intel architecture, the "cli" instruction will disable interrupts, and "sti" will enable them again.