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 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <sys/promif_impl.h>
28 #include <sys/uadmin.h>
29 #include <sys/machsystm.h>
30 #include <sys/hypervisor_api.h>
31 
32 #ifdef _KMDB
33 
34 extern int kmdb_dpi_get_master_cpuid(void);
35 extern void kmdb_dpi_kernpanic(int cpuid);
36 extern void prom_reboot(char *bootstr);
37 
38 #define	PIL_DECL(p)
39 #define	PIL_SET7(p)
40 #define	PIL_REST(p)
41 
42 #else
43 
44 extern int vx_handler(cell_t *argument_array);
45 extern void kldc_debug_enter(void);
46 
47 #define	PIL_DECL(p) int p
48 #define	PIL_SET7(p) (p = spl7())
49 #define	PIL_REST(p) (splx(p))
50 
51 #endif
52 
53 #define	PROMIF_ISPRINT(c)	(((c) >= ' ') && ((c) <= '~'))
54 
55 static int promif_ask_before_reset =
56 #ifdef _KMDB
57 	1;
58 #else
59 	0;
60 #endif
61 
62 /*ARGSUSED*/
63 int
promif_exit_to_mon(void * p)64 promif_exit_to_mon(void *p)
65 {
66 	PIL_DECL(pil);
67 
68 	PIL_SET7(pil);
69 
70 	prom_printf("Program terminated\n");
71 
72 	if (promif_ask_before_reset) {
73 		prom_printf("Press any key to reboot.");
74 		(void) prom_getchar();
75 	}
76 
77 	(void) hv_mach_sir();
78 
79 	/* should not return */
80 	ASSERT(0);
81 
82 	PIL_REST(pil);
83 
84 	return (0);
85 }
86 
87 /*ARGSUSED*/
88 int
promif_enter_mon(void * p)89 promif_enter_mon(void *p)
90 {
91 	char		cmd;
92 	static char	*prompt = "c)ontinue, s)ync, r)eset? ";
93 	PIL_DECL(pil);
94 
95 	PIL_SET7(pil);
96 
97 #ifndef _KMDB
98 	idle_other_cpus();
99 	kldc_debug_enter();
100 #endif
101 
102 	for (;;) {
103 		prom_printf("%s", prompt);
104 		cmd = promif_getchar();
105 		prom_printf("%c\n", cmd);
106 
107 		switch (cmd) {
108 
109 		case 'r':
110 			prom_printf("Resetting...\n");
111 
112 			(void) hv_mach_sir();
113 
114 			/* should not return */
115 			ASSERT(0);
116 			break;
117 
118 		case '\r':
119 			break;
120 
121 		case 's':
122 			{
123 #ifdef _KMDB
124 				kmdb_dpi_kernpanic(kmdb_dpi_get_master_cpuid());
125 #else
126 				cell_t arg = p1275_ptr2cell("sync");
127 
128 				(void) vx_handler(&arg);
129 #endif
130 			}
131 
132 			/* should not return */
133 			ASSERT(0);
134 			break;
135 
136 		case 'c':
137 #ifndef _KMDB
138 			resume_other_cpus();
139 #endif
140 			PIL_REST(pil);
141 
142 			return (0);
143 
144 		default:
145 			if (PROMIF_ISPRINT(cmd))
146 				prom_printf("invalid option (%c)\n", cmd);
147 			break;
148 		}
149 	}
150 
151 	_NOTE(NOTREACHED)
152 }
153