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

Cédric Le Goater clg at kaod.org
Wed Jun 22 11:21:55 CEST 2016


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.

 Changes since v3 :

 - fix pointer comparison 
 - make comments clearer

 Changes since v2 :

 - make it nicer

 arch/ppc/qemu/ofmem.c |   32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 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,36 @@ isi_exception(void)
     hash_page(nip, phys, mode);
 }
 
+/*
+ * Power ISA 2.x has deleted the rfi instruction and rfid shoud be
+ * used instead on cpus following this instruction set or later.
+ *
+ * OpenBIOS 32bits is compiled to use rfi. But, when it runs on a
+ * Power ISA 2.x cpu (a 970 for instance), we need to replace the rfi
+ * instructions with rfid in the vectors' memory section. Else we
+ * won't go any futher than the first exception ...
+ */
+#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++)  {
+        if (*ptr == RFI)
+            *ptr = RFID;
+    }
+    flush_icache_range((char*) vec_start , (char*) vec_end);
+}
 
 /************************************************************************/
 /*	init / cleanup							*/
@@ -532,6 +562,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);



More information about the OpenBIOS mailing list