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 */
39int
40prom_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 */
61void
62prom_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 */
75void
76prom_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 */
90void
91prom_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. */
102void
103prom_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
113static size_t
114prom_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 */
133void
134prom_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