powerpc/powernv: Remove OPAL v1 takeover
authorMichael Ellerman <mpe@ellerman.id.au>
Tue, 24 Jun 2014 07:17:47 +0000 (17:17 +1000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 25 Jun 2014 03:10:47 +0000 (13:10 +1000)
In commit 27f4488872d9 "Add OPAL takeover from PowerVM" we added support
for "takeover" on OPAL v1 machines.

This was a mode of operation where we would boot under pHyp, and query
for the presence of OPAL. If detected we would then do a special
sequence to take over the machine, and the kernel would end up running
in hypervisor mode.

OPAL v1 was never a supported product, and was never shipped outside
IBM. As far as we know no one is still using it.

Newer versions of OPAL do not use the takeover mechanism. Although the
query for OPAL should be harmless on machines with newer OPAL, we have
seen a machine where it causes a crash in Open Firmware.

The code in early_init_devtree() to copy boot_command_line into cmd_line
was added in commit 817c21ad9a1f "Get kernel command line accross OPAL
takeover", and AFAIK is only used by takeover, so should also be
removed.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/Kconfig.debug
arch/powerpc/include/asm/opal.h
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/prom_init_check.sh
arch/powerpc/platforms/powernv/Makefile
arch/powerpc/platforms/powernv/opal-takeover.S [deleted file]

index 790352f..35d16bd 100644 (file)
@@ -303,7 +303,6 @@ config PPC_EARLY_DEBUG_OPAL_VTERMNO
          This correspond to which /dev/hvcN you want to use for early
          debug.
 
-         On OPAL v1 (takeover) this should always be 0
          On OPAL v2, this will be 0 for network console and 1 or 2 for
          the machine built-in serial ports.
 
index 4600188..0da1dbd 100644 (file)
 #ifndef __OPAL_H
 #define __OPAL_H
 
-/****** Takeover interface ********/
-
-/* PAPR H-Call used to querty the HAL existence and/or instanciate
- * it from within pHyp (tech preview only).
- *
- * This is exclusively used in prom_init.c
- */
-
 #ifndef __ASSEMBLY__
-
-struct opal_takeover_args {
-       u64     k_image;                /* r4 */
-       u64     k_size;                 /* r5 */
-       u64     k_entry;                /* r6 */
-       u64     k_entry2;               /* r7 */
-       u64     hal_addr;               /* r8 */
-       u64     rd_image;               /* r9 */
-       u64     rd_size;                /* r10 */
-       u64     rd_loc;                 /* r11 */
-};
-
 /*
  * SG entry
  *
@@ -55,15 +35,6 @@ struct opal_sg_list {
 /* We calculate number of sg entries based on PAGE_SIZE */
 #define SG_ENTRIES_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct opal_sg_entry))
 
-extern long opal_query_takeover(u64 *hal_size, u64 *hal_align);
-
-extern long opal_do_takeover(struct opal_takeover_args *args);
-
-struct rtas_args;
-extern int opal_enter_rtas(struct rtas_args *args,
-                          unsigned long data,
-                          unsigned long entry);
-
 #endif /* __ASSEMBLY__ */
 
 /****** OPAL APIs ******/
index 613a860..b694b07 100644 (file)
@@ -662,13 +662,6 @@ void __init early_init_devtree(void *params)
        of_scan_flat_dt(early_init_dt_scan_fw_dump, NULL);
 #endif
 
-       /* Pre-initialize the cmd_line with the content of boot_commmand_line,
-        * which will be empty except when the content of the variable has
-        * been overriden by a bootloading mechanism. This happens typically
-        * with HAL takeover
-        */
-       strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
-
        /* Retrieve various informations from the /chosen node of the
         * device-tree, including the platform type, initrd location and
         * size, TCE reserve, and more ...
index 078145a..1a85d8f 100644 (file)
@@ -1268,201 +1268,6 @@ static u64 __initdata prom_opal_base;
 static u64 __initdata prom_opal_entry;
 #endif
 
-#ifdef __BIG_ENDIAN__
-/* XXX Don't change this structure without updating opal-takeover.S */
-static struct opal_secondary_data {
-       s64                             ack;    /*  0 */
-       u64                             go;     /*  8 */
-       struct opal_takeover_args       args;   /* 16 */
-} opal_secondary_data;
-
-static u64 __initdata prom_opal_align;
-static u64 __initdata prom_opal_size;
-static int __initdata prom_rtas_start_cpu;
-static u64 __initdata prom_rtas_data;
-static u64 __initdata prom_rtas_entry;
-
-extern char opal_secondary_entry;
-
-static void __init prom_query_opal(void)
-{
-       long rc;
-
-       /* We must not query for OPAL presence on a machine that
-        * supports TNK takeover (970 blades), as this uses the same
-        * h-call with different arguments and will crash
-        */
-       if (PHANDLE_VALID(call_prom("finddevice", 1, 1,
-                                   ADDR("/tnk-memory-map")))) {
-               prom_printf("TNK takeover detected, skipping OPAL check\n");
-               return;
-       }
-
-       prom_printf("Querying for OPAL presence... ");
-
-       rc = opal_query_takeover(&prom_opal_size,
-                                &prom_opal_align);
-       prom_debug("(rc = %ld) ", rc);
-       if (rc != 0) {
-               prom_printf("not there.\n");
-               return;
-       }
-       of_platform = PLATFORM_OPAL;
-       prom_printf(" there !\n");
-       prom_debug("  opal_size  = 0x%lx\n", prom_opal_size);
-       prom_debug("  opal_align = 0x%lx\n", prom_opal_align);
-       if (prom_opal_align < 0x10000)
-               prom_opal_align = 0x10000;
-}
-
-static int __init prom_rtas_call(int token, int nargs, int nret,
-                                int *outputs, ...)
-{
-       struct rtas_args rtas_args;
-       va_list list;
-       int i;
-
-       rtas_args.token = token;
-       rtas_args.nargs = nargs;
-       rtas_args.nret  = nret;
-       rtas_args.rets  = (rtas_arg_t *)&(rtas_args.args[nargs]);
-       va_start(list, outputs);
-       for (i = 0; i < nargs; ++i)
-               rtas_args.args[i] = va_arg(list, rtas_arg_t);
-       va_end(list);
-
-       for (i = 0; i < nret; ++i)
-               rtas_args.rets[i] = 0;
-
-       opal_enter_rtas(&rtas_args, prom_rtas_data,
-                       prom_rtas_entry);
-
-       if (nret > 1 && outputs != NULL)
-               for (i = 0; i < nret-1; ++i)
-                       outputs[i] = rtas_args.rets[i+1];
-       return (nret > 0)? rtas_args.rets[0]: 0;
-}
-
-static void __init prom_opal_hold_cpus(void)
-{
-       int i, cnt, cpu, rc;
-       long j;
-       phandle node;
-       char type[64];
-       u32 servers[8];
-       void *entry = (unsigned long *)&opal_secondary_entry;
-       struct opal_secondary_data *data = &opal_secondary_data;
-
-       prom_debug("prom_opal_hold_cpus: start...\n");
-       prom_debug("    - entry       = 0x%x\n", entry);
-       prom_debug("    - data        = 0x%x\n", data);
-
-       data->ack = -1;
-       data->go = 0;
-
-       /* look for cpus */
-       for (node = 0; prom_next_node(&node); ) {
-               type[0] = 0;
-               prom_getprop(node, "device_type", type, sizeof(type));
-               if (strcmp(type, "cpu") != 0)
-                       continue;
-
-               /* Skip non-configured cpus. */
-               if (prom_getprop(node, "status", type, sizeof(type)) > 0)
-                       if (strcmp(type, "okay") != 0)
-                               continue;
-
-               cnt = prom_getprop(node, "ibm,ppc-interrupt-server#s", servers,
-                            sizeof(servers));
-               if (cnt == PROM_ERROR)
-                       break;
-               cnt >>= 2;
-               for (i = 0; i < cnt; i++) {
-                       cpu = servers[i];
-                       prom_debug("CPU %d ... ", cpu);
-                       if (cpu == prom.cpu) {
-                               prom_debug("booted !\n");
-                               continue;
-                       }
-                       prom_debug("starting ... ");
-
-                       /* Init the acknowledge var which will be reset by
-                        * the secondary cpu when it awakens from its OF
-                        * spinloop.
-                        */
-                       data->ack = -1;
-                       rc = prom_rtas_call(prom_rtas_start_cpu, 3, 1,
-                                           NULL, cpu, entry, data);
-                       prom_debug("rtas rc=%d ...", rc);
-
-                       for (j = 0; j < 100000000 && data->ack == -1; j++) {
-                               HMT_low();
-                               mb();
-                       }
-                       HMT_medium();
-                       if (data->ack != -1)
-                               prom_debug("done, PIR=0x%x\n", data->ack);
-                       else
-                               prom_debug("timeout !\n");
-               }
-       }
-       prom_debug("prom_opal_hold_cpus: end...\n");
-}
-
-static void __init prom_opal_takeover(void)
-{
-       struct opal_secondary_data *data = &opal_secondary_data;
-       struct opal_takeover_args *args = &data->args;
-       u64 align = prom_opal_align;
-       u64 top_addr, opal_addr;
-
-       args->k_image   = (u64)_stext;
-       args->k_size    = _end - _stext;
-       args->k_entry   = 0;
-       args->k_entry2  = 0x60;
-
-       top_addr = _ALIGN_UP(args->k_size, align);
-
-       if (prom_initrd_start != 0) {
-               args->rd_image = prom_initrd_start;
-               args->rd_size = prom_initrd_end - args->rd_image;
-               args->rd_loc = top_addr;
-               top_addr = _ALIGN_UP(args->rd_loc + args->rd_size, align);
-       }
-
-       /* Pickup an address for the HAL. We want to go really high
-        * up to avoid problem with future kexecs. On the other hand
-        * we don't want to be all over the TCEs on P5IOC2 machines
-        * which are going to be up there too. We assume the machine
-        * has plenty of memory, and we ask for the HAL for now to
-        * be just below the 1G point, or above the initrd
-        */
-       opal_addr = _ALIGN_DOWN(0x40000000 - prom_opal_size, align);
-       if (opal_addr < top_addr)
-               opal_addr = top_addr;
-       args->hal_addr = opal_addr;
-
-       /* Copy the command line to the kernel image */
-       strlcpy(boot_command_line, prom_cmd_line,
-               COMMAND_LINE_SIZE);
-
-       prom_debug("  k_image    = 0x%lx\n", args->k_image);
-       prom_debug("  k_size     = 0x%lx\n", args->k_size);
-       prom_debug("  k_entry    = 0x%lx\n", args->k_entry);
-       prom_debug("  k_entry2   = 0x%lx\n", args->k_entry2);
-       prom_debug("  hal_addr   = 0x%lx\n", args->hal_addr);
-       prom_debug("  rd_image   = 0x%lx\n", args->rd_image);
-       prom_debug("  rd_size    = 0x%lx\n", args->rd_size);
-       prom_debug("  rd_loc     = 0x%lx\n", args->rd_loc);
-       prom_printf("Performing OPAL takeover,this can take a few minutes..\n");
-       prom_close_stdin();
-       mb();
-       data->go = 1;
-       for (;;)
-               opal_do_takeover(args);
-}
-#endif /* __BIG_ENDIAN__ */
-
 /*
  * Allocate room for and instantiate OPAL
  */
@@ -1597,12 +1402,6 @@ static void __init prom_instantiate_rtas(void)
                         &val, sizeof(val)) != PROM_ERROR)
                rtas_has_query_cpu_stopped = true;
 
