powerpc/kexec_file: Enable early kernel OPAL calls
authorHari Bathini <hbathini@linux.ibm.com>
Wed, 29 Jul 2020 11:44:06 +0000 (17:14 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 29 Jul 2020 13:47:55 +0000 (23:47 +1000)
Kernels built with CONFIG_PPC_EARLY_DEBUG_OPAL enabled expects r8 & r9
to be filled with OPAL base & entry addresses respectively. Setting
these registers allows the kernel to perform OPAL calls before the
device tree is parsed.

Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
Reviewed-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/159602303975.575379.5032301944162937479.stgit@hbathini
arch/powerpc/kexec/file_load_64.c
arch/powerpc/purgatory/trampoline_64.S

index c6a37ad..53bb71e 100644 (file)
@@ -876,6 +876,7 @@ int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,
                          const void *fdt, unsigned long kernel_load_addr,
                          unsigned long fdt_load_addr)
 {
+       struct device_node *dn = NULL;
        int ret;
 
        ret = setup_purgatory(image, slave_code, fdt, kernel_load_addr,
@@ -903,9 +904,28 @@ int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,
                                             &image->arch.backup_start,
                                             sizeof(image->arch.backup_start),
                                             false);
+       if (ret)
+               goto out;
+
+       /* Setup OPAL base & entry values */
+       dn = of_find_node_by_path("/ibm,opal");
+       if (dn) {
+               u64 val;
+
+               of_property_read_u64(dn, "opal-base-address", &val);
+               ret = kexec_purgatory_get_set_symbol(image, "opal_base", &val,
+                                                    sizeof(val), false);
+               if (ret)
+                       goto out;
+
+               of_property_read_u64(dn, "opal-entry-address", &val);
+               ret = kexec_purgatory_get_set_symbol(image, "opal_entry", &val,
+                                                    sizeof(val), false);
+       }
 out:
        if (ret)
                pr_err("Failed to setup purgatory symbols");
+       of_node_put(dn);
        return ret;
 }
 
index b567da5..d956b8a 100644 (file)
@@ -87,6 +87,10 @@ master:
        li      %r4,28
        STWX_BE %r17,%r3,%r4    /* Store my cpu as __be32 at byte 28 */
 1:
+       /* Load opal base and entry values in r8 & r9 respectively */
+       ld      %r8,(opal_base - 0b)(%r18)
+       ld      %r9,(opal_entry - 0b)(%r18)
+
        /* load the kernel address */
        ld      %r4,(kernel - 0b)(%r18)
 
@@ -133,6 +137,18 @@ backup_start:
        .8byte  0x0
        .size backup_start, . - backup_start
 
+       .balign 8
+       .globl opal_base
+opal_base:
+       .8byte  0x0
+       .size opal_base, . - opal_base
+
+       .balign 8
+       .globl opal_entry
+opal_entry:
+       .8byte  0x0
+       .size opal_entry, . - opal_entry
+
        .data
        .balign 8
 .globl purgatory_sha256_digest