1fea9cb91Slq150181 /*
2fea9cb91Slq150181 * CDDL HEADER START
3fea9cb91Slq150181 *
4fea9cb91Slq150181 * The contents of this file are subject to the terms of the
5fea9cb91Slq150181 * Common Development and Distribution License (the "License").
6fea9cb91Slq150181 * You may not use this file except in compliance with the License.
7fea9cb91Slq150181 *
8fea9cb91Slq150181 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fea9cb91Slq150181 * or http://www.opensolaris.org/os/licensing.
10fea9cb91Slq150181 * See the License for the specific language governing permissions
11fea9cb91Slq150181 * and limitations under the License.
12fea9cb91Slq150181 *
13fea9cb91Slq150181 * When distributing Covered Code, include this CDDL HEADER in each
14fea9cb91Slq150181 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fea9cb91Slq150181 * If applicable, add the following below this CDDL HEADER, with the
16fea9cb91Slq150181 * fields enclosed by brackets "[]" replaced with your own identifying
17fea9cb91Slq150181 * information: Portions Copyright [yyyy] [name of copyright owner]
18fea9cb91Slq150181 *
19fea9cb91Slq150181 * CDDL HEADER END
20fea9cb91Slq150181 */
21fea9cb91Slq150181
22fea9cb91Slq150181 /*
23b52fe415Slipeng sang - Sun Microsystems - Beijing China * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24fea9cb91Slq150181 * Use is subject to license terms.
25fea9cb91Slq150181 */
26fea9cb91Slq150181
27fea9cb91Slq150181 /*
28fea9cb91Slq150181 * ANSI terminal emulator module; parse ANSI X3.64 escape sequences and
29fea9cb91Slq150181 * the like.
30*aecfc01dSrui zang - Sun Microsystems - Beijing China *
31*aecfc01dSrui zang - Sun Microsystems - Beijing China * How Virtual Terminal Emulator Works:
32*aecfc01dSrui zang - Sun Microsystems - Beijing China *
33*aecfc01dSrui zang - Sun Microsystems - Beijing China * Every virtual terminal is associated with a tem_vt_state structure
34*aecfc01dSrui zang - Sun Microsystems - Beijing China * and maintains a virtual screen buffer in tvs_screen_buf, which contains
35*aecfc01dSrui zang - Sun Microsystems - Beijing China * all the characters which should be shown on the physical screen when
36*aecfc01dSrui zang - Sun Microsystems - Beijing China * the terminal is activated. There are also two other buffers, tvs_fg_buf
37*aecfc01dSrui zang - Sun Microsystems - Beijing China * and tvs_bg_buf, which track the foreground and background colors of the
38*aecfc01dSrui zang - Sun Microsystems - Beijing China * on screen characters
39*aecfc01dSrui zang - Sun Microsystems - Beijing China *
40*aecfc01dSrui zang - Sun Microsystems - Beijing China * Data written to a virtual terminal is composed of characters which
41*aecfc01dSrui zang - Sun Microsystems - Beijing China * should be displayed on the screen when this virtual terminal is
42*aecfc01dSrui zang - Sun Microsystems - Beijing China * activated, fg/bg colors of these characters, and other control
43*aecfc01dSrui zang - Sun Microsystems - Beijing China * information (escape sequence, etc).
44*aecfc01dSrui zang - Sun Microsystems - Beijing China *
45*aecfc01dSrui zang - Sun Microsystems - Beijing China * When data is passed to a virtual terminal it first is parsed for
46*aecfc01dSrui zang - Sun Microsystems - Beijing China * control information by tem_safe_parse(). Subsequently the character
47*aecfc01dSrui zang - Sun Microsystems - Beijing China * and color data are written to tvs_screen_buf, tvs_fg_buf, and
48*aecfc01dSrui zang - Sun Microsystems - Beijing China * tvs_bg_buf. They are saved in these buffers in order to refresh
49*aecfc01dSrui zang - Sun Microsystems - Beijing China * the screen when this terminal is activated. If the terminal is
50*aecfc01dSrui zang - Sun Microsystems - Beijing China * currently active, the data (characters and colors) are also written
51*aecfc01dSrui zang - Sun Microsystems - Beijing China * to the physical screen by invoking a callback function,
52*aecfc01dSrui zang - Sun Microsystems - Beijing China * tem_safe_text_callbacks() or tem_safe_pix_callbacks().
53*aecfc01dSrui zang - Sun Microsystems - Beijing China *
54*aecfc01dSrui zang - Sun Microsystems - Beijing China * When rendering data to the framebuffer, if the framebuffer is in
55*aecfc01dSrui zang - Sun Microsystems - Beijing China * VIS_PIXEL mode, the character data will first be converted to pixel
56*aecfc01dSrui zang - Sun Microsystems - Beijing China * data using tem_safe_pix_bit2pix(), and then the pixels get displayed
57*aecfc01dSrui zang - Sun Microsystems - Beijing China * on the physical screen. We only store the character and color data in
58*aecfc01dSrui zang - Sun Microsystems - Beijing China * tem_vt_state since the bit2pix conversion only happens when actually
59*aecfc01dSrui zang - Sun Microsystems - Beijing China * rendering to the physical framebuffer.
60fea9cb91Slq150181 */
61fea9cb91Slq150181
62*aecfc01dSrui zang - Sun Microsystems - Beijing China
63fea9cb91Slq150181 #include <sys/types.h>
64fea9cb91Slq150181 #include <sys/file.h>
65fea9cb91Slq150181 #include <sys/conf.h>
66fea9cb91Slq150181 #include <sys/errno.h>
67fea9cb91Slq150181 #include <sys/open.h>
68fea9cb91Slq150181 #include <sys/cred.h>
69fea9cb91Slq150181 #include <sys/kmem.h>
70fea9cb91Slq150181 #include <sys/ascii.h>
71fea9cb91Slq150181 #include <sys/consdev.h>
72fea9cb91Slq150181 #include <sys/font.h>
73fea9cb91Slq150181 #include <sys/fbio.h>
74fea9cb91Slq150181 #include <sys/conf.h>
75fea9cb91Slq150181 #include <sys/modctl.h>
76fea9cb91Slq150181 #include <sys/strsubr.h>
77fea9cb91Slq150181 #include <sys/stat.h>
78fea9cb91Slq150181 #include <sys/visual_io.h>
79fea9cb91Slq150181 #include <sys/mutex.h>
80fea9cb91Slq150181 #include <sys/param.h>
81fea9cb91Slq150181 #include <sys/debug.h>
82fea9cb91Slq150181 #include <sys/cmn_err.h>
83fea9cb91Slq150181 #include <sys/console.h>
84fea9cb91Slq150181 #include <sys/ddi.h>
85fea9cb91Slq150181 #include <sys/sunddi.h>
86fea9cb91Slq150181 #include <sys/sunldi.h>
87fea9cb91Slq150181 #include <sys/tem_impl.h>
88fea9cb91Slq150181 #ifdef _HAVE_TEM_FIRMWARE
89fea9cb91Slq150181 #include <sys/promif.h>
90fea9cb91Slq150181 #endif /* _HAVE_TEM_FIRMWARE */
91b52fe415Slipeng sang - Sun Microsystems - Beijing China #include <sys/consplat.h>
92*aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/kd.h>
93*aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/sysmacros.h>
94*aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/note.h>
95*aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/t_lock.h>
96fea9cb91Slq150181
97*aecfc01dSrui zang - Sun Microsystems - Beijing China /* Terminal emulator internal helper functions */
98*aecfc01dSrui zang - Sun Microsystems - Beijing China static void tems_setup_terminal(struct vis_devinit *, size_t, size_t);
99*aecfc01dSrui zang - Sun Microsystems - Beijing China static void tems_modechange_callback(struct vis_modechg_arg *,
100*aecfc01dSrui zang - Sun Microsystems - Beijing China struct vis_devinit *);
101*aecfc01dSrui zang - Sun Microsystems - Beijing China
102*aecfc01dSrui zang - Sun Microsystems - Beijing China static void tems_reset_colormap(cred_t *, enum called_from);
103*aecfc01dSrui zang - Sun Microsystems - Beijing China
104*aecfc01dSrui zang - Sun Microsystems - Beijing China static void tem_free_buf(struct tem_vt_state *);
105*aecfc01dSrui zang - Sun Microsystems - Beijing China static void tem_internal_init(struct tem_vt_state *, cred_t *, boolean_t,
106*aecfc01dSrui zang - Sun Microsystems - Beijing China boolean_t);
107*aecfc01dSrui zang - Sun Microsystems - Beijing China static void tems_get_initial_color(tem_color_t *pcolor);
108fea9cb91Slq150181
109fea9cb91Slq150181 /*
110fea9cb91Slq150181 * Globals
111fea9cb91Slq150181 */
112*aecfc01dSrui zang - Sun Microsystems - Beijing China static ldi_ident_t term_li = NULL;
113*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_state_t tems; /* common term info */
114*aecfc01dSrui zang - Sun Microsystems - Beijing China _NOTE(MUTEX_PROTECTS_DATA(tems.ts_lock, tems))
115fea9cb91Slq150181
116fea9cb91Slq150181 extern struct mod_ops mod_miscops;
117fea9cb91Slq150181
118fea9cb91Slq150181 static struct modlmisc modlmisc = {
119fea9cb91Slq150181 &mod_miscops, /* modops */
120fea9cb91Slq150181 "ANSI Terminal Emulator", /* name */
121fea9cb91Slq150181 };
122fea9cb91Slq150181
123fea9cb91Slq150181 static struct modlinkage modlinkage = {
124fea9cb91Slq150181 MODREV_1, (void *)&modlmisc, NULL
125fea9cb91Slq150181 };
126fea9cb91Slq150181
127fea9cb91Slq150181 int
_init(void)128fea9cb91Slq150181 _init(void)
129fea9cb91Slq150181 {
130fea9cb91Slq150181 int ret;
131fea9cb91Slq150181 ret = mod_install(&modlinkage);
132fea9cb91Slq150181 if (ret != 0)
133fea9cb91Slq150181 return (ret);
134fea9cb91Slq150181 ret = ldi_ident_from_mod(&modlinkage, &term_li);
135fea9cb91Slq150181 if (ret != 0) {
136fea9cb91Slq150181 (void) mod_remove(&modlinkage);
137fea9cb91Slq150181 return (ret);
138fea9cb91Slq150181 }
139*aecfc01dSrui zang - Sun Microsystems - Beijing China
140*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_init(&tems.ts_lock, (char *)NULL, MUTEX_DRIVER, NULL);
141*aecfc01dSrui zang - Sun Microsystems - Beijing China list_create(&tems.ts_list, sizeof (struct tem_vt_state),
142*aecfc01dSrui zang - Sun Microsystems - Beijing China offsetof(struct tem_vt_state, tvs_list_node));
143*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_active = NULL;
144*aecfc01dSrui zang - Sun Microsystems - Beijing China
145fea9cb91Slq150181 return (0);
146fea9cb91Slq150181 }
147fea9cb91Slq150181
148fea9cb91Slq150181 int
_fini()149fea9cb91Slq150181 _fini()
150fea9cb91Slq150181 {
151fea9cb91Slq150181 int ret;
152fea9cb91Slq150181
153fea9cb91Slq150181 ret = mod_remove(&modlinkage);
154fea9cb91Slq150181 if (ret == 0) {
155fea9cb91Slq150181 ldi_ident_release(term_li);
156fea9cb91Slq150181 term_li = NULL;
157fea9cb91Slq150181 }
158fea9cb91Slq150181 return (ret);
159fea9cb91Slq150181 }
160fea9cb91Slq150181
161fea9cb91Slq150181 int
_info(struct modinfo * modinfop)162fea9cb91Slq150181 _info(struct modinfo *modinfop)
163fea9cb91Slq150181 {
164fea9cb91Slq150181 return (mod_info(&modlinkage, modinfop));
165fea9cb91Slq150181 }
166fea9cb91Slq150181
167*aecfc01dSrui zang - Sun Microsystems - Beijing China static void
tem_add(struct tem_vt_state * tem)168*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_add(struct tem_vt_state *tem)
169fea9cb91Slq150181 {
170*aecfc01dSrui zang - Sun Microsystems - Beijing China ASSERT(MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock));
171fea9cb91Slq150181
172*aecfc01dSrui zang - Sun Microsystems - Beijing China list_insert_head(&tems.ts_list, tem);
173fea9cb91Slq150181 }
174fea9cb91Slq150181
175fea9cb91Slq150181 static void
tem_rm(struct tem_vt_state * tem)176*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_rm(struct tem_vt_state *tem)
177fea9cb91Slq150181 {
178*aecfc01dSrui zang - Sun Microsystems - Beijing China ASSERT(MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock));
179fea9cb91Slq150181
180*aecfc01dSrui zang - Sun Microsystems - Beijing China list_remove(&tems.ts_list, tem);
181fea9cb91Slq150181 }
182fea9cb91Slq150181
183fea9cb91Slq150181 /*
184fea9cb91Slq150181 * This is the main entry point to the module. It handles output requests
185fea9cb91Slq150181 * during normal system operation, when (e.g.) mutexes are available.
186fea9cb91Slq150181 */
187fea9cb91Slq150181 void
tem_write(tem_vt_state_t tem_arg,uchar_t * buf,ssize_t len,cred_t * credp)188*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_write(tem_vt_state_t tem_arg, uchar_t *buf, ssize_t len, cred_t *credp)
189fea9cb91Slq150181 {
190*aecfc01dSrui zang - Sun Microsystems - Beijing China struct tem_vt_state *tem = (struct tem_vt_state *)tem_arg;
191fea9cb91Slq150181
192*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&tems.ts_lock);
193*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&tem->tvs_lock);
194fea9cb91Slq150181
195*aecfc01dSrui zang - Sun Microsystems - Beijing China if (!tem->tvs_initialized) {
196*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tem->tvs_lock);
197*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
198*aecfc01dSrui zang - Sun Microsystems - Beijing China return;
199*aecfc01dSrui zang - Sun Microsystems - Beijing China }
200fea9cb91Slq150181
201*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_check_first_time(tem, credp, CALLED_FROM_NORMAL);
202*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_terminal_emulate(tem, buf, len, credp, CALLED_FROM_NORMAL);
203*aecfc01dSrui zang - Sun Microsystems - Beijing China
204*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tem->tvs_lock);
205*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
206*aecfc01dSrui zang - Sun Microsystems - Beijing China }
207*aecfc01dSrui zang - Sun Microsystems - Beijing China
208*aecfc01dSrui zang - Sun Microsystems - Beijing China static void
tem_internal_init(struct tem_vt_state * ptem,cred_t * credp,boolean_t init_color,boolean_t clear_screen)209*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_internal_init(struct tem_vt_state *ptem, cred_t *credp,
210*aecfc01dSrui zang - Sun Microsystems - Beijing China boolean_t init_color, boolean_t clear_screen)
211*aecfc01dSrui zang - Sun Microsystems - Beijing China {
212*aecfc01dSrui zang - Sun Microsystems - Beijing China int i, j;
213*aecfc01dSrui zang - Sun Microsystems - Beijing China int width, height;
214*aecfc01dSrui zang - Sun Microsystems - Beijing China int total;
215*aecfc01dSrui zang - Sun Microsystems - Beijing China text_color_t fg;
216*aecfc01dSrui zang - Sun Microsystems - Beijing China text_color_t bg;
217*aecfc01dSrui zang - Sun Microsystems - Beijing China size_t tc_size = sizeof (text_color_t);
218*aecfc01dSrui zang - Sun Microsystems - Beijing China
219*aecfc01dSrui zang - Sun Microsystems - Beijing China ASSERT(MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&ptem->tvs_lock));
220*aecfc01dSrui zang - Sun Microsystems - Beijing China
221*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tems.ts_display_mode == VIS_PIXEL) {
222*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem->tvs_pix_data_size = tems.ts_pix_data_size;
223*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem->tvs_pix_data =
224*aecfc01dSrui zang - Sun Microsystems - Beijing China kmem_alloc(ptem->tvs_pix_data_size, KM_SLEEP);
225*aecfc01dSrui zang - Sun Microsystems - Beijing China }
226*aecfc01dSrui zang - Sun Microsystems - Beijing China
227*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem->tvs_outbuf_size = tems.ts_c_dimension.width;
228*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem->tvs_outbuf =
229*aecfc01dSrui zang - Sun Microsystems - Beijing China (unsigned char *)kmem_alloc(ptem->tvs_outbuf_size, KM_SLEEP);
230*aecfc01dSrui zang - Sun Microsystems - Beijing China
231*aecfc01dSrui zang - Sun Microsystems - Beijing China width = tems.ts_c_dimension.width;
232*aecfc01dSrui zang - Sun Microsystems - Beijing China height = tems.ts_c_dimension.height;
233*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem->tvs_screen_buf_size = width * height;
234*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem->tvs_screen_buf =
235*aecfc01dSrui zang - Sun Microsystems - Beijing China (unsigned char *)kmem_alloc(width * height, KM_SLEEP);
236*aecfc01dSrui zang - Sun Microsystems - Beijing China
237*aecfc01dSrui zang - Sun Microsystems - Beijing China total = width * height * tc_size;
238*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem->tvs_fg_buf = (text_color_t *)kmem_alloc(total, KM_SLEEP);
239*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem->tvs_bg_buf = (text_color_t *)kmem_alloc(total, KM_SLEEP);
240*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem->tvs_color_buf_size = total;
241*aecfc01dSrui zang - Sun Microsystems - Beijing China
242*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_reset_display(ptem, credp, CALLED_FROM_NORMAL,
243*aecfc01dSrui zang - Sun Microsystems - Beijing China clear_screen, init_color);
244*aecfc01dSrui zang - Sun Microsystems - Beijing China
245*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_get_color(ptem, &fg, &bg, TEM_ATTR_SCREEN_REVERSE);
246*aecfc01dSrui zang - Sun Microsystems - Beijing China for (i = 0; i < height; i++)
247*aecfc01dSrui zang - Sun Microsystems - Beijing China for (j = 0; j < width; j++) {
248*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem->tvs_screen_buf[i * width + j] = ' ';
249*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem->tvs_fg_buf[(i * width +j) * tc_size] = fg;
250*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem->tvs_bg_buf[(i * width +j) * tc_size] = bg;
251*aecfc01dSrui zang - Sun Microsystems - Beijing China
252*aecfc01dSrui zang - Sun Microsystems - Beijing China }
253*aecfc01dSrui zang - Sun Microsystems - Beijing China
254*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem->tvs_initialized = 1;
255fea9cb91Slq150181 }
256fea9cb91Slq150181
257fea9cb91Slq150181 int
tem_initialized(tem_vt_state_t tem_arg)258*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_initialized(tem_vt_state_t tem_arg)
259fea9cb91Slq150181 {
260*aecfc01dSrui zang - Sun Microsystems - Beijing China struct tem_vt_state *ptem = (struct tem_vt_state *)tem_arg;
261*aecfc01dSrui zang - Sun Microsystems - Beijing China int ret;
262*aecfc01dSrui zang - Sun Microsystems - Beijing China
263*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&ptem->tvs_lock);
264*aecfc01dSrui zang - Sun Microsystems - Beijing China ret = ptem->tvs_initialized;
265*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&ptem->tvs_lock);
266*aecfc01dSrui zang - Sun Microsystems - Beijing China
267*aecfc01dSrui zang - Sun Microsystems - Beijing China return (ret);
268*aecfc01dSrui zang - Sun Microsystems - Beijing China }
269*aecfc01dSrui zang - Sun Microsystems - Beijing China
270*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_vt_state_t
tem_init(cred_t * credp)271*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_init(cred_t *credp)
272*aecfc01dSrui zang - Sun Microsystems - Beijing China {
273*aecfc01dSrui zang - Sun Microsystems - Beijing China struct tem_vt_state *ptem;
274*aecfc01dSrui zang - Sun Microsystems - Beijing China
275*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem = kmem_zalloc(sizeof (struct tem_vt_state), KM_SLEEP);
276*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_init(&ptem->tvs_lock, (char *)NULL, MUTEX_DRIVER, NULL);
277*aecfc01dSrui zang - Sun Microsystems - Beijing China
278*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&tems.ts_lock);
279*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&ptem->tvs_lock);
280*aecfc01dSrui zang - Sun Microsystems - Beijing China
281*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem->tvs_isactive = B_FALSE;
282*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem->tvs_fbmode = KD_TEXT;
283*aecfc01dSrui zang - Sun Microsystems - Beijing China
284*aecfc01dSrui zang - Sun Microsystems - Beijing China /*
285*aecfc01dSrui zang - Sun Microsystems - Beijing China * A tem is regarded as initialized only after tem_internal_init(),
286*aecfc01dSrui zang - Sun Microsystems - Beijing China * will be set at the end of tem_internal_init().
287*aecfc01dSrui zang - Sun Microsystems - Beijing China */
288*aecfc01dSrui zang - Sun Microsystems - Beijing China ptem->tvs_initialized = 0;
289*aecfc01dSrui zang - Sun Microsystems - Beijing China
290*aecfc01dSrui zang - Sun Microsystems - Beijing China
291*aecfc01dSrui zang - Sun Microsystems - Beijing China if (!tems.ts_initialized) {
292*aecfc01dSrui zang - Sun Microsystems - Beijing China /*
293*aecfc01dSrui zang - Sun Microsystems - Beijing China * Only happens during early console configuration.
294*aecfc01dSrui zang - Sun Microsystems - Beijing China */
295*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_add(ptem);
296*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&ptem->tvs_lock);
297*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
298*aecfc01dSrui zang - Sun Microsystems - Beijing China return ((tem_vt_state_t)ptem);
299*aecfc01dSrui zang - Sun Microsystems - Beijing China }
300*aecfc01dSrui zang - Sun Microsystems - Beijing China
301*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_internal_init(ptem, credp, B_TRUE, B_FALSE);
302*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_add(ptem);
303*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&ptem->tvs_lock);
304*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
305*aecfc01dSrui zang - Sun Microsystems - Beijing China
306*aecfc01dSrui zang - Sun Microsystems - Beijing China return ((tem_vt_state_t)ptem);
307*aecfc01dSrui zang - Sun Microsystems - Beijing China }
308*aecfc01dSrui zang - Sun Microsystems - Beijing China
309*aecfc01dSrui zang - Sun Microsystems - Beijing China /*
310*aecfc01dSrui zang - Sun Microsystems - Beijing China * re-init the tem after video mode has changed and tems_info has
311*aecfc01dSrui zang - Sun Microsystems - Beijing China * been re-inited. The lock is already held.
312*aecfc01dSrui zang - Sun Microsystems - Beijing China */
313*aecfc01dSrui zang - Sun Microsystems - Beijing China static void
tem_reinit(struct tem_vt_state * tem,boolean_t reset_display)314*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_reinit(struct tem_vt_state *tem, boolean_t reset_display)
315*aecfc01dSrui zang - Sun Microsystems - Beijing China {
316*aecfc01dSrui zang - Sun Microsystems - Beijing China ASSERT(MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock));
317*aecfc01dSrui zang - Sun Microsystems - Beijing China
318*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_free_buf(tem); /* only free virtual buffers */
319*aecfc01dSrui zang - Sun Microsystems - Beijing China
320*aecfc01dSrui zang - Sun Microsystems - Beijing China /* reserve color */
321*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_internal_init(tem, kcred, B_FALSE, reset_display);
322*aecfc01dSrui zang - Sun Microsystems - Beijing China }
323*aecfc01dSrui zang - Sun Microsystems - Beijing China
324*aecfc01dSrui zang - Sun Microsystems - Beijing China static void
tem_free_buf(struct tem_vt_state * tem)325*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_free_buf(struct tem_vt_state *tem)
326*aecfc01dSrui zang - Sun Microsystems - Beijing China {
327*aecfc01dSrui zang - Sun Microsystems - Beijing China ASSERT(tem != NULL && MUTEX_HELD(&tem->tvs_lock));
328*aecfc01dSrui zang - Sun Microsystems - Beijing China
329*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tem->tvs_outbuf != NULL)
330*aecfc01dSrui zang - Sun Microsystems - Beijing China kmem_free(tem->tvs_outbuf, tem->tvs_outbuf_size);
331*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tem->tvs_pix_data != NULL)
332*aecfc01dSrui zang - Sun Microsystems - Beijing China kmem_free(tem->tvs_pix_data, tem->tvs_pix_data_size);
333*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tem->tvs_screen_buf != NULL)
334*aecfc01dSrui zang - Sun Microsystems - Beijing China kmem_free(tem->tvs_screen_buf, tem->tvs_screen_buf_size);
335*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tem->tvs_fg_buf != NULL)
336*aecfc01dSrui zang - Sun Microsystems - Beijing China kmem_free(tem->tvs_fg_buf, tem->tvs_color_buf_size);
337*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tem->tvs_bg_buf != NULL)
338*aecfc01dSrui zang - Sun Microsystems - Beijing China kmem_free(tem->tvs_bg_buf, tem->tvs_color_buf_size);
339*aecfc01dSrui zang - Sun Microsystems - Beijing China }
340*aecfc01dSrui zang - Sun Microsystems - Beijing China
341*aecfc01dSrui zang - Sun Microsystems - Beijing China void
tem_destroy(tem_vt_state_t tem_arg,cred_t * credp)342*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_destroy(tem_vt_state_t tem_arg, cred_t *credp)
343*aecfc01dSrui zang - Sun Microsystems - Beijing China {
344*aecfc01dSrui zang - Sun Microsystems - Beijing China struct tem_vt_state *tem = (struct tem_vt_state *)tem_arg;
345*aecfc01dSrui zang - Sun Microsystems - Beijing China
346*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&tems.ts_lock);
347*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&tem->tvs_lock);
348*aecfc01dSrui zang - Sun Microsystems - Beijing China
349*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tem->tvs_isactive && tem->tvs_fbmode == KD_TEXT)
350*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_blank_screen(tem, credp, CALLED_FROM_NORMAL);
351*aecfc01dSrui zang - Sun Microsystems - Beijing China
352*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_free_buf(tem);
353*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_rm(tem);
354*aecfc01dSrui zang - Sun Microsystems - Beijing China
355*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tems.ts_active == tem)
356*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_active = NULL;
357*aecfc01dSrui zang - Sun Microsystems - Beijing China
358*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tem->tvs_lock);
359*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
360*aecfc01dSrui zang - Sun Microsystems - Beijing China
361*aecfc01dSrui zang - Sun Microsystems - Beijing China kmem_free(tem, sizeof (struct tem_vt_state));
362*aecfc01dSrui zang - Sun Microsystems - Beijing China }
363*aecfc01dSrui zang - Sun Microsystems - Beijing China
364*aecfc01dSrui zang - Sun Microsystems - Beijing China static int
tems_failed(cred_t * credp,boolean_t finish_ioctl)365*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_failed(cred_t *credp, boolean_t finish_ioctl)
366*aecfc01dSrui zang - Sun Microsystems - Beijing China {
367fea9cb91Slq150181 int lyr_rval;
368fea9cb91Slq150181
369*aecfc01dSrui zang - Sun Microsystems - Beijing China ASSERT(MUTEX_HELD(&tems.ts_lock));
370fea9cb91Slq150181
371*aecfc01dSrui zang - Sun Microsystems - Beijing China if (finish_ioctl)
372*aecfc01dSrui zang - Sun Microsystems - Beijing China (void) ldi_ioctl(tems.ts_hdl, VIS_DEVFINI, 0,
373*aecfc01dSrui zang - Sun Microsystems - Beijing China FWRITE|FKIOCTL, credp, &lyr_rval);
374fea9cb91Slq150181
375*aecfc01dSrui zang - Sun Microsystems - Beijing China (void) ldi_close(tems.ts_hdl, NULL, credp);
376*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_hdl = NULL;
377*aecfc01dSrui zang - Sun Microsystems - Beijing China return (ENXIO);
378*aecfc01dSrui zang - Sun Microsystems - Beijing China }
379*aecfc01dSrui zang - Sun Microsystems - Beijing China
380*aecfc01dSrui zang - Sun Microsystems - Beijing China /*
381*aecfc01dSrui zang - Sun Microsystems - Beijing China * only called once during boot
382*aecfc01dSrui zang - Sun Microsystems - Beijing China */
383*aecfc01dSrui zang - Sun Microsystems - Beijing China int
tem_info_init(char * pathname,cred_t * credp)384*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_info_init(char *pathname, cred_t *credp)
385*aecfc01dSrui zang - Sun Microsystems - Beijing China {
386*aecfc01dSrui zang - Sun Microsystems - Beijing China int lyr_rval, ret;
387*aecfc01dSrui zang - Sun Microsystems - Beijing China struct vis_devinit temargs;
388*aecfc01dSrui zang - Sun Microsystems - Beijing China char *pathbuf;
389*aecfc01dSrui zang - Sun Microsystems - Beijing China size_t height = 0;
390*aecfc01dSrui zang - Sun Microsystems - Beijing China size_t width = 0;
391*aecfc01dSrui zang - Sun Microsystems - Beijing China struct tem_vt_state *p;
392*aecfc01dSrui zang - Sun Microsystems - Beijing China
393*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&tems.ts_lock);
394*aecfc01dSrui zang - Sun Microsystems - Beijing China
395*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tems.ts_initialized) {
396*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
397*aecfc01dSrui zang - Sun Microsystems - Beijing China return (0);
398*aecfc01dSrui zang - Sun Microsystems - Beijing China }
399fea9cb91Slq150181
400fea9cb91Slq150181 /*
401fea9cb91Slq150181 * Open the layered device using the devfs physical device name
402fea9cb91Slq150181 * after adding the /devices prefix.
403fea9cb91Slq150181 */
404fea9cb91Slq150181 pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
405fea9cb91Slq150181 (void) strcpy(pathbuf, "/devices");
406fea9cb91Slq150181 if (i_ddi_prompath_to_devfspath(pathname,
407fea9cb91Slq150181 pathbuf + strlen("/devices")) != DDI_SUCCESS) {
408*aecfc01dSrui zang - Sun Microsystems - Beijing China cmn_err(CE_WARN, "terminal-emulator: path conversion error");
409fea9cb91Slq150181 kmem_free(pathbuf, MAXPATHLEN);
410*aecfc01dSrui zang - Sun Microsystems - Beijing China
411*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
412fea9cb91Slq150181 return (ENXIO);
413fea9cb91Slq150181 }
414*aecfc01dSrui zang - Sun Microsystems - Beijing China if (ldi_open_by_name(pathbuf, FWRITE, credp,
415*aecfc01dSrui zang - Sun Microsystems - Beijing China &tems.ts_hdl, term_li) != 0) {
416*aecfc01dSrui zang - Sun Microsystems - Beijing China cmn_err(CE_WARN, "terminal-emulator: device path open error");
417fea9cb91Slq150181 kmem_free(pathbuf, MAXPATHLEN);
418*aecfc01dSrui zang - Sun Microsystems - Beijing China
419*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
420fea9cb91Slq150181 return (ENXIO);
421fea9cb91Slq150181 }
422fea9cb91Slq150181 kmem_free(pathbuf, MAXPATHLEN);
423fea9cb91Slq150181
424*aecfc01dSrui zang - Sun Microsystems - Beijing China temargs.modechg_cb = (vis_modechg_cb_t)tems_modechange_callback;
425*aecfc01dSrui zang - Sun Microsystems - Beijing China temargs.modechg_arg = NULL;
426fea9cb91Slq150181
427fea9cb91Slq150181 /*
428fea9cb91Slq150181 * Initialize the console and get the device parameters
429fea9cb91Slq150181 */
430*aecfc01dSrui zang - Sun Microsystems - Beijing China if (ldi_ioctl(tems.ts_hdl, VIS_DEVINIT,
431*aecfc01dSrui zang - Sun Microsystems - Beijing China (intptr_t)&temargs, FWRITE|FKIOCTL, credp, &lyr_rval) != 0) {
432fea9cb91Slq150181 cmn_err(CE_WARN, "terminal emulator: Compatible fb not found");
433*aecfc01dSrui zang - Sun Microsystems - Beijing China ret = tems_failed(credp, B_FALSE);
434*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
435*aecfc01dSrui zang - Sun Microsystems - Beijing China return (ret);
436fea9cb91Slq150181 }
437fea9cb91Slq150181
438fea9cb91Slq150181 /* Make sure the fb driver and terminal emulator versions match */
439*aecfc01dSrui zang - Sun Microsystems - Beijing China if (temargs.version != VIS_CONS_REV) {
440fea9cb91Slq150181 cmn_err(CE_WARN,
441fea9cb91Slq150181 "terminal emulator: VIS_CONS_REV %d (see sys/visual_io.h) "
442*aecfc01dSrui zang - Sun Microsystems - Beijing China "of console fb driver not supported", temargs.version);
443*aecfc01dSrui zang - Sun Microsystems - Beijing China ret = tems_failed(credp, B_TRUE);
444*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
445*aecfc01dSrui zang - Sun Microsystems - Beijing China return (ret);
446fea9cb91Slq150181 }
447fea9cb91Slq150181
448*aecfc01dSrui zang - Sun Microsystems - Beijing China if ((tems.ts_fb_polledio = temargs.polledio) == NULL) {
449fea9cb91Slq150181 cmn_err(CE_WARN, "terminal emulator: fb doesn't support polled "
450fea9cb91Slq150181 "I/O");
451*aecfc01dSrui zang - Sun Microsystems - Beijing China ret = tems_failed(credp, B_TRUE);
452*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
453*aecfc01dSrui zang - Sun Microsystems - Beijing China return (ret);
454fea9cb91Slq150181 }
455fea9cb91Slq150181
456fea9cb91Slq150181 /* other sanity checks */
457*aecfc01dSrui zang - Sun Microsystems - Beijing China if (!((temargs.depth == 4) || (temargs.depth == 8) ||
458*aecfc01dSrui zang - Sun Microsystems - Beijing China (temargs.depth == 24) || (temargs.depth == 32))) {
459fea9cb91Slq150181 cmn_err(CE_WARN, "terminal emulator: unsupported depth");
460*aecfc01dSrui zang - Sun Microsystems - Beijing China ret = tems_failed(credp, B_TRUE);
461*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
462*aecfc01dSrui zang - Sun Microsystems - Beijing China return (ret);
463fea9cb91Slq150181 }
464fea9cb91Slq150181
465*aecfc01dSrui zang - Sun Microsystems - Beijing China if ((temargs.mode != VIS_TEXT) && (temargs.mode != VIS_PIXEL)) {
466fea9cb91Slq150181 cmn_err(CE_WARN, "terminal emulator: unsupported mode");
467*aecfc01dSrui zang - Sun Microsystems - Beijing China ret = tems_failed(credp, B_TRUE);
468*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
469*aecfc01dSrui zang - Sun Microsystems - Beijing China return (ret);
470fea9cb91Slq150181 }
471fea9cb91Slq150181
472*aecfc01dSrui zang - Sun Microsystems - Beijing China if ((temargs.mode == VIS_PIXEL) && plat_stdout_is_framebuffer())
473fea9cb91Slq150181 plat_tem_get_prom_size(&height, &width);
474*aecfc01dSrui zang - Sun Microsystems - Beijing China
475*aecfc01dSrui zang - Sun Microsystems - Beijing China /*
476*aecfc01dSrui zang - Sun Microsystems - Beijing China * Initialize the common terminal emulator info
477*aecfc01dSrui zang - Sun Microsystems - Beijing China */
478*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_setup_terminal(&temargs, height, width);
479*aecfc01dSrui zang - Sun Microsystems - Beijing China
480*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_reset_colormap(credp, CALLED_FROM_NORMAL);
481*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_get_initial_color(&tems.ts_init_color);
482*aecfc01dSrui zang - Sun Microsystems - Beijing China
483*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_initialized = 1; /* initialization flag */
484*aecfc01dSrui zang - Sun Microsystems - Beijing China
485*aecfc01dSrui zang - Sun Microsystems - Beijing China for (p = list_head(&tems.ts_list); p != NULL;
486*aecfc01dSrui zang - Sun Microsystems - Beijing China p = list_next(&tems.ts_list, p)) {
487*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&p->tvs_lock);
488*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_internal_init(p, credp, B_TRUE, B_FALSE);
489*aecfc01dSrui zang - Sun Microsystems - Beijing China if (temargs.mode == VIS_PIXEL)
490*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_pix_align(p, credp, CALLED_FROM_NORMAL);
491*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&p->tvs_lock);
492fea9cb91Slq150181 }
493fea9cb91Slq150181
494*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
495fea9cb91Slq150181 return (0);
496fea9cb91Slq150181 }
497fea9cb91Slq150181
498*aecfc01dSrui zang - Sun Microsystems - Beijing China #define TEMS_DEPTH_DIFF 0x01
499*aecfc01dSrui zang - Sun Microsystems - Beijing China #define TEMS_DIMENSION_DIFF 0x02
500*aecfc01dSrui zang - Sun Microsystems - Beijing China
501*aecfc01dSrui zang - Sun Microsystems - Beijing China static uchar_t
tems_check_videomode(struct vis_devinit * tp)502*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_check_videomode(struct vis_devinit *tp)
503*aecfc01dSrui zang - Sun Microsystems - Beijing China {
504*aecfc01dSrui zang - Sun Microsystems - Beijing China uchar_t result = 0;
505*aecfc01dSrui zang - Sun Microsystems - Beijing China
506*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tems.ts_pdepth != tp->depth)
507*aecfc01dSrui zang - Sun Microsystems - Beijing China result |= TEMS_DEPTH_DIFF;
508*aecfc01dSrui zang - Sun Microsystems - Beijing China
509*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tp->mode == VIS_TEXT) {
510*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tems.ts_c_dimension.width != tp->width ||
511*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_c_dimension.height != tp->height)
512*aecfc01dSrui zang - Sun Microsystems - Beijing China result |= TEMS_DIMENSION_DIFF;
513*aecfc01dSrui zang - Sun Microsystems - Beijing China } else {
514*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tems.ts_p_dimension.width != tp->width ||
515*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_p_dimension.height != tp->height)
516*aecfc01dSrui zang - Sun Microsystems - Beijing China result |= TEMS_DIMENSION_DIFF;
517*aecfc01dSrui zang - Sun Microsystems - Beijing China }
518*aecfc01dSrui zang - Sun Microsystems - Beijing China
519*aecfc01dSrui zang - Sun Microsystems - Beijing China return (result);
520*aecfc01dSrui zang - Sun Microsystems - Beijing China }
521*aecfc01dSrui zang - Sun Microsystems - Beijing China
522*aecfc01dSrui zang - Sun Microsystems - Beijing China static void
tems_setup_terminal(struct vis_devinit * tp,size_t height,size_t width)523*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_setup_terminal(struct vis_devinit *tp, size_t height, size_t width)
524*aecfc01dSrui zang - Sun Microsystems - Beijing China {
525*aecfc01dSrui zang - Sun Microsystems - Beijing China int i;
526*aecfc01dSrui zang - Sun Microsystems - Beijing China int old_blank_buf_size = tems.ts_c_dimension.width;
527*aecfc01dSrui zang - Sun Microsystems - Beijing China
528*aecfc01dSrui zang - Sun Microsystems - Beijing China ASSERT(MUTEX_HELD(&tems.ts_lock));
529*aecfc01dSrui zang - Sun Microsystems - Beijing China
530*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_pdepth = tp->depth;
531*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_linebytes = tp->linebytes;
532*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_display_mode = tp->mode;
533*aecfc01dSrui zang - Sun Microsystems - Beijing China
534*aecfc01dSrui zang - Sun Microsystems - Beijing China switch (tp->mode) {
535*aecfc01dSrui zang - Sun Microsystems - Beijing China case VIS_TEXT:
536*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_p_dimension.width = 0;
537*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_p_dimension.height = 0;
538*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_c_dimension.width = tp->width;
539*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_c_dimension.height = tp->height;
540*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_callbacks = &tem_safe_text_callbacks;
541*aecfc01dSrui zang - Sun Microsystems - Beijing China
542*aecfc01dSrui zang - Sun Microsystems - Beijing China break;
543*aecfc01dSrui zang - Sun Microsystems - Beijing China
544*aecfc01dSrui zang - Sun Microsystems - Beijing China case VIS_PIXEL:
545*aecfc01dSrui zang - Sun Microsystems - Beijing China /*
546*aecfc01dSrui zang - Sun Microsystems - Beijing China * First check to see if the user has specified a screen size.
547*aecfc01dSrui zang - Sun Microsystems - Beijing China * If so, use those values. Else use 34x80 as the default.
548*aecfc01dSrui zang - Sun Microsystems - Beijing China */
549*aecfc01dSrui zang - Sun Microsystems - Beijing China if (width == 0) {
550*aecfc01dSrui zang - Sun Microsystems - Beijing China width = TEM_DEFAULT_COLS;
551*aecfc01dSrui zang - Sun Microsystems - Beijing China height = TEM_DEFAULT_ROWS;
552*aecfc01dSrui zang - Sun Microsystems - Beijing China }
553*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_c_dimension.height = (screen_size_t)height;
554*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_c_dimension.width = (screen_size_t)width;
555*aecfc01dSrui zang - Sun Microsystems - Beijing China
556*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_p_dimension.height = tp->height;
557*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_p_dimension.width = tp->width;
558*aecfc01dSrui zang - Sun Microsystems - Beijing China
559*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_callbacks = &tem_safe_pix_callbacks;
560*aecfc01dSrui zang - Sun Microsystems - Beijing China
561*aecfc01dSrui zang - Sun Microsystems - Beijing China /*
562*aecfc01dSrui zang - Sun Microsystems - Beijing China * set_font() will select a appropriate sized font for
563*aecfc01dSrui zang - Sun Microsystems - Beijing China * the number of rows and columns selected. If we don't
564*aecfc01dSrui zang - Sun Microsystems - Beijing China * have a font that will fit, then it will use the
565*aecfc01dSrui zang - Sun Microsystems - Beijing China * default builtin font and adjust the rows and columns
566*aecfc01dSrui zang - Sun Microsystems - Beijing China * to fit on the screen.
567*aecfc01dSrui zang - Sun Microsystems - Beijing China */
568*aecfc01dSrui zang - Sun Microsystems - Beijing China set_font(&tems.ts_font,
569*aecfc01dSrui zang - Sun Microsystems - Beijing China &tems.ts_c_dimension.height,
570*aecfc01dSrui zang - Sun Microsystems - Beijing China &tems.ts_c_dimension.width,
571*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_p_dimension.height,
572*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_p_dimension.width);
573*aecfc01dSrui zang - Sun Microsystems - Beijing China
574*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_p_offset.y = (tems.ts_p_dimension.height -
575*aecfc01dSrui zang - Sun Microsystems - Beijing China (tems.ts_c_dimension.height * tems.ts_font.height)) / 2;
576*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_p_offset.x = (tems.ts_p_dimension.width -
577*aecfc01dSrui zang - Sun Microsystems - Beijing China (tems.ts_c_dimension.width * tems.ts_font.width)) / 2;
578*aecfc01dSrui zang - Sun Microsystems - Beijing China
579*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_pix_data_size =
580*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_font.width * tems.ts_font.height;
581*aecfc01dSrui zang - Sun Microsystems - Beijing China
582*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_pix_data_size *= 4;
583*aecfc01dSrui zang - Sun Microsystems - Beijing China
584*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_pdepth = tp->depth;
585*aecfc01dSrui zang - Sun Microsystems - Beijing China
586*aecfc01dSrui zang - Sun Microsystems - Beijing China break;
587*aecfc01dSrui zang - Sun Microsystems - Beijing China }
588*aecfc01dSrui zang - Sun Microsystems - Beijing China
589*aecfc01dSrui zang - Sun Microsystems - Beijing China /* Now virtual cls also uses the blank_line buffer */
590*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tems.ts_blank_line)
591*aecfc01dSrui zang - Sun Microsystems - Beijing China kmem_free(tems.ts_blank_line, old_blank_buf_size);
592*aecfc01dSrui zang - Sun Microsystems - Beijing China
593*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_blank_line = (unsigned char *)
594*aecfc01dSrui zang - Sun Microsystems - Beijing China kmem_alloc(tems.ts_c_dimension.width, KM_SLEEP);
595*aecfc01dSrui zang - Sun Microsystems - Beijing China for (i = 0; i < tems.ts_c_dimension.width; i++)
596*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_blank_line[i] = ' ';
597*aecfc01dSrui zang - Sun Microsystems - Beijing China }
598*aecfc01dSrui zang - Sun Microsystems - Beijing China
599fea9cb91Slq150181 /*
600fea9cb91Slq150181 * This is a callback function that we register with the frame
601fea9cb91Slq150181 * buffer driver layered underneath. It gets invoked from
602fea9cb91Slq150181 * the underlying frame buffer driver to reconfigure the terminal
603fea9cb91Slq150181 * emulator to a new screen size and depth in conjunction with
604fea9cb91Slq150181 * framebuffer videomode changes.
605c9503a49Slq150181 * Here we keep the foreground/background color and attributes,
606c9503a49Slq150181 * which may be different with the initial settings, so that
607c9503a49Slq150181 * the color won't change while the framebuffer videomode changes.
608c9503a49Slq150181 * And we also reset the kernel terminal emulator and clear the
609c9503a49Slq150181 * whole screen.
610fea9cb91Slq150181 */
611*aecfc01dSrui zang - Sun Microsystems - Beijing China /* ARGSUSED */
612fea9cb91Slq150181 void
tems_modechange_callback(struct vis_modechg_arg * arg,struct vis_devinit * devinit)613*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_modechange_callback(struct vis_modechg_arg *arg,
614*aecfc01dSrui zang - Sun Microsystems - Beijing China struct vis_devinit *devinit)
615fea9cb91Slq150181 {
616*aecfc01dSrui zang - Sun Microsystems - Beijing China uchar_t diff;
617*aecfc01dSrui zang - Sun Microsystems - Beijing China struct tem_vt_state *p;
618*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_modechg_cb_t cb;
619*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_modechg_cb_arg_t cb_arg;
620c9503a49Slq150181
621*aecfc01dSrui zang - Sun Microsystems - Beijing China ASSERT(!(list_is_empty(&tems.ts_list)));
622fea9cb91Slq150181
623*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&tems.ts_lock);
624fea9cb91Slq150181
625fea9cb91Slq150181 /*
626*aecfc01dSrui zang - Sun Microsystems - Beijing China * currently only for pixel mode
627fea9cb91Slq150181 */
628*aecfc01dSrui zang - Sun Microsystems - Beijing China diff = tems_check_videomode(devinit);
629*aecfc01dSrui zang - Sun Microsystems - Beijing China if (diff == 0) {
630*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
631*aecfc01dSrui zang - Sun Microsystems - Beijing China return;
632fea9cb91Slq150181 }
633fea9cb91Slq150181
634*aecfc01dSrui zang - Sun Microsystems - Beijing China diff = diff & TEMS_DIMENSION_DIFF;
635fea9cb91Slq150181
636*aecfc01dSrui zang - Sun Microsystems - Beijing China if (diff == 0) {
637fea9cb91Slq150181 /*
638*aecfc01dSrui zang - Sun Microsystems - Beijing China * Only need to reinit the active tem.
639fea9cb91Slq150181 */
640*aecfc01dSrui zang - Sun Microsystems - Beijing China struct tem_vt_state *active = tems.ts_active;
641*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_pdepth = devinit->depth;
642*aecfc01dSrui zang - Sun Microsystems - Beijing China
643*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&active->tvs_lock);
644*aecfc01dSrui zang - Sun Microsystems - Beijing China ASSERT(active->tvs_isactive);
645*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_reinit(active, B_TRUE);
646*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&active->tvs_lock);
647*aecfc01dSrui zang - Sun Microsystems - Beijing China
648*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
649*aecfc01dSrui zang - Sun Microsystems - Beijing China return;
650fea9cb91Slq150181 }
651fea9cb91Slq150181
652*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_setup_terminal(devinit, tems.ts_c_dimension.height,
653*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_c_dimension.width);
654*aecfc01dSrui zang - Sun Microsystems - Beijing China
655*aecfc01dSrui zang - Sun Microsystems - Beijing China for (p = list_head(&tems.ts_list); p != NULL;
656*aecfc01dSrui zang - Sun Microsystems - Beijing China p = list_next(&tems.ts_list, p)) {
657*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&p->tvs_lock);
658*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_reinit(p, p->tvs_isactive);
659*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&p->tvs_lock);
660*aecfc01dSrui zang - Sun Microsystems - Beijing China }
661*aecfc01dSrui zang - Sun Microsystems - Beijing China
662*aecfc01dSrui zang - Sun Microsystems - Beijing China
663*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tems.ts_modechg_cb == NULL) {
664*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
665*aecfc01dSrui zang - Sun Microsystems - Beijing China return;
666*aecfc01dSrui zang - Sun Microsystems - Beijing China }
667*aecfc01dSrui zang - Sun Microsystems - Beijing China
668*aecfc01dSrui zang - Sun Microsystems - Beijing China cb = tems.ts_modechg_cb;
669*aecfc01dSrui zang - Sun Microsystems - Beijing China cb_arg = tems.ts_modechg_arg;
670fea9cb91Slq150181
671fea9cb91Slq150181 /*
672*aecfc01dSrui zang - Sun Microsystems - Beijing China * Release the lock while doing callback.
673fea9cb91Slq150181 */
674*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
675*aecfc01dSrui zang - Sun Microsystems - Beijing China cb(cb_arg);
676fea9cb91Slq150181 }
677fea9cb91Slq150181
678fea9cb91Slq150181 /*
679fea9cb91Slq150181 * This function is used to display a rectangular blit of data
680fea9cb91Slq150181 * of a given size and location via the underlying framebuffer driver.
681fea9cb91Slq150181 * The blit can be as small as a pixel or as large as the screen.
682fea9cb91Slq150181 */
683fea9cb91Slq150181 void
tems_display_layered(struct vis_consdisplay * pda,cred_t * credp)684*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_display_layered(
685fea9cb91Slq150181 struct vis_consdisplay *pda,
686fea9cb91Slq150181 cred_t *credp)
687fea9cb91Slq150181 {
688fea9cb91Slq150181 int rval;
689fea9cb91Slq150181
690*aecfc01dSrui zang - Sun Microsystems - Beijing China (void) ldi_ioctl(tems.ts_hdl, VIS_CONSDISPLAY,
691fea9cb91Slq150181 (intptr_t)pda, FKIOCTL, credp, &rval);
692fea9cb91Slq150181 }
693fea9cb91Slq150181
694fea9cb91Slq150181 /*
695fea9cb91Slq150181 * This function is used to invoke a block copy operation in the
696fea9cb91Slq150181 * underlying framebuffer driver. Rectangle copies are how scrolling
697fea9cb91Slq150181 * is implemented, as well as horizontal text shifting escape seqs.
698fea9cb91Slq150181 * such as from vi when deleting characters and words.
699fea9cb91Slq150181 */
700fea9cb91Slq150181 void
tems_copy_layered(struct vis_conscopy * pma,cred_t * credp)701*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_copy_layered(
702fea9cb91Slq150181 struct vis_conscopy *pma,
703fea9cb91Slq150181 cred_t *credp)
704fea9cb91Slq150181 {
705fea9cb91Slq150181 int rval;
706fea9cb91Slq150181
707*aecfc01dSrui zang - Sun Microsystems - Beijing China (void) ldi_ioctl(tems.ts_hdl, VIS_CONSCOPY,
708fea9cb91Slq150181 (intptr_t)pma, FKIOCTL, credp, &rval);
709fea9cb91Slq150181 }
710fea9cb91Slq150181
711fea9cb91Slq150181 /*
712fea9cb91Slq150181 * This function is used to show or hide a rectangluar monochrom
713fea9cb91Slq150181 * pixel inverting, text block cursor via the underlying framebuffer.
714fea9cb91Slq150181 */
715fea9cb91Slq150181 void
tems_cursor_layered(struct vis_conscursor * pca,cred_t * credp)716*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_cursor_layered(
717fea9cb91Slq150181 struct vis_conscursor *pca,
718fea9cb91Slq150181 cred_t *credp)
719fea9cb91Slq150181 {
720fea9cb91Slq150181 int rval;
721fea9cb91Slq150181
722*aecfc01dSrui zang - Sun Microsystems - Beijing China (void) ldi_ioctl(tems.ts_hdl, VIS_CONSCURSOR,
723fea9cb91Slq150181 (intptr_t)pca, FKIOCTL, credp, &rval);
724fea9cb91Slq150181 }
725fea9cb91Slq150181
726*aecfc01dSrui zang - Sun Microsystems - Beijing China static void
tem_kdsetmode(int mode,cred_t * credp)727*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_kdsetmode(int mode, cred_t *credp)
728*aecfc01dSrui zang - Sun Microsystems - Beijing China {
729*aecfc01dSrui zang - Sun Microsystems - Beijing China int rval;
730*aecfc01dSrui zang - Sun Microsystems - Beijing China
731*aecfc01dSrui zang - Sun Microsystems - Beijing China (void) ldi_ioctl(tems.ts_hdl, KDSETMODE,
732*aecfc01dSrui zang - Sun Microsystems - Beijing China (intptr_t)mode, FKIOCTL, credp, &rval);
733*aecfc01dSrui zang - Sun Microsystems - Beijing China
734*aecfc01dSrui zang - Sun Microsystems - Beijing China }
735*aecfc01dSrui zang - Sun Microsystems - Beijing China
736*aecfc01dSrui zang - Sun Microsystems - Beijing China static void
tems_reset_colormap(cred_t * credp,enum called_from called_from)737*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_reset_colormap(cred_t *credp, enum called_from called_from)
738fea9cb91Slq150181 {
739fea9cb91Slq150181 struct vis_cmap cm;
740fea9cb91Slq150181 int rval;
741fea9cb91Slq150181
742fea9cb91Slq150181 if (called_from == CALLED_FROM_STANDALONE)
743fea9cb91Slq150181 return;
744fea9cb91Slq150181
745*aecfc01dSrui zang - Sun Microsystems - Beijing China switch (tems.ts_pdepth) {
746fea9cb91Slq150181 case 8:
747fea9cb91Slq150181 cm.index = 0;
748fea9cb91Slq150181 cm.count = 16;
749fea9cb91Slq150181 cm.red = cmap4_to_24.red; /* 8-bits (1/3 of TrueColor 24) */
750fea9cb91Slq150181 cm.blue = cmap4_to_24.blue; /* 8-bits (1/3 of TrueColor 24) */
751fea9cb91Slq150181 cm.green = cmap4_to_24.green; /* 8-bits (1/3 of TrueColor 24) */
752*aecfc01dSrui zang - Sun Microsystems - Beijing China (void) ldi_ioctl(tems.ts_hdl, VIS_PUTCMAP, (intptr_t)&cm,
753fea9cb91Slq150181 FKIOCTL, credp, &rval);
754fea9cb91Slq150181 break;
755fea9cb91Slq150181 }
756fea9cb91Slq150181 }
757fea9cb91Slq150181
758fea9cb91Slq150181 void
tem_get_size(ushort_t * r,ushort_t * c,ushort_t * x,ushort_t * y)759*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_get_size(ushort_t *r, ushort_t *c,
760fea9cb91Slq150181 ushort_t *x, ushort_t *y)
761fea9cb91Slq150181 {
762*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&tems.ts_lock);
763*aecfc01dSrui zang - Sun Microsystems - Beijing China *r = (ushort_t)tems.ts_c_dimension.height;
764*aecfc01dSrui zang - Sun Microsystems - Beijing China *c = (ushort_t)tems.ts_c_dimension.width;
765*aecfc01dSrui zang - Sun Microsystems - Beijing China *x = (ushort_t)tems.ts_p_dimension.width;
766*aecfc01dSrui zang - Sun Microsystems - Beijing China *y = (ushort_t)tems.ts_p_dimension.height;
767*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
768fea9cb91Slq150181 }
769fea9cb91Slq150181
770fea9cb91Slq150181 void
tem_register_modechg_cb(tem_modechg_cb_t func,tem_modechg_cb_arg_t arg)771*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_register_modechg_cb(tem_modechg_cb_t func,
772fea9cb91Slq150181 tem_modechg_cb_arg_t arg)
773fea9cb91Slq150181 {
774*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&tems.ts_lock);
775*aecfc01dSrui zang - Sun Microsystems - Beijing China
776*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_modechg_cb = func;
777*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_modechg_arg = arg;
778*aecfc01dSrui zang - Sun Microsystems - Beijing China
779*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
780fea9cb91Slq150181 }
781fea9cb91Slq150181
782fea9cb91Slq150181 /*
783fea9cb91Slq150181 * This function is to scroll up the OBP output, which has
784fea9cb91Slq150181 * different screen height and width with our kernel console.
785fea9cb91Slq150181 */
786fea9cb91Slq150181 static void
tem_prom_scroll_up(struct tem_vt_state * tem,int nrows,cred_t * credp,enum called_from called_from)787*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_prom_scroll_up(struct tem_vt_state *tem, int nrows, cred_t *credp,
788*aecfc01dSrui zang - Sun Microsystems - Beijing China enum called_from called_from)
789fea9cb91Slq150181 {
790fea9cb91Slq150181 struct vis_conscopy ma;
791fea9cb91Slq150181 int ncols, width;
792fea9cb91Slq150181
793fea9cb91Slq150181 /* copy */
794*aecfc01dSrui zang - Sun Microsystems - Beijing China ma.s_row = nrows * tems.ts_font.height;
795*aecfc01dSrui zang - Sun Microsystems - Beijing China ma.e_row = tems.ts_p_dimension.height - 1;
796fea9cb91Slq150181 ma.t_row = 0;
797fea9cb91Slq150181
798fea9cb91Slq150181 ma.s_col = 0;
799*aecfc01dSrui zang - Sun Microsystems - Beijing China ma.e_col = tems.ts_p_dimension.width - 1;
800fea9cb91Slq150181 ma.t_col = 0;
801fea9cb91Slq150181
802*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_safe_copy(&ma, credp, called_from);
803fea9cb91Slq150181
804fea9cb91Slq150181 /* clear */
805*aecfc01dSrui zang - Sun Microsystems - Beijing China width = tems.ts_font.width;
806*aecfc01dSrui zang - Sun Microsystems - Beijing China ncols = (tems.ts_p_dimension.width + (width - 1))/ width;
807fea9cb91Slq150181
808*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_pix_cls_range(tem, 0, nrows, tems.ts_p_offset.y,
809*aecfc01dSrui zang - Sun Microsystems - Beijing China 0, ncols, 0, B_TRUE, credp, called_from);
810fea9cb91Slq150181 }
811fea9cb91Slq150181
812fea9cb91Slq150181 #define PROM_DEFAULT_FONT_HEIGHT 22
813fea9cb91Slq150181 #define PROM_DEFAULT_WINDOW_TOP 0x8a
814fea9cb91Slq150181
815fea9cb91Slq150181 /*
816fea9cb91Slq150181 * This function is to compute the starting row of the console, according to
817fea9cb91Slq150181 * PROM cursor's position. Here we have to take different fonts into account.
818fea9cb91Slq150181 */
819fea9cb91Slq150181 static int
tem_adjust_row(struct tem_vt_state * tem,int prom_row,cred_t * credp,enum called_from called_from)820*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_adjust_row(struct tem_vt_state *tem, int prom_row, cred_t *credp,
821*aecfc01dSrui zang - Sun Microsystems - Beijing China enum called_from called_from)
822fea9cb91Slq150181 {
823fea9cb91Slq150181 int tem_row;
824fea9cb91Slq150181 int tem_y;
825fea9cb91Slq150181 int prom_charheight = 0;
826fea9cb91Slq150181 int prom_window_top = 0;
827fea9cb91Slq150181 int scroll_up_lines;
828fea9cb91Slq150181
829fea9cb91Slq150181 plat_tem_get_prom_font_size(&prom_charheight, &prom_window_top);
830fea9cb91Slq150181 if (prom_charheight == 0)
831fea9cb91Slq150181 prom_charheight = PROM_DEFAULT_FONT_HEIGHT;
832fea9cb91Slq150181 if (prom_window_top == 0)
833fea9cb91Slq150181 prom_window_top = PROM_DEFAULT_WINDOW_TOP;
834fea9cb91Slq150181
835fea9cb91Slq150181 tem_y = (prom_row + 1) * prom_charheight + prom_window_top -
836*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_p_offset.y;
837*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_row = (tem_y + tems.ts_font.height - 1) /
838*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_font.height - 1;
839fea9cb91Slq150181
840fea9cb91Slq150181 if (tem_row < 0) {
841fea9cb91Slq150181 tem_row = 0;
842*aecfc01dSrui zang - Sun Microsystems - Beijing China } else if (tem_row >= (tems.ts_c_dimension.height - 1)) {
843fea9cb91Slq150181 /*
844fea9cb91Slq150181 * Scroll up the prom outputs if the PROM cursor's position is
845fea9cb91Slq150181 * below our tem's lower boundary.
846fea9cb91Slq150181 */
847fea9cb91Slq150181 scroll_up_lines = tem_row -
848*aecfc01dSrui zang - Sun Microsystems - Beijing China (tems.ts_c_dimension.height - 1);
849*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_prom_scroll_up(tem, scroll_up_lines, credp, called_from);
850*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_row = tems.ts_c_dimension.height - 1;
851fea9cb91Slq150181 }
852fea9cb91Slq150181
853fea9cb91Slq150181 return (tem_row);
854fea9cb91Slq150181 }
855c9503a49Slq150181
856*aecfc01dSrui zang - Sun Microsystems - Beijing China void
tem_pix_align(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)857*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_pix_align(struct tem_vt_state *tem, cred_t *credp,
858*aecfc01dSrui zang - Sun Microsystems - Beijing China enum called_from called_from)
859*aecfc01dSrui zang - Sun Microsystems - Beijing China {
860*aecfc01dSrui zang - Sun Microsystems - Beijing China uint32_t row = 0;
861*aecfc01dSrui zang - Sun Microsystems - Beijing China uint32_t col = 0;
862*aecfc01dSrui zang - Sun Microsystems - Beijing China
863*aecfc01dSrui zang - Sun Microsystems - Beijing China if (plat_stdout_is_framebuffer()) {
864*aecfc01dSrui zang - Sun Microsystems - Beijing China plat_tem_hide_prom_cursor();
865*aecfc01dSrui zang - Sun Microsystems - Beijing China
866*aecfc01dSrui zang - Sun Microsystems - Beijing China /*
867*aecfc01dSrui zang - Sun Microsystems - Beijing China * We are getting the current cursor position in pixel
868*aecfc01dSrui zang - Sun Microsystems - Beijing China * mode so that we don't over-write the console output
869*aecfc01dSrui zang - Sun Microsystems - Beijing China * during boot.
870*aecfc01dSrui zang - Sun Microsystems - Beijing China */
871*aecfc01dSrui zang - Sun Microsystems - Beijing China plat_tem_get_prom_pos(&row, &col);
872*aecfc01dSrui zang - Sun Microsystems - Beijing China
873*aecfc01dSrui zang - Sun Microsystems - Beijing China /*
874*aecfc01dSrui zang - Sun Microsystems - Beijing China * Adjust the row if necessary when the font of our
875*aecfc01dSrui zang - Sun Microsystems - Beijing China * kernel console tem is different with that of prom
876*aecfc01dSrui zang - Sun Microsystems - Beijing China * tem.
877*aecfc01dSrui zang - Sun Microsystems - Beijing China */
878*aecfc01dSrui zang - Sun Microsystems - Beijing China row = tem_adjust_row(tem, row, credp, called_from);
879*aecfc01dSrui zang - Sun Microsystems - Beijing China
880*aecfc01dSrui zang - Sun Microsystems - Beijing China /* first line of our kernel console output */
881*aecfc01dSrui zang - Sun Microsystems - Beijing China tem->tvs_first_line = row + 1;
882*aecfc01dSrui zang - Sun Microsystems - Beijing China
883*aecfc01dSrui zang - Sun Microsystems - Beijing China /* re-set and align cusror position */
884*aecfc01dSrui zang - Sun Microsystems - Beijing China tem->tvs_s_cursor.row = tem->tvs_c_cursor.row =
885*aecfc01dSrui zang - Sun Microsystems - Beijing China (screen_pos_t)row;
886*aecfc01dSrui zang - Sun Microsystems - Beijing China tem->tvs_s_cursor.col = tem->tvs_c_cursor.col = 0;
887*aecfc01dSrui zang - Sun Microsystems - Beijing China } else {
888*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_reset_display(tem, credp, called_from, B_TRUE, B_TRUE);
889*aecfc01dSrui zang - Sun Microsystems - Beijing China }
890*aecfc01dSrui zang - Sun Microsystems - Beijing China }
891*aecfc01dSrui zang - Sun Microsystems - Beijing China
892c9503a49Slq150181 static void
tems_get_inverses(boolean_t * p_inverse,boolean_t * p_inverse_screen)893*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_get_inverses(boolean_t *p_inverse, boolean_t *p_inverse_screen)
894c9503a49Slq150181 {
895c9503a49Slq150181 int i_inverse = 0;
896c9503a49Slq150181 int i_inverse_screen = 0;
897c9503a49Slq150181
898c9503a49Slq150181 plat_tem_get_inverses(&i_inverse, &i_inverse_screen);
899c9503a49Slq150181
900c9503a49Slq150181 *p_inverse = (i_inverse == 0) ? B_FALSE : B_TRUE;
901c9503a49Slq150181 *p_inverse_screen = (i_inverse_screen == 0) ? B_FALSE : B_TRUE;
902c9503a49Slq150181 }
903c9503a49Slq150181
904c9503a49Slq150181 /*
905c9503a49Slq150181 * Get the foreground/background color and attributes from the initial
906c9503a49Slq150181 * PROM, so that our kernel console can keep the same visual behaviour.
907c9503a49Slq150181 */
908c9503a49Slq150181 static void
tems_get_initial_color(tem_color_t * pcolor)909*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_get_initial_color(tem_color_t *pcolor)
910c9503a49Slq150181 {
911c9503a49Slq150181 boolean_t inverse, inverse_screen;
912c9503a49Slq150181 unsigned short flags = 0;
913c9503a49Slq150181
914*aecfc01dSrui zang - Sun Microsystems - Beijing China pcolor->fg_color = DEFAULT_ANSI_FOREGROUND;
915*aecfc01dSrui zang - Sun Microsystems - Beijing China pcolor->bg_color = DEFAULT_ANSI_BACKGROUND;
916c9503a49Slq150181
917c9503a49Slq150181 if (plat_stdout_is_framebuffer()) {
918*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_get_inverses(&inverse, &inverse_screen);
919c9503a49Slq150181 if (inverse)
920c9503a49Slq150181 flags |= TEM_ATTR_REVERSE;
921c9503a49Slq150181 if (inverse_screen)
922c9503a49Slq150181 flags |= TEM_ATTR_SCREEN_REVERSE;
923c9503a49Slq150181 if (flags != 0)
924c9503a49Slq150181 flags |= TEM_ATTR_BOLD;
925c9503a49Slq150181 }
926c9503a49Slq150181
927*aecfc01dSrui zang - Sun Microsystems - Beijing China pcolor->a_flags = flags;
928*aecfc01dSrui zang - Sun Microsystems - Beijing China }
929*aecfc01dSrui zang - Sun Microsystems - Beijing China
930*aecfc01dSrui zang - Sun Microsystems - Beijing China uchar_t
tem_get_fbmode(tem_vt_state_t tem_arg)931*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_get_fbmode(tem_vt_state_t tem_arg)
932*aecfc01dSrui zang - Sun Microsystems - Beijing China {
933*aecfc01dSrui zang - Sun Microsystems - Beijing China struct tem_vt_state *tem = (struct tem_vt_state *)tem_arg;
934*aecfc01dSrui zang - Sun Microsystems - Beijing China
935*aecfc01dSrui zang - Sun Microsystems - Beijing China uchar_t fbmode;
936*aecfc01dSrui zang - Sun Microsystems - Beijing China
937*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&tem->tvs_lock);
938*aecfc01dSrui zang - Sun Microsystems - Beijing China fbmode = tem->tvs_fbmode;
939*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tem->tvs_lock);
940*aecfc01dSrui zang - Sun Microsystems - Beijing China
941*aecfc01dSrui zang - Sun Microsystems - Beijing China return (fbmode);
942*aecfc01dSrui zang - Sun Microsystems - Beijing China }
943*aecfc01dSrui zang - Sun Microsystems - Beijing China
944*aecfc01dSrui zang - Sun Microsystems - Beijing China void
tem_set_fbmode(tem_vt_state_t tem_arg,uchar_t fbmode,cred_t * credp)945*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_set_fbmode(tem_vt_state_t tem_arg, uchar_t fbmode, cred_t *credp)
946*aecfc01dSrui zang - Sun Microsystems - Beijing China {
947*aecfc01dSrui zang - Sun Microsystems - Beijing China struct tem_vt_state *tem = (struct tem_vt_state *)tem_arg;
948*aecfc01dSrui zang - Sun Microsystems - Beijing China
949*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&tems.ts_lock);
950*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&tem->tvs_lock);
951*aecfc01dSrui zang - Sun Microsystems - Beijing China
952*aecfc01dSrui zang - Sun Microsystems - Beijing China if (fbmode == tem->tvs_fbmode) {
953*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tem->tvs_lock);
954*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
955*aecfc01dSrui zang - Sun Microsystems - Beijing China return;
956*aecfc01dSrui zang - Sun Microsystems - Beijing China }
957*aecfc01dSrui zang - Sun Microsystems - Beijing China
958*aecfc01dSrui zang - Sun Microsystems - Beijing China tem->tvs_fbmode = fbmode;
959*aecfc01dSrui zang - Sun Microsystems - Beijing China
960*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tem->tvs_isactive) {
961*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_kdsetmode(tem->tvs_fbmode, credp);
962*aecfc01dSrui zang - Sun Microsystems - Beijing China if (fbmode == KD_TEXT)
963*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_unblank_screen(tem, credp, CALLED_FROM_NORMAL);
964*aecfc01dSrui zang - Sun Microsystems - Beijing China }
965*aecfc01dSrui zang - Sun Microsystems - Beijing China
966*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tem->tvs_lock);
967*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
968*aecfc01dSrui zang - Sun Microsystems - Beijing China }
969*aecfc01dSrui zang - Sun Microsystems - Beijing China
970*aecfc01dSrui zang - Sun Microsystems - Beijing China void
tem_activate(tem_vt_state_t tem_arg,boolean_t unblank,cred_t * credp)971*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_activate(tem_vt_state_t tem_arg, boolean_t unblank, cred_t *credp)
972*aecfc01dSrui zang - Sun Microsystems - Beijing China {
973*aecfc01dSrui zang - Sun Microsystems - Beijing China struct tem_vt_state *tem = (struct tem_vt_state *)tem_arg;
974*aecfc01dSrui zang - Sun Microsystems - Beijing China
975*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&tems.ts_lock);
976*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_active = tem;
977*aecfc01dSrui zang - Sun Microsystems - Beijing China
978*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&tem->tvs_lock);
979*aecfc01dSrui zang - Sun Microsystems - Beijing China tem->tvs_isactive = B_TRUE;
980*aecfc01dSrui zang - Sun Microsystems - Beijing China
981*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_kdsetmode(tem->tvs_fbmode, credp);
982*aecfc01dSrui zang - Sun Microsystems - Beijing China
983*aecfc01dSrui zang - Sun Microsystems - Beijing China if (unblank)
984*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_unblank_screen(tem, credp, CALLED_FROM_NORMAL);
985*aecfc01dSrui zang - Sun Microsystems - Beijing China
986*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tem->tvs_lock);
987*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
988*aecfc01dSrui zang - Sun Microsystems - Beijing China }
989*aecfc01dSrui zang - Sun Microsystems - Beijing China
990*aecfc01dSrui zang - Sun Microsystems - Beijing China void
tem_switch(tem_vt_state_t tem_arg1,tem_vt_state_t tem_arg2,cred_t * credp)991*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_switch(tem_vt_state_t tem_arg1, tem_vt_state_t tem_arg2, cred_t *credp)
992*aecfc01dSrui zang - Sun Microsystems - Beijing China {
993*aecfc01dSrui zang - Sun Microsystems - Beijing China struct tem_vt_state *cur = (struct tem_vt_state *)tem_arg1;
994*aecfc01dSrui zang - Sun Microsystems - Beijing China struct tem_vt_state *tobe = (struct tem_vt_state *)tem_arg2;
995*aecfc01dSrui zang - Sun Microsystems - Beijing China
996*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&tems.ts_lock);
997*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&tobe->tvs_lock);
998*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_enter(&cur->tvs_lock);
999*aecfc01dSrui zang - Sun Microsystems - Beijing China
1000*aecfc01dSrui zang - Sun Microsystems - Beijing China tems.ts_active = tobe;
1001*aecfc01dSrui zang - Sun Microsystems - Beijing China cur->tvs_isactive = B_FALSE;
1002*aecfc01dSrui zang - Sun Microsystems - Beijing China tobe->tvs_isactive = B_TRUE;
1003*aecfc01dSrui zang - Sun Microsystems - Beijing China
1004*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&cur->tvs_lock);
1005*aecfc01dSrui zang - Sun Microsystems - Beijing China
1006*aecfc01dSrui zang - Sun Microsystems - Beijing China if (cur->tvs_fbmode != tobe->tvs_fbmode)
1007*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_kdsetmode(tobe->tvs_fbmode, credp);
1008*aecfc01dSrui zang - Sun Microsystems - Beijing China
1009*aecfc01dSrui zang - Sun Microsystems - Beijing China if (tobe->tvs_fbmode == KD_TEXT)
1010*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_unblank_screen(tobe, credp, CALLED_FROM_NORMAL);
1011*aecfc01dSrui zang - Sun Microsystems - Beijing China
1012*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tobe->tvs_lock);
1013*aecfc01dSrui zang - Sun Microsystems - Beijing China mutex_exit(&tems.ts_lock);
1014c9503a49Slq150181 }
1015