-#if defined(CONFIG_PPC_POWERNV) && defined(__BIG_ENDIAN__)
-       /* PowerVN takeover hack */
-       prom_rtas_data = base;
-       prom_rtas_entry = entry;
-       prom_getprop(rtas_node, "start-cpu", &prom_rtas_start_cpu, 4);
-#endif
        prom_debug("rtas base     = 0x%x\n", base);
        prom_debug("rtas entry    = 0x%x\n", entry);
        prom_debug("rtas size     = 0x%x\n", (long)size);
@@ -3027,16 +2826,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
                prom_instantiate_rtas();
 
 #ifdef CONFIG_PPC_POWERNV
-#ifdef __BIG_ENDIAN__
-       /* Detect HAL and try instanciating it & doing takeover */
-       if (of_platform == PLATFORM_PSERIES_LPAR) {
-               prom_query_opal();
-               if (of_platform == PLATFORM_OPAL) {
-                       prom_opal_hold_cpus();
-                       prom_opal_takeover();
-               }
-       } else
-#endif /* __BIG_ENDIAN__ */
        if (of_platform == PLATFORM_OPAL)
                prom_instantiate_opal();
 #endif /* CONFIG_PPC_POWERNV */
index 77aa1e9..fe8e54b 100644 (file)
@@ -21,9 +21,7 @@ _end enter_prom memcpy memset reloc_offset __secondary_hold
 __secondary_hold_acknowledge __secondary_hold_spinloop __start
 strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224
 reloc_got2 kernstart_addr memstart_addr linux_banner _stext
