[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-ppc] [OpenBIOS] Running client with MMU off
From: |
Alexander Graf |
Subject: |
Re: [Qemu-ppc] [OpenBIOS] Running client with MMU off |
Date: |
Wed, 30 Jul 2014 16:49:56 +0200 |
> Am 30.07.2014 um 16:42 schrieb BALATON Zoltan <address@hidden>:
>
>> On Mon, 28 Jul 2014, Alexander Graf wrote:
>>> 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.
>
> They are probably on a stack somewhere but the handlers replace the stack if
> I remember correctly so it's not trivial to access that from C code.
Then pass a pointer to them to the C handler code?
> But my question was primarily about why the exception is retriggering? Do I
> need to do something else to signal to the CPU that the protection violation
> is handled or how can I ignore an exception so the execution continues?
If you don't fix up the reason why the interrupt occured in the first place it
will simply happen again.
Alex