[OpenBIOS] Running client with MMU off

BALATON Zoltan balaton at eik.bme.hu
Fri Jun 6 13:21:46 CEST 2014


On Fri, 6 Jun 2014, Mark Cave-Ayland wrote:
> On 06/06/14 01:55, BALATON Zoltan wrote:
> 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.

>From the device trees I've seen this seems to be the case but that does 
not mean that the client code is also run with enabled MMU. OF could 
enable it only during callbacks as my patch tried. Without real hardware I 
can't find out though.

> 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;

Except if OF does what I said above. Either that or on real hardware no 
MMU interrupt is generated while overwriting the vectors until they are 
correct again for some other reason. (Like because page zero is alredy 
mapped unlike with OpenBIOS.)

> 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

No it doesn't. All CIF calls are before it touches the vectors and they 
work all right as long as MMU is enabled.

> 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.

So this suggests those traps are probably not happening on real hardware. 
Maybe because the MMU is off while client code is running?

> 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?

I don't think this is what happens (it would also break when the OF ROM is 
updated so I can't imagine they'd do that). Instead the addresses they 
copy first is where the final vectors will be after they set up their 
memory map. But before that they use the vectors from the loaded boot 
executable and this is what the fixup does. (I've said above the first 
vectors point to somewhere near the end of the ROM area but this is later 
replaced with their routines after the MMU is taken over. It just happens 
to be OpenBIOS ROM at this point.)

> 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.

The entire region is copied with default addresses pointing to the final 
location of exception handlers but at the time of copying these are not 
correct yet and point into the OF ROM. These are then immediately replaced 
by addresses pointing to the current location of the handlers in the boot 
code but on QEMU a DSI is happening during this which jumps off to the 
wrong address. If I disable the MMU at the time when the first vectors are 
copied it works. No CIF calls are made after this point but they are made 
after quiesce and before setting up the vectors so diabling MMU at 
call_elf or quiesce does not work.

There is some disassembly of the part replacing the vectors at the end of 
this message and how it fails when getting a DSI during it.

Regards,
BALATON Zoltan

IN:
0x0040091c:  rlwinm  r0,r26,0,0,19
0x00400920:  lis     r3,104
0x00400924:  lis     r4,66
0x00400928:  stw     r0,40(r2)
0x0040092c:  addi    r3,r3,-18952
0x00400930:  addi    r4,r4,4068
0x00400934:  li      r5,8192
0x00400938:  bl      0x41f004

IN:
0x0041f004:  stwu    r1,-32(r1)
0x0041f008:  mflr    r0
0x0041f00c:  stw     r29,20(r1)
0x0041f010:  stw     r30,24(r1)
0x0041f014:  stw     r31,28(r1)
0x0041f018:  stw     r0,36(r1)
0x0041f01c:  mr      r29,r3
0x0041f020:  mr      r30,r4
0x0041f024:  mr      r31,r5
0x0041f028:  li      r3,0
0x0041f02c:  crclr   4*cr1+eq
0x0041f030:  bl      0x441bb0

IN:
0x00441bb0:  rlwinm. r0,r5,27,5,31
0x00441bb4:  mr      r11,r3
0x00441bb8:  mtctr   r0
0x00441bbc:  beq-    0x441c14

IN:
0x00441bc0:  rlwinm  r0,r5,0,0,26
0x00441bc4:  subf    r5,r0,r5
0x00441bc8:  lwz     r0,0(r4)
0x00441bcc:  stw     r0,0(r3)
0x00441bd0:  lwz     r9,4(r4)
0x00441bd4:  stw     r9,4(r3)
0x00441bd8:  lwz     r0,8(r4)
0x00441bdc:  stw     r0,8(r3)
0x00441be0:  lwz     r9,12(r4)
0x00441be4:  stw     r9,12(r3)
0x00441be8:  lwz     r0,16(r4)
0x00441bec:  stw     r0,16(r3)
0x00441bf0:  lwz     r9,20(r4)
0x00441bf4:  stw     r9,20(r3)
0x00441bf8:  lwz     r0,24(r4)
0x00441bfc:  stw     r0,24(r3)
0x00441c00:  lwz     r9,28(r4)
0x00441c04:  stw     r9,28(r3)
0x00441c08:  addi    r4,r4,32
0x00441c0c:  addi    r3,r3,32
0x00441c10:  bdnz+   0x441bc8

