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

Alexander Graf agraf at suse.de
Mon Jul 28 15:37:37 CEST 2014


On 27.06.14 23:34, BALATON Zoltan wrote:
> On Thu, 26 Jun 2014, Alexander Graf wrote:
>> On 26.06.14 13:20, BALATON Zoltan wrote:
>>> On Thu, 26 Jun 2014, Alexander Graf wrote:
>>>> 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.
>>>
>>> Good idea, I'll look into this. But 0x00-0xff is reserved for 
>>> operating system use and MorphOS does write to 0x80 before touching 
>>> the vectors (that's why I can't just check from the DSI handler). 
>>> Can I selectively enable writes on a write protected page? (I'll 
>>> need to read about it some more.)
>>
>> Not easily. You could emulate the 0x80 write maybe. Is it too early 
>> if you just disable DR/IR on the 0x80 touch? I don't think any other 
>> OS really accesses these ranges, but only time will tell ;).
>
> As a start I've tried this patch:
>
> --- a/openbios-devel/arch/ppc/qemu/ofmem.c
> +++ b/openbios-devel/arch/ppc/qemu/ofmem.c
> @@ -460,15 +460,26 @@ static void hash_page(unsigned long ea, 
> phys_addr_t phys,
>  void
>  dsi_exception(void)
>  {
> -    unsigned long dar, dsisr;
> +    unsigned long dar, dsisr, srr1;
>      ucell mode;
>      phys_addr_t phys;
>
>      asm volatile("mfdar %0" : "=r" (dar) : );
>      asm volatile("mfdsisr %0" : "=r" (dsisr) : );
> -
> +    asm volatile("mfsrr1 %0" : "=r" (srr1) : );
>      phys = ea_to_phys(dar, &mode);
> -    hash_page(dar, phys, mode);
> +
> +    if (dsisr & BIT(1)) {
> +        /* handle page fault */
> +        hash_page(dar, phys, mode);
> +    }
> +
> +    if (dsisr & BIT(4) && dar == 0) {
> +        /* handle protection violation */
> +        hash_page(dar, phys, mode);
> +        srr1 &= ~(MSR_IR | MSR_DR);
> +        asm volatile("mtsrr1 %0" :: "r" (srr1));
> +    }
>  }
>
>  void
> @@ -554,9 +565,10 @@ ofmem_init(void)
>      ofmem_claim_virt(PAGE_SIZE, get_ram_bottom() - PAGE_SIZE, 0);
>      ofmem_map(PAGE_SIZE, PAGE_SIZE, get_ram_bottom() - PAGE_SIZE, 0);
>
> -    /* Mark the first page as non-free */
> +    /* Mark the first page as non-free and write protect it */
>      ofmem_claim_phys(0, PAGE_SIZE, 0);
>      ofmem_claim_virt(0, PAGE_SIZE, 0);
> +    hash_page(0, 0, 3);
>
>      /* Map everything at the top of physical RAM 1:1, minus the 
> OpenBIOS ROM in
>      ofmem_claim_phys(get_ram_top(), get_hash_base() + HASH_SIZE - 
> get_ram_top()
>
> which does not break Finnix but does not work with MorphOS because it 
> catches the write to 0x80 as it should but instead of ignoring it this 
> protection violation exception is always retrigerring infinitely and 
> it does not go further. What am I missing to ignore protection 
> violations for writes to page 0 without emulating the writes at the 
> moment. (The initial write to 0x80 is setting it to 0 which is the 
> value it already has.) Unfortunatly it is hard to debug because if I 
> call printk from the exception handler it seems to break beyond repair 
> possibly due to side effects.
>
> I've also looked at the code you've referred to but that uses kvm 
> functions not included in the patch so it may be more complicated than 
> that. If I get it correctly I can get the instruction from the address 
> in srr0, the target memory cell from dar but still need to find out 
> the source which is probably a register that does not contain the 
> value by the time I get it so it may not be trivial to emulate the write.

They have to be somewhere, because we have to swap them all back in 
after the interrupt.


Alex




More information about the OpenBIOS mailing list