powerpc: Fix up RTAS invocation for new qemu versions
In order to call RTAS functions on powerpc kvm-unit-tests relies on the
RTAS blob supplied by qemu. But new versions of qemu don't supply an RTAS
blob: since the normal way for guests to get RTAS is to call the guest
firmware's instantiate-rtas function, we now rely on that guest firmware
to provide the RTAS code itself.
But qemu-kvm-tests bypasses the usual guest firmware to just run itself,
so we can't get the rtas blob from SLOF.
But.. in fact the RTAS blob under qemu is a bit of a sham anyway - it's
a tiny wrapper that forwards the RTAS call to a hypercall. So, we can
just invoke that hypercall directly.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Message-Id: <20191004103844.32590-1-david@gibson.dropbear.id.au>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
diff --git a/lib/powerpc/asm/hcall.h b/lib/powerpc/asm/hcall.h
index a8bd7e3..1173fea 100644
--- a/lib/powerpc/asm/hcall.h
+++ b/lib/powerpc/asm/hcall.h
@@ -24,6 +24,9 @@
#define H_RANDOM 0x300
#define H_SET_MODE 0x31C
+#define KVMPPC_HCALL_BASE 0xf000
+#define KVMPPC_H_RTAS (KVMPPC_HCALL_BASE + 0x0)
+
#ifndef __ASSEMBLY__
/*
* hcall_have_broken_sc1 checks if we're on a host with a broken sc1.
diff --git a/lib/powerpc/rtas.c b/lib/powerpc/rtas.c
index 2e7e0da..41c0a24 100644
--- a/lib/powerpc/rtas.c
+++ b/lib/powerpc/rtas.c
@@ -46,9 +46,9 @@
prop = fdt_get_property(dt_fdt(), node,
"linux,rtas-entry", &len);
if (!prop) {
- printf("%s: /rtas/linux,rtas-entry: %s\n",
- __func__, fdt_strerror(len));
- abort();
+ /* We don't have a qemu provided RTAS blob, enter_rtas
+ * will use H_RTAS directly */
+ return;
}
data = (u32 *)prop->data;
rtas_entry = (unsigned long)fdt32_to_cpu(*data);
diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
index ec673b3..972851f 100644
--- a/powerpc/cstart64.S
+++ b/powerpc/cstart64.S
@@ -121,13 +121,25 @@
.globl enter_rtas
enter_rtas:
+ LOAD_REG_ADDR(r11, rtas_entry)
+ ld r10, 0(r11)
+
+ cmpdi r10,0
+ bne external_rtas
+
+ /* Use H_RTAS directly */
+ mr r4,r3
+ lis r3,KVMPPC_H_RTAS@h
+ ori r3,r3,KVMPPC_H_RTAS@l
+ b hcall
+
+external_rtas:
+ /* Use external RTAS blob */
mflr r0
std r0, 16(r1)
- LOAD_REG_ADDR(r10, rtas_return_loc)
- mtlr r10
- LOAD_REG_ADDR(r11, rtas_entry)
- ld r10, 0(r11)
+ LOAD_REG_ADDR(r11, rtas_return_loc)
+ mtlr r11
mfmsr r11
LOAD_REG_IMMEDIATE(r9, RTAS_MSR_MASK)