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