[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 

Secondly, for context I quote from one of your earlier emails:

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.

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 



More information about the OpenBIOS mailing list