[PATCH] powerpc/powernv: Remove OPAL v1 takeover
Mike Qiu
qiudayu at linux.vnet.ibm.com
Tue Jun 24 17:50:47 EST 2014
Reported-and-tested-by: Mike Qiu <qiudayu at linux.vnet.ibm.com>
Thanks
Mike
On 06/24/2014 03:17 PM, Michael Ellerman wrote:
> 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 at ellerman.id.au>
> ---
> arch/powerpc/Kconfig.debug | 1 -
> arch/powerpc/include/asm/opal.h | 29 ----
> arch/powerpc/kernel/prom.c | 7 -
> arch/powerpc/kernel/prom_init.c | 211 -------------------------
> arch/powerpc/kernel/prom_init_check.sh | 4 +-
> arch/powerpc/platforms/powernv/Makefile | 2 +-
> arch/powerpc/platforms/powernv/opal-takeover.S | 140 ----------------
> 7 files changed, 2 insertions(+), 392 deletions(-)
> delete mode 100644 arch/powerpc/platforms/powernv/opal-takeover.S
>
> diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
> index 790352f..35d16bd 100644
> --- a/arch/powerpc/Kconfig.debug
> +++ b/arch/powerpc/Kconfig.debug
> @@ -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.
>
> diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
> index 4600188..0da1dbd 100644
> --- a/arch/powerpc/include/asm/opal.h
> +++ b/arch/powerpc/include/asm/opal.h
> @@ -12,27 +12,7 @@
> #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 ******/
> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> index 613a860..b694b07 100644
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -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 ...
> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index 078145a..1a85d8f 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -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 */
> diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh
> index 77aa1e9..fe8e54b 100644
> --- a/arch/powerpc/kernel/prom_init_check.sh
> +++ b/arch/powerpc/kernel/prom_init_check.sh
> @@ -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"
> diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
> index d55891f..4ad227d 100644
> --- a/arch/powerpc/platforms/powernv/Makefile
> +++ b/arch/powerpc/platforms/powernv/Makefile
> @@ -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
> index 11a3169..0000000
> --- a/arch/powerpc/platforms/powernv/opal-takeover.S
> +++ /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
More information about the Linuxppc-dev
mailing list