Am 22.06.2016 um 09:29 schrieb Cédric Le Goater clg@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@kaod.org Suggested-by: Alexander Graf agraf@suse.de
Tested on qemu.
Changes since v2 :
- make it nicer
arch/ppc/qemu/ofmem.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 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,30 @@ 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.
Please use
/* * Comments like this */
and explain exactly why "we can not use rfi anymore", so that someone looking at the code in 5 years will still know what's going on.
- */
+#define RFI 0x4c000064 +#define RFID 0x4c000024
+extern char __vectors[]; +extern char __vectors_end[];
+static void patch_rfi(void) +{
- uint32_t* ptr;
- uint32_t* vec_start = (uint32_t*) 0x100UL;
- uint32_t* vec_end = (uint32_t*) (__vectors_end - __vectors);
- if (!is_ppc64())
return;
- for (ptr = vec_start; ptr < vec_end; ptr++) {
Last time I asked < was not really defined for pointers. You can only match (==, !=) or convert to numbers (uintptr_t) them. The smaller comparison might work for now, but I can't guarantee it won't break in gcc7 or so.
In short, please just make it != :).
Alex
if (*ptr == RFI)
*ptr = RFID;
- }
- flush_icache_range((char*) vec_start , (char*) vec_end);
+}
/************************************************************************/ /* init / cleanup */ @@ -532,6 +556,8 @@ setup_mmu(unsigned long ramsize)
memcpy((void *)get_rom_base(), (void *)OF_CODE_START, OF_CODE_SIZE);
patch_rfi();
/* Enable MMU */
mtmsr(mfmsr() | MSR_IR | MSR_DR);