-opal_query_takeover opal_do_takeover opal_enter_rtas opal_secondary_entry
-boot_command_line __prom_init_toc_start __prom_init_toc_end
-btext_setup_display TOC."
+__prom_init_toc_start __prom_init_toc_end btext_setup_display TOC."
 
 NM="$1"
 OBJ="$2"
index d55891f..4ad227d 100644 (file)
@@ -1,4 +1,4 @@
-obj-y                  += setup.o opal-takeover.o opal-wrappers.o opal.o opal-async.o
+obj-y                  += setup.o opal-wrappers.o opal.o opal-async.o
 obj-y                  += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
 obj-y                  += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o
 obj-y                  += opal-msglog.o
diff --git a/arch/powerpc/platforms/powernv/opal-takeover.S b/arch/powerpc/platforms/powernv/opal-takeover.S
deleted file mode 100644 (file)
index 11a3169..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * PowerNV OPAL takeover assembly code, for use by prom_init.c
- *
- * Copyright 2011 IBM Corp.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <asm/ppc_asm.h>
-#include <asm/hvcall.h>
-#include <asm/asm-offsets.h>
-#include <asm/opal.h>
-
-#define H_HAL_TAKEOVER                 0x5124
-#define H_HAL_TAKEOVER_QUERY_MAGIC     -1
-
-       .text
-_GLOBAL(opal_query_takeover)
-       mfcr    r0
-       stw     r0,8(r1)
-       stdu    r1,-STACKFRAMESIZE(r1)
-       std     r3,STK_PARAM(R3)(r1)
-       std     r4,STK_PARAM(R4)(r1)
-       li      r3,H_HAL_TAKEOVER
-       li      r4,H_HAL_TAKEOVER_QUERY_MAGIC
-       HVSC
-       addi    r1,r1,STACKFRAMESIZE
-       ld      r10,STK_PARAM(R3)(r1)
-       std     r4,0(r10)
-       ld      r10,STK_PARAM(R4)(r1)
-       std     r5,0(r10)
-       lwz     r0,8(r1)
-       mtcrf   0xff,r0
-       blr
-
-_GLOBAL(opal_do_takeover)
-       mfcr    r0
-       stw     r0,8(r1)
-       mflr    r0
-       std     r0,16(r1)
-       bl      __opal_do_takeover
-       ld      r0,16(r1)
-       mtlr    r0
-       lwz     r0,8(r1)
-       mtcrf   0xff,r0
-       blr
-
-__opal_do_takeover:
-       ld      r4,0(r3)
-       ld      r5,0x8(r3)
-       ld      r6,0x10(r3)
-       ld      r7,0x18(r3)
-       ld      r8,0x20(r3)
-       ld      r9,0x28(r3)
-       ld      r10,0x30(r3)
-       ld      r11,0x38(r3)
-       li      r3,H_HAL_TAKEOVER
-       HVSC
-       blr
-
-       .globl opal_secondary_entry
-opal_secondary_entry:
-       mr      r31,r3
-       mfmsr   r11
-       li      r12,(MSR_SF | MSR_ISF)@highest
-       sldi    r12,r12,48
-       or      r11,r11,r12
-       mtmsrd  r11
-       isync
-       mfspr   r4,SPRN_PIR
-       std     r4,0(r3)
-1:     HMT_LOW
-       ld      r4,8(r3)
-       cmpli   cr0,r4,0
-       beq     1b
-       HMT_MEDIUM
-1:     addi    r3,r31,16
-       bl      __opal_do_takeover
-       b       1b
-
-_GLOBAL(opal_enter_rtas)
-       mflr    r0
-       std     r0,16(r1)
-        stdu   r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */
-
-       /* Because PROM is running in 32b mode, it clobbers the high order half
-        * of all registers that it saves.  We therefore save those registers
-        * PROM might touch to the stack.  (r0, r3-r13 are caller saved)
-       */
-       SAVE_GPR(2, r1)
-       SAVE_GPR(13, r1)
-       SAVE_8GPRS(14, r1)
-       SAVE_10GPRS(22, r1)
-       mfcr    r10
-       mfmsr   r11
-       std     r10,_CCR(r1)
-       std     r11,_MSR(r1)
-
-       /* Get the PROM entrypoint */
-       mtlr    r5
-
-       /* Switch MSR to 32 bits mode
-        */
-        li      r12,1
-        rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
-        andc    r11,r11,r12
-        li      r12,1
-        rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
-        andc    r11,r11,r12
-        mtmsrd  r11
-        isync
-
-       /* Enter RTAS here... */
-       blrl
-
-       /* Just make sure that r1 top 32 bits didn't get
-        * corrupt by OF
-        */
-       rldicl  r1,r1,0,32
-
-       /* Restore the MSR (back to 64 bits) */
-       ld      r0,_MSR(r1)
-       MTMSRD(r0)
-        isync
-
-       /* Restore other registers */
-       REST_GPR(2, r1)
-       REST_GPR(13, r1)
-       REST_8GPRS(14, r1)
-       REST_10GPRS(22, r1)
-       ld      r4,_CCR(r1)
-       mtcr    r4
-
-        addi   r1,r1,PROM_FRAME_SIZE
-       ld      r0,16(r1)
-       mtlr    r0
-       blr