[OpenBIOS] [Qemu-ppc] Running client with MMU off

Alexander Graf agraf at suse.de
Thu Jun 26 13:13:37 CEST 2014


On 26.06.14 13:10, BALATON Zoltan wrote:
> On Thu, 26 Jun 2014, Alexander Graf wrote:
>> On 26.06.14 01:36, BALATON Zoltan wrote:
>>> On Wed, 25 Jun 2014, Alexander Graf wrote:
>>>> On 25.06.14 12:40, BALATON Zoltan wrote:
>>>>> On Wed, 25 Jun 2014, BALATON Zoltan wrote:
>>>>>> ppc_store_sdr1: 0fe00000
>>>>>> helper_store_sr: reg=0 20000400 00000000
>>>>> [...]
>>>>>> helper_store_sr: reg=0 00000000 20000400
>>>>>> Raise exception at 0041cd00 => 00000003 (40000000)
>>>>>>
>>>>>> ^^^ This exception should not happen. It is trying to handle it 
>>>>>> but the handlers are not working yet and gets in an infinite 
>>>>>> loop. It boots if MMU is disabled while this part runs but 
>>>>>> MorphOS does not disable it yet and according to my oftest 
>>>>>> results they are enabled on Apple too. How does it work on real 
>>>>>> hardware and why does it fail on QEMU? (Note the the value of sr0 
>>>>>> is identical to the one set by OpenBIOS and SDR1 is unchanged so 
>>>>>> translations via the page table should still work, shouldn't it?)
>>>>>
>>>>> I was mistaken about the values being the same as it is zeroing 
>>>>> sr0. So can this explain why translation via the page table fails 
>>>>> after this and why an ISI is generated? Why are the sr registers 
>>>>> set up with the values above by OpenBIOS? Could they be 0 instead?
>>>>
>>>> SR registers are used to translate EAs to VAs. If you set them all 
>>>> to 0 they would end up getting the same VSID.
>>>
>>> OK but why is SEGR_BASE defined as 0x0400 in arch/ppc/qemu/ofmem.c? 
>>
>> I guess to make it easier to debug vs empty SR registers and to make 
>> sure it doesn't collide with a guest that sets SR registers to 0 
>> temporarily?
>>
>> What does real Apple firmware use for their VSIDs?
>
> I'll modify oftest to print sr regs and try to rerun it to find out.
>
>>> 0x0041cdf8: isync
>>>
>>> htab_base 000000000fe00000 htab_mask 000000000000ffff hash 
>>> 000000000000041c
>>> 0 htab=000000000fe00000/000000000000ffff vsid=0 ptem=1 
>>> hash=000000000000041c
>>>
>>> ppc_store_sdr1: 00000000
>>>
>>> htab_base 0000000000000000 htab_mask 000000000000ffff hash 
>>> 000000000000041c
>>> 0 htab=0000000000000000/000000000000ffff vsid=0 ptem=1 
>>> hash=000000000000041c
>>> 1 htab=0000000000000000/000000000000ffff vsid=0 api=1 
>>> hash=fffffffffffffbe3
>>> Raise exception at 0041cdfc => 00000003 (40000000)
>>> IN:
>>> 0x00000400:  mtsprg  2,r2
>>>
>>> What comes after this is loading some values from the stack then 
>>> disabling MMU bits in MSR (then putting the values loaded into BAT 
>>> regs). If I could get these run without getting an ISI inbetween it 
>>> would boot:
>>>
>>>   41ce0c:       82 84 00 14     lwz     r20,20(r4)
>>>   41ce10:       82 a4 00 10     lwz     r21,16(r4)
>>>   41ce14:       82 c4 00 1c     lwz     r22,28(r4)
>>>   41ce18:       82 e4 00 18     lwz     r23,24(r4)
>>>   41ce1c:       83 05 00 04     lwz     r24,4(r5)
>>>   41ce20:       83 25 00 00     lwz     r25,0(r5)
>>>   41ce24:       83 45 00 0c     lwz     r26,12(r5)
>>>   41ce28:       83 65 00 08     lwz     r27,8(r5)
>>>   41ce2c:       83 85 00 14     lwz     r28,20(r5)
>>>   41ce30:       83 a5 00 10     lwz     r29,16(r5)
>>>   41ce34:       83 c5 00 1c     lwz     r30,28(r5)
>>>   41ce38:       83 e5 00 18     lwz     r31,24(r5)
>>>   41ce3c:       7c 00 04 ac     sync
>>>   41ce40:       7c 00 00 a6     mfmsr   r0
>>>   41ce44:       70 00 ff cf     andi.   r0,r0,65487
>>>   41ce48:       7c 00 04 ac     sync
>>>   41ce4c:       7c 00 01 24     mtmsr   r0
>>>   41ce50:       4c 00 01 2c     isync
>>>
>>> Why are we getting ISIs on QEMU and why can this work on real 
>>> hardware without crashing?
>>
>> We are getting ISIs because the HTAB is now 0 bytes long, so it 
>> doesn't contain any entries. Maybe it works on real hardware by 
>> accident because the translations are still in the TLB?
>
> If so then why is not that the case on QEMU and can it be changed? Is 
> the TLB flushed differently than real hardware? But I suspect the 
> cache to be a more likely explanation.

IIRC real hardware has a TLB and an ERAT, similar to L1 and L2 caches. 
QEMU only models a TLB - and even then takes the liberty of flushing 
entries whenever it wants to.

>
>> I think with MorphOS you're best off detecting that you are running 
>> MorphOS somehow (checksum over loaded files, specific client 
>> interface calls only it does) and set MSR.DR=0 and MSR.IR=0.
>
> This is extremely fragile and dependent on an exact version of 
> executable that I like to avoid. Is there a problem with always 
> disabling MMU bits when our vectors are overwritten? I guess that a 
> well behaved guest should disable these before overwriting the vectors 
> and enable them afterwards and for a buggy guest this would prevent 
> random crashes or may make it work as in case of MorphOS. The problem 
> is I don't know how to detect if the vectors are overwritten. I though 
> about checking it from dsi_exception handler, but here I don't get 
> more than one hits not like the ISI-s I don't want to happen. Do any 
> of you have an idea about how could this be done?

You could enable write protection on the first page before you enter the 
payload. Then you could unprotect it and disable interrupts as soon as 
someone wrote to it. I guess that'd be a pretty solid hack.


Alex




More information about the OpenBIOS mailing list