[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Re: [f-cpu] More Dark and Dusty Corners



hello,

it seems that i have let this discussion pass...
here are some hints.

BTW, how can a user-land SW emulate a virtual OS
if the instructions have to trap when emulation
must be done ?

I have no idea of how it works on mainframes (heck)
but here is some idea :
 1) there is a "capability bit" which allows the running
code to modify its own Interrupt Routine Table pointer.
This way, the IRQ table can be stored in the user land
and be modified at will. Software interrupts/traps
occuring from THIS user program (of course) are redirected
to this table. HW interrupt and failures in the setup
of the new table are redirected to the kernel.
Note : When the bit is set, the "local IRQ table pointer"
is stored in the CMB. This isolates every task for each others.
 2) setup the table so every "supervisor" instruction is
trapped and handled by our code. Other instructions are simply
"forwarded" (ie : FDIV emulation...) to the kernel by re-running
the code inside the trap handler or something like that.

you're done.


>De: Michael Riepe <michael@stud.uni-hannover.de>
>On Mon, Sep 03, 2001 at 08:22:52PM -0400, nicO wrote:
>[...]
>> > First of all, how do we detect supervisor mode?  I guess there should be
>> > a special register indicating the current privilege level.  Bit 0 will
>> > be the `supervisor' bit, all other bits are reserved and must be zero
>> > (we can later refine the model to include specific privileges, similar
>> > to capabilities in the linux kernel).
yes, something like that.

>> Nice idea the capabilities ! It look like new protection scheme from new
>> designed OS.
>> 
>> But do you want to detect the mode by software or you speak from the
>> hardware point of view ? [...]
>I said "register", so I guess I meant hardware ;)  Whether user mode
>programs are allowed to read that register is currently unspecified.

It is mapped in the SRs so reading and writing is controlled
by another "capability bit", on a register-wise granularity
(some SRs are strictly user-dependent, such as the size
properties, some others are striclty kernel-only.)

>> > When doing a context switch, the `privilege' SR should be loaded from
>> > the new CMB before any other operation is performed.  Remember that
>> > the F-CPU might be interrupted in supervisor mode, and must be able to
>> > return to that mode when `rfe' is executed.
>> 
>> ??? During an interrupt the cpu switch to priviledge mode and then the
>> kernel do what i want.
It depends on the IRQ.
Ie : see above, a user application may want to emulate some
instructions itself.

>> But the some trap could stay in user land to handel some error (div by
>> zero,...). 
>
>I'm not in OS/Software land here either...
>
>The CPU simply must know where it came from, in order to return properly.
obviously :-)

>That in turn means it has to save a certain amount of state, including
>the priviledge mode SR, automatically (that is, in hardware).
>
>> > A propos `rfe'/interrupts: something that is not clear yet is what
>> > happens when the F-CPU is interrupted.  Is it supposed to perform
>> > a full context switch in all cases?  That might be overkill in some
>> > situations, especially when the interrupt handler is short.
not necessarily.
In practice, the time to fetch the handler code can be very
long, if you have to fetch it from external SDRAM...

>> >  What happens
>> > if the IRQ handler reaches the final `rfe' before the SRB is finished?
>> It freeze the code !
>That's what I was afraid of.

no. SRB is ATOMIC. It also reorganises the access pattern
to avoid certain stalls. If RFE occurs before SRB ends,
the return code will be fetched but SRB will continue.
SRB also blocks IRQs.

SRB IS SAFE by design. It simply spares some time during
most context switches.
One solution to your problem (fast/slow IRQs) would be to
use the SRB instruction explicitely when the IRQ routine
starts but we will have wasted some precious time (it
can take a long time before the routine code is available).

>> > According to the manual, the running SRB must finish before a new one
>> > can be started, but that's not appropriate -- why finish something you
>> > have to undo anyway?

it is because when it returns, it would be very complicated
to know if the register was saved or something like that.

In fact i think that i remember : If you interrupt one SRB
by another, we can't know which register belongs to what.

>> I don't think that you're supposed to come back to the same program
>> after an interrupt, the kernel should choose.
>
>You don't call the scheduler on every interrupt.  Linux only calls it
>when the current process runs out of fuel (timeslice is over), or when
>another process is woken up (or created) that probably has a higher
>priority.  And a timeslice is rather long -- 20 ticks IIRC (that's 2
>seconds).
>
>Most interrupts are handled on-the-fly, without switching to kernel mode.
>They do their (short) work and then return to the interrupted process.
>You would lose too much time otherwise.
>
>> Maybe we can implement such fast interrupt with shadow register (like
>> ARM does). Instead of saving the regiter bank, you just switch the bank
>> (maybe we don't need a complete new 64 registers set). But then you
>> could have many problems with the implementation of a preemptive system
>> (allowing an interrupt to interrupt an other interrupt). Because, then
>> you should save 2 register sets ! 
>
>We have that nasty nested interrupt problem anyway.

Register windows are no-no.
We already have a "huge" register set and SRB to reduce the
latency. register windows would kill the clock cycle length.

>> > Another problem is nested interrupts.  When each interrupt (or exception)
>> > causes a context switch, we need a CMB stack -- on the second interrupt,
>> > the context of the first IRQ handler must be saved, and it must be
>> > properly restored when the "inner" handler returns.  If we don't
>> > permit an IRQ to interrupt its own handler (that is, block it until
>> > the corresponding `rfe'), we may get away with one CMB per possible
>> > IRQ/exception, but that's already a whole lot of CMBs.  Oh by the way:
>> > we need an `interrupt enable' SR, too.

we have it, at least internally. SRB masks it.

>> That's the difference between instrerrupt enable and interrupt mask
>> (which leaves the interrupt pending until the rfe). In fact, the first
>> thing that the kernel should do is to prepare a new pointer to a CMB and
>> then renable the interrupt. In fact, it's the common problem with every
>> cpu.

right.
if you want your IRQ handler to be reentrant, you have
to setup your CMB stack in SW explicitely and reenable IRQs.
(it's the reverse when leaving.)

>What about exceptions?  You can't turn them off like interrupts.
>An interrupt/exception handler may trigger an exception, and there may
>be interrupts while an exception handler is executed.  You can't avoid
>the nesting, and software may not always be fast enough to prepare a
>new CMB pointer before the next interrupt/exception occurs.
>
>Linux uses CMBs (or Task State Segments, or struct task_struct,
>or whatever) only for user tasks, and it only does a context switch
>(save/reload all registers) when switching from one task to another,
>because that's faster.
>

> Michael "Tired" Riepe <Michael.Riepe@stud.uni-hannover.de>

*************************************************************
To unsubscribe, send an e-mail to majordomo@seul.org with
unsubscribe f-cpu       in the body. http://f-cpu.seul.org/