IN:
0x00441bc8:  lwz     r0,0(r4)
0x00441bcc:  stw     r0,0(r3)
0x00441bd0:  lwz     r9,4(r4)
0x00441bd4:  stw     r9,4(r3)
0x00441bd8:  lwz     r0,8(r4)
0x00441bdc:  stw     r0,8(r3)
0x00441be0:  lwz     r9,12(r4)
0x00441be4:  stw     r9,12(r3)
0x00441be8:  lwz     r0,16(r4)
0x00441bec:  stw     r0,16(r3)
0x00441bf0:  lwz     r9,20(r4)
0x00441bf4:  stw     r9,20(r3)
0x00441bf8:  lwz     r0,24(r4)
0x00441bfc:  stw     r0,24(r3)
0x00441c00:  lwz     r9,28(r4)
0x00441c04:  stw     r9,28(r3)
0x00441c08:  addi    r4,r4,32
0x00441c0c:  addi    r3,r3,32
0x00441c10:  bdnz+   0x441bc8

IN:
0x00441bc8:  lwz     r0,0(r4)
0x00441bcc:  stw     r0,0(r3)
0x00441bd0:  lwz     r9,4(r4)
0x00441bd4:  stw     r9,4(r3)
0x00441bd8:  lwz     r0,8(r4)
0x00441bdc:  stw     r0,8(r3)
0x00441be0:  lwz     r9,12(r4)
0x00441be4:  stw     r9,12(r3)
0x00441be8:  lwz     r0,16(r4)
0x00441bec:  stw     r0,16(r3)
0x00441bf0:  lwz     r9,20(r4)
0x00441bf4:  stw     r9,20(r3)
0x00441bf8:  lwz     r0,24(r4)
0x00441bfc:  stw     r0,24(r3)
0x00441c00:  lwz     r9,28(r4)
0x00441c04:  stw     r9,28(r3)
0x00441c08:  addi    r4,r4,32
0x00441c0c:  addi    r3,r3,32
0x00441c10:  bdnz+   0x441bc8

IN:
0x00441bcc:  stw     r0,0(r3)

IN:
0x00441bd0:  lwz     r9,4(r4)

IN:
0x00441bd4:  stw     r9,4(r3)
0x00441bd8:  lwz     r0,8(r4)
0x00441bdc:  stw     r0,8(r3)
0x00441be0:  lwz     r9,12(r4)
0x00441be4:  stw     r9,12(r3)
0x00441be8:  lwz     r0,16(r4)
0x00441bec:  stw     r0,16(r3)
0x00441bf0:  lwz     r9,20(r4)
0x00441bf4:  stw     r9,20(r3)
0x00441bf8:  lwz     r0,24(r4)
0x00441bfc:  stw     r0,24(r3)
0x00441c00:  lwz     r9,28(r4)
0x00441c04:  stw     r9,28(r3)
0x00441c08:  addi    r4,r4,32
0x00441c0c:  addi    r3,r3,32
0x00441c10:  bdnz+   0x441bc8

IN:
0x00441bc8:  lwz     r0,0(r4)
0x00441bcc:  stw     r0,0(r3)
0x00441bd0:  lwz     r9,4(r4)
0x00441bd4:  stw     r9,4(r3)
0x00441bd8:  lwz     r0,8(r4)
0x00441bdc:  stw     r0,8(r3)
0x00441be0:  lwz     r9,12(r4)
0x00441be4:  stw     r9,12(r3)
0x00441be8:  lwz     r0,16(r4)
0x00441bec:  stw     r0,16(r3)
0x00441bf0:  lwz     r9,20(r4)
0x00441bf4:  stw     r9,20(r3)
0x00441bf8:  lwz     r0,24(r4)
0x00441bfc:  stw     r0,24(r3)
0x00441c00:  lwz     r9,28(r4)
0x00441c04:  stw     r9,28(r3)
0x00441c08:  addi    r4,r4,32
0x00441c0c:  addi    r3,r3,32
0x00441c10:  bdnz+   0x441bc8

