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