[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:05:07 CEST 2016
> Am 22.06.2016 um 08:42 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 ...
>
> yes. I tried a couple of versions and that was the most friendly for the
> flush_icache_range.
Just call it for every instruction :)
Alex
>
>
>>> + 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++)
>>
>>>
>>> /************************************************************************/
>>> /* 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);
>>> + }
>>
>> Just fold all of this together. Make patch_rfi have no parameters and just call it unconditionally. Then check for ppc64 in there.
>
> ok. v3 on the way.
>
> Thanks,
>
> C.
>
>> Alex
>>
>>> +
>>> /* Enable MMU */
>>>
>>> mtmsr(mfmsr() | MSR_IR | MSR_DR);
>
More information about the OpenBIOS
mailing list