1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/promif_impl.h> 30 #include <sys/hypervisor_api.h> 31 32 /* 33 * Reboot Command String 34 * 35 * The prom_reboot() CIF handler takes an optional string containing 36 * arguments to the boot command that are to be applied to the reboot. 37 * This information is used to create a full boot command string that 38 * is stored in a well known ldom variable (REBOOT_CMD_VAR_NAME). The 39 * string is constructed to take the following form: 40 * 41 * boot <specified boot arguments><NULL> 42 * 43 * When the domain comes back up, OBP consults this variable. If set, 44 * it will use the unmodified boot command string to boot the domain. 45 * The maximum length of the boot command is specified by the constant 46 * REBOOT_CMD_MAX_LEN. If the specified arguments cause the command 47 * string to exceed this length, the arguments are truncated. 48 */ 49 #define REBOOT_CMD_VAR_NAME "reboot-command" 50 #define REBOOT_CMD_BASE "boot " 51 #define REBOOT_CMD_MAX_LEN 256 52 #define REBOOT_CMD_ARGS_MAX_LEN (REBOOT_CMD_MAX_LEN - \ 53 prom_strlen(REBOOT_CMD_BASE) - 1) 54 int 55 promif_reboot(void *p) 56 { 57 cell_t *ci = (cell_t *)p; 58 int rv = 0; 59 #ifndef _KMDB 60 char *bootargs; 61 char bootcmd[REBOOT_CMD_MAX_LEN]; 62 char *cmd_end; 63 int cmd_len; 64 #endif 65 66 /* one argument expected */ 67 ASSERT(ci[1] == 1); 68 69 #ifndef _KMDB 70 bootargs = p1275_cell2ptr(ci[3]); 71 72 if (bootargs == NULL) 73 bootargs = ""; 74 75 /* verify the length of the command string */ 76 cmd_len = prom_strlen(REBOOT_CMD_BASE) + prom_strlen(bootargs) + 1; 77 78 if (cmd_len > REBOOT_CMD_MAX_LEN) { 79 /* 80 * Unable to set the requested boot arguments. 81 * Truncate them so that the boot command will 82 * fit within the maximum length. This follows 83 * the policy also used by OBP. 84 */ 85 cmd_end = bootargs + REBOOT_CMD_ARGS_MAX_LEN; 86 *cmd_end = '\0'; 87 88 prom_printf("WARNING: reboot command length (%d) too long, " 89 "truncating command arguments\n", cmd_len); 90 } 91 92 /* construct the boot command string */ 93 (void) prom_sprintf(bootcmd, "%s%s", REBOOT_CMD_BASE, bootargs); 94 95 cmd_len = prom_strlen(bootcmd) + 1; 96 ASSERT(cmd_len <= REBOOT_CMD_MAX_LEN); 97 98 CIF_DBG_REBOOT("bootcmd='%s'\n", bootcmd); 99 100 /* attempt to set the ldom variable */ 101 if (promif_ldom_setprop(REBOOT_CMD_VAR_NAME, bootcmd, cmd_len) == -1) { 102 prom_printf("WARNING: unable to store boot command for " 103 "use on reboot\n"); 104 } 105 #endif 106 107 prom_printf("Resetting...\n"); 108 109 rv = hv_mach_sir(); 110 111 /* should not return */ 112 ASSERT(0); 113 114 return (rv); 115 } 116