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 2007 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.h>
30 #include <sys/promimpl.h>
31 
32 /*
33  * Because kmdb links prom_stdout_is_framebuffer into its own
34  * module and coherent console adds "device-type=console" for
35  * /os-io node, we also check if the device-type is "console",
36  * (if not "display"), so that prom_stdout_is_framebuffer still
37  * works corrrectly after /os-io node is registered into OBP.
38  */
39 int
prom_stdout_is_framebuffer(void)40 prom_stdout_is_framebuffer(void)
41 {
42 	static int remember = -1;
43 
44 	if (remember != -1)
45 		return (remember);
46 
47 	remember = prom_devicetype((pnode_t)prom_stdout_node(),
48 		OBP_DISPLAY);
49 
50 	if (remember == 0)
51 		remember = prom_devicetype((pnode_t)prom_stdout_node(),
52 			OBP_DISPLAY_CONSOLE);
53 
54 	return (remember);
55 }
56 
57 /*
58  * get inverse? and inverse-screen? property,
59  * -1 is returned if true, 0 is returned if false.
60  */
61 void
prom_get_tem_inverses(int * inverse,int * inverse_screen)62 prom_get_tem_inverses(int *inverse, int *inverse_screen)
63 {
64 	prom_interpret(
65 	    "my-self >r stdout @ is my-self "
66 	    "inverse? swap l! inverse-screen? swap l! "
67 	    "r> is my-self",
68 	    (uintptr_t)inverse, (uintptr_t)inverse_screen, 0, 0, 0);
69 }
70 
71 /*
72  * get current cursor position from the stdout handle, which
73  * containing the instance handle of the OBP console output device.
74  */
75 void
prom_get_tem_pos(uint32_t * row,uint32_t * col)76 prom_get_tem_pos(uint32_t *row, uint32_t *col)
77 {
78 	prom_interpret(
79 	    "my-self >r stdout @ is my-self "
80 	    "line# swap l! column# swap l! "
81 	    "r> is my-self",
82 	    (uintptr_t)row, (uintptr_t)col, 0, 0, 0);
83 }
84 
85 
86 /*
87  * get the font size and the start window top of
88  * OBP terminal emulator
89  */
90 void
prom_get_term_font_size(int * charheight,int * window_top)91 prom_get_term_font_size(int *charheight, int *window_top)
92 {
93 	prom_interpret(
94 	    "my-self >r stdout @ is my-self "
95 	    "char-height swap l! window-top swap l! "
96 	    "r> is my-self",
97 	    (uintptr_t)charheight, (uintptr_t)window_top, 0, 0, 0);
98 
99 }
100 
101 /* Clear the spining "|" character and hide the PROM cursor. */
102 void
prom_hide_cursor(void)103 prom_hide_cursor(void)
104 {
105 	prom_interpret(
106 	    "my-self >r stdout @ is my-self "
107 	    "toggle-cursor "
108 	    "1 delete-characters "
109 	    "r> is my-self",
110 	    0, 0, 0, 0, 0);
111 }
112 
113 static size_t
prom_atol(const char * str,int len)114 prom_atol(const char *str, int len)
115 {
116 	size_t n = 0;
117 
118 	while (len-- && (*str != '\0')) {
119 		n = n * 10 + (*str - '0');
120 		str++;
121 	}
122 
123 	return (n);
124 }
125 
126 /*
127  * Here we use the "screen-#columns" and "screen-#rows" settings of
128  * PROM to help us decide the console size and cursor position. The
129  * actual sizes of PROM's TEM and the console might be different with
130  * those "screen-#.." settings, in cases that they are too big to
131  * accommodate.
132  */
133 void
prom_get_tem_size(size_t * height,size_t * width)134 prom_get_tem_size(size_t *height, size_t *width)
135 {
136 	char buf[MAXPATHLEN];
137 	char name[16];
138 	pnode_t node;
139 	int len;
140 
141 	if ((node = prom_optionsnode()) == OBP_BADNODE)
142 		return;
143 
144 	(void) prom_strcpy(name, "screen-#rows");
145 	if ((len = prom_getproplen(node, (caddr_t)name)) > 0) {
146 		(void) prom_getprop(node, (caddr_t)name, (caddr_t)buf);
147 		*height = prom_atol(buf, len);
148 	}
149 
150 	(void) prom_strcpy(name, "screen-#columns");
151 	if ((len = prom_getproplen(node, (caddr_t)name)) > 0) {
152 		(void) prom_getprop(node, (caddr_t)name, (caddr_t)buf);
153 		*width = prom_atol(buf, len);
154 	}
155 }
156