[OpenBIOS] Running client with MMU off
Mark Cave-Ayland
mark.cave-ayland at ilande.co.uk
Fri Jun 6 10:31:47 CEST 2014
On 06/06/14 01:55, BALATON Zoltan wrote:
> I'm trying to solve the last bigger outstanding problem for MorphOS to
> run with OpenBIOS. This is that it modifies exception vectors without
> first turning the MMU off (probably expecting it to be off as happens on
> real hardware). OpenBIOS on the other hand turns the MMU on and needs
> this for client interface calls to work so calling the client boot code
> with MMU off results in a hang. There is disabled code in the quiesce
> method to clear the MMU bits but this is not sufficient/correct because
> MorphOS continues to call client interface callbacks after calling
> quiesce. Thus I was trying to save MSR, turn MMU on then restore MSR on
> client callbacks with the patch below but it does not work and leads to
> writes to wrong addresses and a crash on restore. (Probably the stack
> location is wrong after the patch?) Can anyone tell why it's not working
> and what could be done instead?
I really don't think that this is the correct way to handle this at all.
Firstly I believe that real-mode? is set to false by default on real
hardware, e.g. from articles like
http://www.dialectronics.com/Words/OF_Part_III.shtml.
Secondly, for context I quote from one of your earlier emails:
<quote>
MorphOS does not set a callback but seems to call OF functions before
starting to take over memory management and it probably only calls exit
after that which may work according to the above document. During MMU
take over what happens though is this: First MorphOS copies some code to
0x0000-0x1fff without first disabling the memory management interrupts.
(Maybe it expects them to be off until enabled.) The code it copies is
not correct yet as it has jumps pointing to somewhere near the end of
ROM area. Then it fixes up these jumps with addresses pointing to its
current location at its load address (it may change this back later
again but I have not got there yet). Then it enables the MMU bits in the
MSR. Surely enough on QEMU it hits a DSI exception just after it copied
its vectors but before it fixed them up which leads to a jump to
somewhere in ROM and eventually hits an invalid opcode again. This does
not happen if I disable the MMU bits in MSR when the vectors are first
copied and let MorphOS enable them later after it fixed the vectors up.
I think this either again just works by chance on real hardware or the
OF implementations there disable these bits when calling the boot loader
and do not need working MMU for client functions. It could be verified
by checking the value of MSR on real hardware but I have no access to
any. In either case if MorphOS had not assumed that no MMU exception
happens while the vectors are wrong but explicitely disabled MMU bits
before touching the vectors it would work. The exception happening here
during MMU take over is not caused by openbios but by accessing memory
by the boot code but openbios needs working MMU for client functions
earlier so it cannot disable these bits itself before calling the
bootloader unless it could enable during callbacks. So I see no easy way
to fix this within openbios.
</quote>
It seems to me that if real-mode? is set to false on real hardware, then
your hypothesis that MorphOS expects MMU interrupts to be disabled can't
be true; as soon as your hit an MMU fault you have to service it. Now I
can think of two possible things here:
1) Incorrect/not enough state saving on CIF entry/exit
Does MorphOS call CIF between updating the trap table and fixing it up?
This was similar to a recent bug I had with SPARC64, in that I had to
modify the CIF entry/exit to save more processor state to prevent traps.
This is because *BSDs assume they could call CIF at a similar point
before final takeover without realising that a window fill/spill trap
could occur between these two points.
2) Trap table is copied from OpenFirmware directly
Maybe the MorphOS developers have found the address of the default trap
table in a real OF ROM and copy those values into the real vectors as a
starting point? Then they can just fix up the values into their
executable as required while during the transition any "unfixed" traps
would be handled by the PROM as before? Can you provide more details as
to exactly which addresses are copied from, and whether this is done on
a "per vector" basis or whether the entire 0x0000-0x1fff block is copied
as a single chunk and from where? I think this may be the more likely
scenario.
ATB,
Mark.
More information about the OpenBIOS
mailing list