Common thing page faults. So we talk about paging later in this
course. But, if you go try to access some piece of
memory and the memory's not mapped in correctly.
So you, you just can't, the machine physically can't go find memory.
You'll take a, a trap. And then finally, the things like system
calls or interrupts on x86. There's an instruction called int, which
actually causes a, just an interrupt to occur.
And then it takes as a parameter a number. So that's how system calls have
traditionally worked on x86. They later replaced it with actually, an
instruction called sys enter which, does a similar sort of thing with a little bit
cleaner semantics. So I think we, oh actually there's one
point I wanted to talk about asynchronous interrupts.
With asynchronous interrupts, it's hard to know when to deliver the interrupt.
Cuz it's not pegged to a specific instruction.
If the instructions are going down the pipeline, you don't necessarily know
whether to attack it to the first instruction that's in the pipe.
I think it's at the sort of a fetch stage. I think it's at the execute stage.
I think it's at the write back stage. So that's, that's a, that's a challenge.
Another important thing to think about with, asynchronous interrupts is,
sometimes multiple of them go off at the same time.
So let's say your timer interrupt goes off at, at, time t0.
= zero, your, network card gets a packet in and someone hits the keyboard exactly
at the same time. Well, which, which should happen?
Which should you actually go handle? Typically machines have a prioritized
inner-request mechanism. So there would be some sort of priority
encoder there which will determine which is the highest priority.
Some of them, some machines will actually have re-programmable priority interrupt
encoders effectively which will allow you, allow the system software, the operating
system to decide what is the highest priority interrupt to go take in that
case. Sometimes machines will just sort of make
a decision, or the objects of the, of the machine will sort of make a decision, and
say these classes of interrupts are not ver, or asynchronous interrupts are not
very easy to handle so we'll sort of put those in these of low priority bucket, and
then some small set you'll actually be alter sort of re, re-prioritize if you
will. Oh.
Oh, yeah. So, I wanted to talk about this.
What actually happens, when you take a interrupt, from a hardware mechanism
perspective. So the, this is a very idealized view, but
from a mechanical perspective things need to happen in a machine.
There's some state that needs to be updated.
The first thing that needs to happen is, you should basically stop the program at
some point. And you should try to save the program
counter somewhere. Cuz if we want to come back to, let's say,
the instruction that took the interrupt, We need to know where to come back to.
But we're going to go and execute some other piece of code in the meantime.
So our, we can't just save it in the program counter.
We need to save it off. And that's typically called either an
exceptional PC. So EPC that's, what its called on, on a
MIPS, MIPS processor. On x86, I'm trying to remember what it
does. I think it actually gets, pushed onto a
systems stack. So it gets put into memory somewhere.
And if you had something like MIPS, one of the tricky things here is all of your
registers. Are still live from the previous
instruction sequence here. So all of a sudden you, you jump into a
new piece of code and all of your instructions are still, or all of your
registers are still live, They have values you can't throw away.
And you're in the interrupt exception handler.
What do you do? Well there's, there's different,
mechanisms to this, to, to have this happen.
Some architectures, something like MIPS actually reserves two registers that are
only allowed to be used by interrupt handlers.
This is actually a pretty poor solution in my opinion.
So they, they save off two registers. I believe it is, it's somewhere high, it's
like, maybe like 28 and 29. Registers 28 and 29, are not allowed to be
used by the, basically operating system, or the user code and it's only used by
interrupt handlers, in the operating system to save off state.
And what happens in that case is you could use those registers to basically take the
other registers, Compute some addresses and do a store.
Cuz if you recall on, on MIPS, you need to have an address to do the store to.
So you compose the address into, let's say, register 28, and then use that as the
store address. And you can store off all of the other
registers into memory somewhere. And then you can unwind that back when
you're, when you're going to return from the interrupt.
So it's a, a complicated dance. Something like x86, there is some power
mechanisms they are which actually take it and take a lot of your registers and put
them on to a in memory stock for you. So, it's typically, well it's either a
push A which is, push, pushes all of the register state onto the stack and, and pop
A which pops it off. It is not actually required though.
There's other, some operating systems don't actually do push A and pop A, better
operating systems, or more modern operating system will actually only save
off what is strictly needed. That's something, something to think
about. One other important thing here.
Typically when an interrupt occurs, you probably want to mask other interrupts
from happening. So this is, this is a really hard problem
to solve, is you have interrupts inside the interrupt handler.
Ooh. Yeah, that doesn't sound like a, like a
happy day for, for anyone. Cuz what if you're in interrupt handle and