Am 22.06.2016 um 08:42 schrieb Cédric Le Goater clg@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@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.
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);