[OpenBIOS] [Qemu-ppc] Running client with MMU off
BALATON Zoltan
balaton at eik.bme.hu
Wed Jul 30 16:42:16 CEST 2014
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.
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?
Regards,
BALATON Zoltan
More information about the OpenBIOS
mailing list