[OpenBIOS] [PATCH v2] ppc: use rfid when running under a CPU from the 970 family.

Alexander Graf agraf at suse.de
Wed Jun 22 09:19:18 CEST 2016



> Am 22.06.2016 um 09:08 schrieb Cédric Le Goater <clg at kaod.org>:
> 
>> On 06/22/2016 06:50 AM, Alexander Graf wrote:
>> 
>> 
>>> Am 21.06.2016 um 23:36 schrieb Cédric Le Goater <clg at kaod.org>:
>>> 
>>> A recent attempt to restrict the use of rfi on 64bit cpus in qemu
>>> broke 32bit OpenBIOS when run under a 970.
>>> 
>>> This patches memory to replace rfi instructions with rfid in the
>>> vector code.
>>> 
>>> Signed-off-by: Cédric Le Goater <clg at kaod.org>
>>> Suggested-by: Alexander Graf <agraf at suse.de>
>>> ---
>>> 
>>> Tested on qemu.
>>> 
>>> arch/ppc/qemu/ofmem.c |   24 ++++++++++++++++++++++++
>>> 1 file changed, 24 insertions(+)
>>> 
>>> Index: openbios.git/arch/ppc/qemu/ofmem.c
>>> ===================================================================
>>> --- openbios.git.orig/arch/ppc/qemu/ofmem.c
>>> +++ openbios.git/arch/ppc/qemu/ofmem.c
>>> @@ -478,6 +478,26 @@ isi_exception(void)
>>>    hash_page(nip, phys, mode);
>>> }
>>> 
>>> +/* When running on ppc64, we cannot use rfi anymore. Let's patch the
>>> + * vectors to use rfid instead.
>>> + */
>>> +#define RFI     0x4c000064
>>> +#define RFID    0x4c000024
>>> +
>>> +static void patch_rfi(char *from, uint32_t len)
>>> +{
>>> +    int i;
>>> +
>>> +    for (i = 0; i < len; i += 4)  {
>>> +        uint32_t* addr = (uint32_t *) (from + i);
>> 
>> If you use a uint32* here you can just increment by 1 ...
>> 
>>> +        if (*addr == RFI)
>>> +            *addr = RFID;
>>> +    }
>>> +    flush_icache_range(from, from + len);
>>> +}
>>> +
>>> +extern char __vectors[];
>>> +extern char __vectors_end[];
>> 
>> And in fact you can just loop from vectors until ptr==vectors_end.
>> 
>> uint32_t *ptr;
>> 
>> for (ptr = __vectors; ptr != __vectors_end; ptr++)
> 
> ah, we can not do that, we need to patch the memory and not the rom, so 
> [ 0,  __vectors_end - __vectors]

Aaah, I see. Then your version makes more sense.

> 
> C. 
> 
>> 
>>> 
>>> /************************************************************************/
>>> /*    init / cleanup                            */
>>> @@ -532,6 +552,10 @@ setup_mmu(unsigned long ramsize)
>>> 
>>>    memcpy((void *)get_rom_base(), (void *)OF_CODE_START, OF_CODE_SIZE);
>>> 
>>> +    if (is_ppc64()) {
>>> +        patch_rfi(0x0, (uint32_t) __vectors_end - (uint32_t) __vectors);

Please cast to uintptr_t instead though :)

Alex

>>> +    }
>> 
>> Just fold all of this together. Make patch_rfi have no parameters and just call it unconditionally. Then check for ppc64 in there.
>> 
>> Alex
>> 
>>> +
>>>    /* Enable MMU */
>>> 
>>>    mtmsr(mfmsr() | MSR_IR | MSR_DR);
> 




More information about the OpenBIOS mailing list