IN:
0x00441bc8:  lwz     r0,0(r4)
0x00441bcc:  stw     r0,0(r3)
0x00441bd0:  lwz     r9,4(r4)
0x00441bd4:  stw     r9,4(r3)
0x00441bd8:  lwz     r0,8(r4)
0x00441bdc:  stw     r0,8(r3)
0x00441be0:  lwz     r9,12(r4)
0x00441be4:  stw     r9,12(r3)
0x00441be8:  lwz     r0,16(r4)
0x00441bec:  stw     r0,16(r3)
0x00441bf0:  lwz     r9,20(r4)
0x00441bf4:  stw     r9,20(r3)
0x00441bf8:  lwz     r0,24(r4)
0x00441bfc:  stw     r0,24(r3)
0x00441c00:  lwz     r9,28(r4)
0x00441c04:  stw     r9,28(r3)
0x00441c08:  addi    r4,r4,32
0x00441c0c:  addi    r3,r3,32
0x00441c10:  bdnz+   0x441bc8

Raise exception at 00441bcc => 00000002 (00)
IN:
0x00000300:  b       0xffffc3a0

invalid/unsupported opcode: 00 - 00 - 00 (00000000) ffffc3a0 0
IN:
0xffffc3a0:  .long 0x0

Raise exception at ffffc3a4 => 00000006 (21)
IN:
0x00000700:  mtsprg  2,r2
0x00000704:  li      r2,7
0x00000708:  b       0xffffe0f0

invalid/unsupported opcode: 00 - 00 - 00 (00000000) ffffe0f0 0
IN:
0xffffe0f0:  .long 0x0

Raise exception at ffffe0f4 => 00000006 (21)
Raise exception at ffffe0f4 => 00000006 (21)

Vectors as set up by OpenBIOS and copied to page zero (this is what it 
looked like before MorphOS replaced them):

Disassembly of section .text.vectors:

fff00000 <.text.vectors>:
fff00000:       60 00 00 00     nop
fff00004:       60 00 00 00     nop
fff00008:       4b ff ff fc     b       0xfff00004
         ...
fff00100:       48 00 24 20     b       0xfff02520
fff00104:       3c 20 80 00     lis     r1,-32768
fff00108:       7c 21 0a 15     add.    r1,r1,r1
fff0010c:       41 82 00 10     beq     0xfff0011c
fff00110:       7c 20 00 a6     mfmsr   r1
fff00114:       78 21 00 40     clrldi  r1,r1,1
fff00118:       7c 20 01 64     mtmsrd  r1
fff0011c:       7c 68 02 a6     mflr    r3
fff00120:       3c 80 ff f1     lis     r4,-15
fff00124:       38 84 8e 98     addi    r4,r4,-29032
fff00128:       7c 89 03 a6     mtctr   r4
fff0012c:       4e 80 04 20     bctr
         ...
fff00200:       4b ff ff 05     bl      0xfff00104
         ...
fff00300:       48 00 20 8c     b       0xfff0238c
         ...
fff00380:       4b ff fd 85     bl      0xfff00104
         ...
fff00400:       48 00 20 28     b       0xfff02428
         ...
fff00480:       4b ff fc 85     bl      0xfff00104
         ...
fff00500:       4b ff fc 05     bl      0xfff00104
         ...
fff00600:       4b ff fb 05     bl      0xfff00104
         ...
fff00700:       4b ff fa 05     bl      0xfff00104




More information about the OpenBIOS mailing list