promif_reboot.c revision 1ae0874509b6811fdde1dfd46f0d93fd09867a3f
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * CDDL HEADER START
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * The contents of this file are subject to the terms of the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Common Development and Distribution License (the "License").
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * You may not use this file except in compliance with the License.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * or http://www.opensolaris.org/os/licensing.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * See the License for the specific language governing permissions
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * and limitations under the License.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * When distributing Covered Code, include this CDDL HEADER in each
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * If applicable, add the following below this CDDL HEADER, with the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * fields enclosed by brackets "[]" replaced with your own identifying
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * information: Portions Copyright [yyyy] [name of copyright owner]
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * CDDL HEADER END
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Use is subject to license terms.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#pragma ident "%Z%%M% %I% %E% SMI"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/promif_impl.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/hypervisor_api.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Reboot Command String
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * The prom_reboot() CIF handler takes an optional string containing
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * arguments to the boot command that are to be applied to the reboot.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * This information is used to create a full boot command string that
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * is stored in a well known ldom variable (REBOOT_CMD_VAR_NAME). The
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * string is constructed to take the following form:
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * boot <specified boot arguments><NULL>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * When the domain comes back up, OBP consults this variable. If set,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * it will use the unmodified boot command string to boot the domain.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * The maximum length of the boot command is specified by the constant
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * REBOOT_CMD_MAX_LEN. If the specified arguments cause the command
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * string to exceed this length, the arguments are truncated.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#define REBOOT_CMD_VAR_NAME "reboot-command"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#define REBOOT_CMD_BASE "boot "
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#define REBOOT_CMD_MAX_LEN 256
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#define REBOOT_CMD_ARGS_MAX_LEN (REBOOT_CMD_MAX_LEN - \
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_strlen(REBOOT_CMD_BASE) - 1)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoint
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_reboot(void *p)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cell_t *ci = (cell_t *)p;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int rv = 0;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#ifndef _KMDB
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char *bootargs;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char bootcmd[REBOOT_CMD_MAX_LEN];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char *cmd_end;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int cmd_len;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#endif
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* one argument expected */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(ci[1] == 1);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#ifndef _KMDB
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo bootargs = p1275_cell2ptr(ci[3]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (bootargs == NULL)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo bootargs = "";
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* verify the length of the command string */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmd_len = prom_strlen(REBOOT_CMD_BASE) + prom_strlen(bootargs) + 1;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (cmd_len > REBOOT_CMD_MAX_LEN) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Unable to set the requested boot arguments.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Truncate them so that the boot command will
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * fit within the maximum length. This follows
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * the policy also used by OBP.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmd_end = bootargs + REBOOT_CMD_ARGS_MAX_LEN;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *cmd_end = '\0';
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_printf("WARNING: reboot command length (%d) too long, "
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo "truncating command arguments\n", cmd_len);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* construct the boot command string */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) prom_sprintf(bootcmd, "%s%s", REBOOT_CMD_BASE, bootargs);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cmd_len = prom_strlen(bootcmd) + 1;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(cmd_len <= REBOOT_CMD_MAX_LEN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo CIF_DBG_REBOOT("bootcmd='%s'\n", bootcmd);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* attempt to set the ldom variable */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (promif_ldom_setprop(REBOOT_CMD_VAR_NAME, bootcmd, cmd_len) == -1) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_printf("WARNING: unable to store boot command for "
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo "use on reboot\n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#endif
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_printf("Resetting...\n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rv = hv_mach_sir();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* should not return */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ASSERT(0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}