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/i86pc/boot/boot_console.c
+++ new/usr/src/uts/i86pc/boot/boot_console.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 */
|
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
21 21 /*
22 22 * Copyright (c) 2012 Gary Mills
23 23 *
24 24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25 25 * Use is subject to license terms.
26 26 */
27 27
28 28 #include <sys/types.h>
29 29 #include <sys/systm.h>
30 30 #include <sys/archsystm.h>
31 +#include <sys/framebuffer.h>
31 32 #include <sys/boot_console.h>
32 33 #include <sys/panic.h>
33 34 #include <sys/ctype.h>
35 +#include <sys/ascii.h>
34 36 #if defined(__xpv)
35 37 #include <sys/hypervisor.h>
36 38 #endif /* __xpv */
37 39
40 +#include "boot_console_impl.h"
38 41 #include "boot_serial.h"
39 42 #include "boot_vga.h"
40 43
41 44 #if defined(_BOOT)
42 45 #include <dboot/dboot_asm.h>
43 46 #include <dboot/dboot_xboot.h>
44 47 #else /* _BOOT */
45 48 #include <sys/bootconf.h>
46 49 #if defined(__xpv)
47 50 #include <sys/evtchn_impl.h>
48 51 #endif /* __xpv */
49 52 static char *defcons_buf;
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
50 53 static char *defcons_cur;
51 54 #endif /* _BOOT */
52 55
53 56 #if defined(__xpv)
54 57 extern void bcons_init_xen(char *);
55 58 extern void bcons_putchar_xen(int);
56 59 extern int bcons_getchar_xen(void);
57 60 extern int bcons_ischar_xen(void);
58 61 #endif /* __xpv */
59 62
60 -static int cons_color = CONS_COLOR;
63 +fb_info_t fb_info;
64 +static bcons_dev_t bcons_dev; /* Device callbacks */
61 65 static int console = CONS_SCREEN_TEXT;
66 +static int diag = CONS_INVALID;
62 67 static int tty_num = 0;
63 68 static int tty_addr[] = {0x3f8, 0x2f8, 0x3e8, 0x2e8};
64 69 static char *boot_line;
65 70 static struct boot_env {
66 71 char *be_env; /* ends with double ascii nul */
67 72 size_t be_size; /* size of the environment, including nul */
68 73 } boot_env;
69 74
75 +/*
76 + * Simple console terminal emulator for early boot.
77 + * We need this to support kmdb, all other console output is supposed
78 + * to be simple text output.
79 + */
80 +typedef enum btem_state_type {
81 + A_STATE_START,
82 + A_STATE_ESC,
83 + A_STATE_CSI,
84 + A_STATE_CSI_QMARK,
85 + A_STATE_CSI_EQUAL
86 +} btem_state_type_t;
87 +
88 +#define BTEM_MAXPARAMS 5
89 +typedef struct btem_state {
90 + btem_state_type_t btem_state;
91 + boolean_t btem_gotparam;
92 + int btem_curparam;
93 + int btem_paramval;
94 + int btem_params[BTEM_MAXPARAMS];
95 +} btem_state_t;
96 +
97 +static btem_state_t boot_tem;
98 +
70 99 static int serial_ischar(void);
71 100 static int serial_getchar(void);
72 101 static void serial_putchar(int);
73 102 static void serial_adjust_prop(void);
74 103
75 104 #if !defined(_BOOT)
76 105 /* Set if the console or mode are expressed in the boot line */
77 106 static int console_set, console_mode_set;
78 107 #endif
79 108
80 109 #if defined(__xpv)
81 110 static int console_hypervisor_redirect = B_FALSE;
82 111 static int console_hypervisor_device = CONS_INVALID;
83 112 static int console_hypervisor_tty_num = 0;
84 113
|
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
85 114 /* Obtain the hypervisor console type */
86 115 int
87 116 console_hypervisor_dev_type(int *tnum)
88 117 {
89 118 if (tnum != NULL)
90 119 *tnum = console_hypervisor_tty_num;
91 120 return (console_hypervisor_device);
92 121 }
93 122 #endif /* __xpv */
94 123
95 -/* Clear the screen and initialize VIDEO, XPOS and YPOS. */
96 -void
97 -clear_screen(void)
98 -{
99 - /*
100 - * XXX should set vga mode so we don't depend on the
101 - * state left by the boot loader. Note that we have to
102 - * enable the cursor before clearing the screen since
103 - * the cursor position is dependant upon the cursor
104 - * skew, which is initialized by vga_cursor_display()
105 - */
106 - vga_cursor_display();
107 - vga_clear(cons_color);
108 - vga_setpos(0, 0);
109 -}
110 -
111 -/* Put the character C on the screen. */
112 -static void
113 -screen_putchar(int c)
114 -{
115 - int row, col;
116 -
117 - vga_getpos(&row, &col);
118 - switch (c) {
119 - case '\t':
120 - col += 8 - (col % 8);
121 - if (col == VGA_TEXT_COLS)
122 - col = 79;
123 - vga_setpos(row, col);
124 - break;
125 -
126 - case '\r':
127 - vga_setpos(row, 0);
128 - break;
129 -
130 - case '\b':
131 - if (col > 0)
132 - vga_setpos(row, col - 1);
133 - break;
134 -
135 - case '\n':
136 - if (row < VGA_TEXT_ROWS - 1)
137 - vga_setpos(row + 1, col);
138 - else
139 - vga_scroll(cons_color);
140 - break;
141 -
142 - default:
143 - vga_drawc(c, cons_color);
144 - if (col < VGA_TEXT_COLS -1)
145 - vga_setpos(row, col + 1);
146 - else if (row < VGA_TEXT_ROWS - 1)
147 - vga_setpos(row + 1, 0);
148 - else {
149 - vga_setpos(row, 0);
150 - vga_scroll(cons_color);
151 - }
152 - break;
153 - }
154 -}
155 -
156 124 static int port;
157 125
158 126 static void
159 127 serial_init(void)
160 128 {
161 129 port = tty_addr[tty_num];
162 130
163 131 outb(port + ISR, 0x20);
164 132 if (inb(port + ISR) & 0x20) {
165 133 /*
166 134 * 82510 chip is present
167 135 */
168 136 outb(port + DAT+7, 0x04); /* clear status */
169 137 outb(port + ISR, 0x40); /* set to bank 2 */
170 138 outb(port + MCR, 0x08); /* IMD */
171 139 outb(port + DAT, 0x21); /* FMD */
172 140 outb(port + ISR, 0x00); /* set to bank 0 */
173 141 } else {
174 142 /*
175 143 * set the UART in FIFO mode if it has FIFO buffers.
176 144 * use 16550 fifo reset sequence specified in NS
177 145 * application note. disable fifos until chip is
178 146 * initialized.
179 147 */
180 148 outb(port + FIFOR, 0x00); /* clear */
181 149 outb(port + FIFOR, FIFO_ON); /* enable */
182 150 outb(port + FIFOR, FIFO_ON|FIFORXFLSH); /* reset */
183 151 outb(port + FIFOR,
184 152 FIFO_ON|FIFODMA|FIFOTXFLSH|FIFORXFLSH|0x80);
185 153 if ((inb(port + ISR) & 0xc0) != 0xc0) {
186 154 /*
187 155 * no fifo buffers so disable fifos.
188 156 * this is true for 8250's
189 157 */
190 158 outb(port + FIFOR, 0x00);
191 159 }
192 160 }
193 161
194 162 /* disable interrupts */
195 163 outb(port + ICR, 0);
|
↓ open down ↓ |
30 lines elided |
↑ open up ↑ |
196 164
197 165 #if !defined(_BOOT)
198 166 if (IN_XPV_PANIC())
199 167 return;
200 168 #endif
201 169
202 170 /* adjust setting based on tty properties */
203 171 serial_adjust_prop();
204 172
205 173 #if defined(_BOOT)
174 +#if 0
206 175 /*
207 176 * Do a full reset to match console behavior.
208 177 * 0x1B + c - reset everything
209 178 */
210 179 serial_putchar(0x1B);
211 180 serial_putchar('c');
212 181 #endif
182 +#endif
213 183 }
214 184
215 185 /* Advance str pointer past white space */
216 186 #define EAT_WHITE_SPACE(str) { \
217 187 while ((*str != '\0') && ISSPACE(*str)) \
218 188 str++; \
219 189 }
220 190
221 191 /*
222 192 * boot_line is set when we call here. Search it for the argument name,
223 193 * and if found, return a pointer to it.
224 194 */
225 195 static char *
226 196 find_boot_line_prop(const char *name)
227 197 {
228 198 char *ptr;
229 199 char *ret = NULL;
230 200 char end_char;
231 201 size_t len;
232 202
233 203 if (boot_line == NULL)
234 204 return (NULL);
235 205
236 206 len = strlen(name);
237 207
238 208 /*
239 209 * We have two nested loops here: the outer loop discards all options
240 210 * except -B, and the inner loop parses the -B options looking for
241 211 * the one we're interested in.
242 212 */
243 213 for (ptr = boot_line; *ptr != '\0'; ptr++) {
244 214 EAT_WHITE_SPACE(ptr);
245 215
246 216 if (*ptr == '-') {
247 217 ptr++;
248 218 while ((*ptr != '\0') && (*ptr != 'B') &&
249 219 !ISSPACE(*ptr))
250 220 ptr++;
251 221 if (*ptr == '\0')
252 222 goto out;
253 223 else if (*ptr != 'B')
254 224 continue;
255 225 } else {
256 226 while ((*ptr != '\0') && !ISSPACE(*ptr))
257 227 ptr++;
258 228 if (*ptr == '\0')
259 229 goto out;
260 230 continue;
261 231 }
262 232
263 233 do {
264 234 ptr++;
265 235 EAT_WHITE_SPACE(ptr);
266 236
267 237 if ((strncmp(ptr, name, len) == 0) &&
268 238 (ptr[len] == '=')) {
269 239 ptr += len + 1;
270 240 if ((*ptr == '\'') || (*ptr == '"')) {
271 241 ret = ptr + 1;
272 242 end_char = *ptr;
273 243 ptr++;
274 244 } else {
275 245 ret = ptr;
276 246 end_char = ',';
277 247 }
278 248 goto consume_property;
279 249 }
280 250
281 251 /*
282 252 * We have a property, and it's not the one we're
283 253 * interested in. Skip the property name. A name
284 254 * can end with '=', a comma, or white space.
285 255 */
286 256 while ((*ptr != '\0') && (*ptr != '=') &&
287 257 (*ptr != ',') && (!ISSPACE(*ptr)))
288 258 ptr++;
289 259
290 260 /*
291 261 * We only want to go through the rest of the inner
292 262 * loop if we have a comma. If we have a property
293 263 * name without a value, either continue or break.
294 264 */
295 265 if (*ptr == '\0')
296 266 goto out;
297 267 else if (*ptr == ',')
298 268 continue;
299 269 else if (ISSPACE(*ptr))
300 270 break;
301 271 ptr++;
302 272
303 273 /*
304 274 * Is the property quoted?
305 275 */
306 276 if ((*ptr == '\'') || (*ptr == '"')) {
307 277 end_char = *ptr;
308 278 ptr++;
309 279 } else {
310 280 /*
311 281 * Not quoted, so the string ends at a comma
312 282 * or at white space. Deal with white space
313 283 * later.
314 284 */
315 285 end_char = ',';
316 286 }
317 287
318 288 /*
319 289 * Now, we can ignore any characters until we find
320 290 * end_char.
321 291 */
322 292 consume_property:
323 293 for (; (*ptr != '\0') && (*ptr != end_char); ptr++) {
324 294 if ((end_char == ',') && ISSPACE(*ptr))
325 295 break;
326 296 }
327 297 if (*ptr && (*ptr != ',') && !ISSPACE(*ptr))
328 298 ptr++;
329 299 } while (*ptr == ',');
330 300 }
331 301 out:
332 302 return (ret);
333 303 }
334 304
335 305 /*
336 306 * Find prop from boot env module. The data in module is list of C strings
337 307 * name=value, the list is terminated by double nul.
338 308 */
339 309 static const char *
340 310 find_boot_env_prop(const char *name)
341 311 {
342 312 char *ptr;
343 313 size_t len;
344 314 uintptr_t size;
345 315
346 316 if (boot_env.be_env == NULL)
347 317 return (NULL);
348 318
349 319 ptr = boot_env.be_env;
350 320 len = strlen(name);
351 321
352 322 /*
353 323 * Make sure we have at least len + 2 bytes in the environment.
354 324 * We are looking for name=value\0 constructs, and the environment
355 325 * itself is terminated by '\0'.
356 326 */
357 327 if (boot_env.be_size < len + 2)
358 328 return (NULL);
359 329
360 330 do {
361 331 if ((strncmp(ptr, name, len) == 0) && (ptr[len] == '=')) {
362 332 ptr += len + 1;
363 333 return (ptr);
364 334 }
365 335 /* find the first '\0' */
366 336 while (*ptr != '\0') {
367 337 ptr++;
368 338 size = (uintptr_t)ptr - (uintptr_t)boot_env.be_env;
369 339 if (size > boot_env.be_size)
370 340 return (NULL);
371 341 }
372 342 ptr++;
373 343
374 344 /* If the remainder is shorter than name + 2, get out. */
375 345 size = (uintptr_t)ptr - (uintptr_t)boot_env.be_env;
376 346 if (boot_env.be_size - size < len + 2)
377 347 return (NULL);
378 348 } while (*ptr != '\0');
379 349 return (NULL);
380 350 }
381 351
382 352 /*
383 353 * Get prop value from either command line or boot environment.
384 354 * We always check kernel command line first, as this will keep the
385 355 * functionality and will allow user to override the values in environment.
386 356 */
387 357 const char *
388 358 find_boot_prop(const char *name)
389 359 {
390 360 const char *value = find_boot_line_prop(name);
391 361
392 362 if (value == NULL)
393 363 value = find_boot_env_prop(name);
394 364 return (value);
395 365 }
396 366
397 367 #define MATCHES(p, pat) \
398 368 (strncmp(p, pat, strlen(pat)) == 0 ? (p += strlen(pat), 1) : 0)
399 369
400 370 #define SKIP(p, c) \
401 371 while (*(p) != 0 && *p != (c)) \
402 372 ++(p); \
403 373 if (*(p) == (c)) \
404 374 ++(p);
405 375
406 376 /*
407 377 * find a tty mode property either from cmdline or from boot properties
408 378 */
409 379 static const char *
410 380 get_mode_value(char *name)
411 381 {
412 382 /*
413 383 * when specified on boot line it looks like "name" "="....
414 384 */
415 385 if (boot_line != NULL) {
416 386 return (find_boot_prop(name));
417 387 }
418 388
419 389 #if defined(_BOOT)
420 390 return (NULL);
421 391 #else
422 392 /*
423 393 * if we're running in the full kernel we check the bootenv.rc settings
424 394 */
425 395 {
426 396 static char propval[20];
427 397
428 398 propval[0] = 0;
429 399 if (do_bsys_getproplen(NULL, name) <= 0)
430 400 return (NULL);
431 401 (void) do_bsys_getprop(NULL, name, propval);
432 402 return (propval);
433 403 }
434 404 #endif
435 405 }
436 406
437 407 /*
438 408 * adjust serial port based on properties
439 409 * These come either from the cmdline or from boot properties.
440 410 */
441 411 static void
442 412 serial_adjust_prop(void)
443 413 {
444 414 char propname[20];
445 415 const char *propval;
446 416 const char *p;
447 417 ulong_t baud;
448 418 uchar_t lcr = 0;
449 419 uchar_t mcr = DTR | RTS;
450 420
451 421 (void) strcpy(propname, "ttyX-mode");
452 422 propname[3] = 'a' + tty_num;
453 423 propval = get_mode_value(propname);
454 424 if (propval == NULL)
455 425 propval = "9600,8,n,1,-";
456 426 #if !defined(_BOOT)
457 427 else
458 428 console_mode_set = 1;
459 429 #endif
460 430
461 431 /* property is of the form: "9600,8,n,1,-" */
462 432 p = propval;
463 433 if (MATCHES(p, "110,"))
464 434 baud = ASY110;
465 435 else if (MATCHES(p, "150,"))
466 436 baud = ASY150;
467 437 else if (MATCHES(p, "300,"))
468 438 baud = ASY300;
469 439 else if (MATCHES(p, "600,"))
470 440 baud = ASY600;
471 441 else if (MATCHES(p, "1200,"))
472 442 baud = ASY1200;
473 443 else if (MATCHES(p, "2400,"))
474 444 baud = ASY2400;
475 445 else if (MATCHES(p, "4800,"))
476 446 baud = ASY4800;
477 447 else if (MATCHES(p, "19200,"))
478 448 baud = ASY19200;
479 449 else if (MATCHES(p, "38400,"))
480 450 baud = ASY38400;
481 451 else if (MATCHES(p, "57600,"))
482 452 baud = ASY57600;
483 453 else if (MATCHES(p, "115200,"))
484 454 baud = ASY115200;
485 455 else {
486 456 baud = ASY9600;
487 457 SKIP(p, ',');
488 458 }
489 459 outb(port + LCR, DLAB);
490 460 outb(port + DAT + DLL, baud & 0xff);
491 461 outb(port + DAT + DLH, (baud >> 8) & 0xff);
492 462
493 463 switch (*p) {
494 464 case '5':
495 465 lcr |= BITS5;
496 466 ++p;
497 467 break;
498 468 case '6':
499 469 lcr |= BITS6;
500 470 ++p;
501 471 break;
502 472 case '7':
503 473 lcr |= BITS7;
504 474 ++p;
505 475 break;
506 476 case '8':
507 477 ++p;
508 478 default:
509 479 lcr |= BITS8;
510 480 break;
511 481 }
512 482
513 483 SKIP(p, ',');
514 484
515 485 switch (*p) {
516 486 case 'n':
517 487 lcr |= PARITY_NONE;
518 488 ++p;
519 489 break;
520 490 case 'o':
521 491 lcr |= PARITY_ODD;
522 492 ++p;
523 493 break;
524 494 case 'e':
525 495 ++p;
526 496 default:
527 497 lcr |= PARITY_EVEN;
528 498 break;
529 499 }
530 500
531 501
532 502 SKIP(p, ',');
533 503
534 504 switch (*p) {
535 505 case '1':
536 506 /* STOP1 is 0 */
537 507 ++p;
538 508 break;
539 509 default:
540 510 lcr |= STOP2;
541 511 break;
542 512 }
543 513 /* set parity bits */
544 514 outb(port + LCR, lcr);
545 515
546 516 (void) strcpy(propname, "ttyX-rts-dtr-off");
547 517 propname[3] = 'a' + tty_num;
548 518 propval = get_mode_value(propname);
549 519 if (propval == NULL)
550 520 propval = "false";
551 521 if (propval[0] != 'f' && propval[0] != 'F')
552 522 mcr = 0;
553 523 /* set modem control bits */
554 524 outb(port + MCR, mcr | OUT2);
555 525 }
556 526
557 527 /* Obtain the console type */
558 528 int
559 529 boot_console_type(int *tnum)
560 530 {
561 531 if (tnum != NULL)
562 532 *tnum = tty_num;
563 533 return (console);
564 534 }
565 535
566 536 /*
567 537 * A structure to map console names to values.
568 538 */
569 539 typedef struct {
570 540 char *name;
571 541 int value;
572 542 } console_value_t;
573 543
574 544 console_value_t console_devices[] = {
575 545 { "ttya", CONS_TTY }, /* 0 */
576 546 { "ttyb", CONS_TTY }, /* 1 */
577 547 { "ttyc", CONS_TTY }, /* 2 */
578 548 { "ttyd", CONS_TTY }, /* 3 */
579 549 { "text", CONS_SCREEN_TEXT },
580 550 { "graphics", CONS_SCREEN_GRAPHICS },
581 551 #if defined(__xpv)
582 552 { "hypervisor", CONS_HYPERVISOR },
583 553 #endif
584 554 #if !defined(_BOOT)
585 555 { "usb-serial", CONS_USBSER },
586 556 #endif
587 557 { NULL, CONS_INVALID }
588 558 };
589 559
590 560 static void
591 561 bcons_init_env(struct xboot_info *xbi)
592 562 {
593 563 uint32_t i;
594 564 struct boot_modules *modules;
595 565
596 566 modules = (struct boot_modules *)(uintptr_t)xbi->bi_modules;
597 567 for (i = 0; i < xbi->bi_module_cnt; i++) {
|
↓ open down ↓ |
375 lines elided |
↑ open up ↑ |
598 568 if (modules[i].bm_type == BMT_ENV)
599 569 break;
600 570 }
601 571 if (i == xbi->bi_module_cnt)
602 572 return;
603 573
604 574 boot_env.be_env = (char *)(uintptr_t)modules[i].bm_addr;
605 575 boot_env.be_size = modules[i].bm_size;
606 576 }
607 577
578 +int
579 +boot_fb(struct xboot_info *xbi, int console)
580 +{
581 + if (xbi_fb_init(xbi, &bcons_dev) == B_FALSE)
582 + return (console);
583 +
584 + /* FB address is not set, fall back to serial terminal. */
585 + if (fb_info.paddr == 0) {
586 + return (CONS_TTY);
587 + }
588 +
589 + fb_info.terminal.x = VGA_TEXT_COLS;
590 + fb_info.terminal.y = VGA_TEXT_ROWS;
591 + boot_fb_init(CONS_FRAMEBUFFER);
592 +
593 + if (console == CONS_SCREEN_TEXT)
594 + return (CONS_FRAMEBUFFER);
595 + return (console);
596 +}
597 +
598 +/*
599 + * TODO.
600 + * quick and dirty local atoi. Perhaps should build with strtol, but
601 + * dboot & early boot mix does overcomplicate things much.
602 + * Stolen from libc anyhow.
603 + */
604 +static int
605 +atoi(const char *p)
606 +{
607 + int n, c, neg = 0;
608 + unsigned char *up = (unsigned char *)p;
609 +
610 + if (!isdigit(c = *up)) {
611 + while (isspace(c))
612 + c = *++up;
613 + switch (c) {
614 + case '-':
615 + neg++;
616 + /* FALLTHROUGH */
617 + case '+':
618 + c = *++up;
619 + }
620 + if (!isdigit(c))
621 + return (0);
622 + }
623 + for (n = '0' - c; isdigit(c = *++up); ) {
624 + n *= 10; /* two steps to avoid unnecessary overflow */
625 + n += '0' - c; /* accum neg to avoid surprises at MAX */
626 + }
627 + return (neg ? n : -n);
628 +}
629 +
630 +static void
631 +bcons_init_fb(void)
632 +{
633 + const char *propval;
634 + int intval;
635 +
636 + /* initialize with explicit default values */
637 + fb_info.fg_color = CONS_COLOR;
638 + fb_info.bg_color = 0;
639 + fb_info.inverse = B_FALSE;
640 + fb_info.inverse_screen = B_FALSE;
641 +
642 + /* color values are 0 - 7 */
643 + propval = find_boot_prop("tem.fg_color");
644 + if (propval != NULL) {
645 + intval = atoi(propval);
646 + if (intval >= 0 && intval <= 7)
647 + fb_info.fg_color = intval;
648 + }
649 +
650 + /* color values are 0 - 7 */
651 + propval = find_boot_prop("tem.bg_color");
652 + if (propval != NULL && ISDIGIT(*propval)) {
653 + intval = atoi(propval);
654 + if (intval >= 0 && intval <= 7)
655 + fb_info.bg_color = intval;
656 + }
657 +
658 + /* get inverses. allow 0, 1, true, false */
659 + propval = find_boot_prop("tem.inverse");
660 + if (propval != NULL) {
661 + if (*propval == '1' || MATCHES(propval, "true"))
662 + fb_info.inverse = B_TRUE;
663 + }
664 +
665 + propval = find_boot_prop("tem.inverse-screen");
666 + if (propval != NULL) {
667 + if (*propval == '1' || MATCHES(propval, "true"))
668 + fb_info.inverse_screen = B_TRUE;
669 + }
670 +
671 +#if defined(_BOOT)
672 + /*
673 + * Load cursor position from bootloader only in dboot,
674 + * dboot will pass cursor position to kernel via xboot info.
675 + */
676 + propval = find_boot_prop("tem.cursor.row");
677 + if (propval != NULL) {
678 + intval = atoi(propval);
679 + if (intval >= 0 && intval <= 0xFFFF)
680 + fb_info.cursor.pos.y = intval;
681 + }
682 +
683 + propval = find_boot_prop("tem.cursor.col");
684 + if (propval != NULL) {
685 + intval = atoi(propval);
686 + if (intval >= 0 && intval <= 0xFFFF)
687 + fb_info.cursor.pos.x = intval;
688 + }
689 +#endif
690 +}
691 +
692 +/*
693 + * Go through the console_devices array trying to match the string
694 + * we were given. The string on the command line must end with
695 + * a comma or white space.
696 + *
697 + * Eventually we need to rework this to process dual console setup.
698 + * This function does set tty_num as an side effect.
699 + */
700 +static int
701 +lookup_console_devices(const char *cons_str)
702 +{
703 + int n, cons;
704 + size_t len, cons_len;
705 + console_value_t *consolep;
706 +
707 + cons = CONS_INVALID;
708 + if (cons_str != NULL) {
709 +
710 + cons_len = strlen(cons_str);
711 + for (n = 0; console_devices[n].name != NULL; n++) {
712 + consolep = &console_devices[n];
713 + len = strlen(consolep->name);
714 + if ((len <= cons_len) && ((cons_str[len] == '\0') ||
715 + (cons_str[len] == ',') || (cons_str[len] == '\'') ||
716 + (cons_str[len] == '"') || ISSPACE(cons_str[len])) &&
717 + (strncmp(cons_str, consolep->name, len) == 0)) {
718 + cons = consolep->value;
719 + if (cons == CONS_TTY)
720 + tty_num = n;
721 + break;
722 + }
723 + }
724 + }
725 + return (cons);
726 +}
727 +
608 728 void
609 729 bcons_init(struct xboot_info *xbi)
610 730 {
611 - console_value_t *consolep;
612 - size_t len, cons_len;
613 731 const char *cons_str;
614 732 #if !defined(_BOOT)
615 733 static char console_text[] = "text";
616 734 extern int post_fastreboot;
617 735 #endif
618 736
737 + if (xbi == NULL) {
738 + /* This is very early dboot console, set up ttya. */
739 + console = CONS_TTY;
740 + serial_init();
741 + return;
742 + }
743 +
619 744 /* Set up data to fetch properties from commad line and boot env. */
620 745 boot_line = (char *)(uintptr_t)xbi->bi_cmdline;
621 746 bcons_init_env(xbi);
622 747 console = CONS_INVALID;
623 748
749 + /* set up initial fb_info */
750 + bcons_init_fb();
751 +
624 752 #if defined(__xpv)
625 753 bcons_init_xen(boot_line);
626 754 #endif /* __xpv */
627 755
756 + /*
757 + * First check for diag-device.
758 + */
759 + cons_str = find_boot_prop("diag-device");
760 + if (cons_str != NULL) {
761 + diag = lookup_console_devices(cons_str);
762 + serial_init();
763 + }
764 +
628 765 cons_str = find_boot_prop("console");
629 766 if (cons_str == NULL)
630 767 cons_str = find_boot_prop("output-device");
631 768
632 769 #if !defined(_BOOT)
633 770 if (post_fastreboot && strcmp(cons_str, "graphics") == 0)
634 771 cons_str = console_text;
635 772 #endif
636 773
637 - /*
638 - * Go through the console_devices array trying to match the string
639 - * we were given. The string on the command line must end with
640 - * a comma or white space.
641 - */
642 - if (cons_str != NULL) {
643 - int n;
774 + if (cons_str != NULL)
775 + console = lookup_console_devices(cons_str);
644 776
645 - cons_len = strlen(cons_str);
646 - for (n = 0; console_devices[n].name != NULL; n++) {
647 - consolep = &console_devices[n];
648 - len = strlen(consolep->name);
649 - if ((len <= cons_len) && ((cons_str[len] == '\0') ||
650 - (cons_str[len] == ',') || (cons_str[len] == '\'') ||
651 - (cons_str[len] == '"') || ISSPACE(cons_str[len])) &&
652 - (strncmp(cons_str, consolep->name, len) == 0)) {
653 - console = consolep->value;
654 - if (console == CONS_TTY)
655 - tty_num = n;
656 - break;
657 - }
658 - }
659 - }
660 -
661 777 #if defined(__xpv)
662 778 /*
663 779 * domU's always use the hypervisor regardless of what
664 780 * the console variable may be set to.
665 781 */
666 782 if (!DOMAIN_IS_INITDOMAIN(xen_info)) {
667 783 console = CONS_HYPERVISOR;
668 784 console_hypervisor_redirect = B_TRUE;
669 785 }
670 786 #endif /* __xpv */
671 787
672 788 /*
673 789 * If no console device specified, default to text.
674 790 * Remember what was specified for second phase.
675 791 */
676 792 if (console == CONS_INVALID)
677 793 console = CONS_SCREEN_TEXT;
678 794 #if !defined(_BOOT)
679 795 else
680 796 console_set = 1;
681 797 #endif
682 798
683 799 #if defined(__xpv)
684 800 if (DOMAIN_IS_INITDOMAIN(xen_info)) {
685 801 switch (HYPERVISOR_console_io(CONSOLEIO_get_device, 0, NULL)) {
686 802 case XEN_CONSOLE_COM1:
687 803 case XEN_CONSOLE_COM2:
688 804 console_hypervisor_device = CONS_TTY;
689 805 console_hypervisor_tty_num = tty_num;
690 806 break;
691 807 case XEN_CONSOLE_VGA:
692 808 /*
693 809 * Currently xen doesn't really support
694 810 * keyboard/display console devices.
695 811 * What this setting means is that
696 812 * "vga=keep" has been enabled, which is
697 813 * more of a xen debugging tool that a
698 814 * true console mode. Hence, we're going
699 815 * to ignore this xen "console" setting.
700 816 */
701 817 /*FALLTHROUGH*/
702 818 default:
703 819 console_hypervisor_device = CONS_INVALID;
704 820 }
705 821 }
706 822
707 823 /*
|
↓ open down ↓ |
37 lines elided |
↑ open up ↑ |
708 824 * if the hypervisor is using the currently selected serial
709 825 * port then default to using the hypervisor as the console
710 826 * device.
711 827 */
712 828 if (console == console_hypervisor_device) {
713 829 console = CONS_HYPERVISOR;
714 830 console_hypervisor_redirect = B_TRUE;
715 831 }
716 832 #endif /* __xpv */
717 833
834 + /* make sure the FB is set up if present */
835 + console = boot_fb(xbi, console);
718 836 switch (console) {
719 837 case CONS_TTY:
720 838 serial_init();
721 839 break;
722 840
723 841 case CONS_HYPERVISOR:
724 842 break;
725 843
726 844 #if !defined(_BOOT)
727 845 case CONS_USBSER:
728 846 /*
729 847 * We can't do anything with the usb serial
730 848 * until we have memory management.
731 849 */
732 850 break;
733 851 #endif
734 852 case CONS_SCREEN_GRAPHICS:
735 853 kb_init();
736 854 break;
737 855 case CONS_SCREEN_TEXT:
856 + boot_vga_init(&bcons_dev);
857 + /* Fall through */
738 858 default:
739 -#if defined(_BOOT)
740 - clear_screen(); /* clears the grub or xen screen */
741 -#endif /* _BOOT */
742 859 kb_init();
743 860 break;
744 861 }
745 862 }
746 863
747 864 #if !defined(_BOOT)
748 865 /*
749 866 * 2nd part of console initialization.
750 867 * In the kernel (ie. fakebop), this can be used only to switch to
751 868 * using a serial port instead of screen based on the contents
752 869 * of the bootenv.rc file.
753 870 */
754 871 /*ARGSUSED*/
755 872 void
756 873 bcons_init2(char *inputdev, char *outputdev, char *consoledev)
757 874 {
758 875 int cons = CONS_INVALID;
759 876 int ttyn;
760 877 char *devnames[] = { consoledev, outputdev, inputdev, NULL };
761 878 console_value_t *consolep;
762 879 int i;
763 880 extern int post_fastreboot;
764 881
765 882 if (post_fastreboot && console == CONS_SCREEN_GRAPHICS)
766 883 console = CONS_SCREEN_TEXT;
767 884
768 885 if (console != CONS_USBSER && console != CONS_SCREEN_GRAPHICS) {
769 886 if (console_set) {
770 887 /*
771 888 * If the console was set on the command line,
772 889 * but the ttyX-mode was not, we only need to
773 890 * check bootenv.rc for that setting.
774 891 */
775 892 if ((!console_mode_set) && (console == CONS_TTY))
776 893 serial_init();
777 894 return;
778 895 }
779 896
780 897 for (i = 0; devnames[i] != NULL; i++) {
781 898 int n;
782 899
783 900 for (n = 0; console_devices[n].name != NULL; n++) {
784 901 consolep = &console_devices[n];
785 902 if (strcmp(devnames[i], consolep->name) == 0) {
786 903 cons = consolep->value;
787 904 if (cons == CONS_TTY)
788 905 ttyn = n;
789 906 }
790 907 }
791 908 if (cons != CONS_INVALID)
792 909 break;
793 910 }
794 911
795 912 #if defined(__xpv)
796 913 /*
797 914 * if the hypervisor is using the currently selected console
798 915 * device then default to using the hypervisor as the console
799 916 * device.
800 917 */
801 918 if (cons == console_hypervisor_device) {
802 919 cons = CONS_HYPERVISOR;
803 920 console_hypervisor_redirect = B_TRUE;
804 921 }
805 922 #endif /* __xpv */
806 923
807 924 if ((cons == CONS_INVALID) || (cons == console)) {
808 925 /*
809 926 * we're sticking with whatever the current setting is
810 927 */
811 928 return;
812 929 }
813 930
814 931 console = cons;
815 932 if (cons == CONS_TTY) {
816 933 tty_num = ttyn;
817 934 serial_init();
818 935 return;
819 936 }
820 937 } else {
821 938 /*
822 939 * USB serial and GRAPHICS console
823 940 * we just collect data into a buffer
824 941 */
825 942 extern void *defcons_init(size_t);
826 943 defcons_buf = defcons_cur = defcons_init(MMU_PAGESIZE);
827 944 }
828 945 }
829 946
830 947 #if defined(__xpv)
831 948 boolean_t
832 949 bcons_hypervisor_redirect(void)
833 950 {
834 951 return (console_hypervisor_redirect);
835 952 }
836 953
837 954 void
838 955 bcons_device_change(int new_console)
839 956 {
840 957 if (new_console < CONS_MIN || new_console > CONS_MAX)
841 958 return;
842 959
843 960 /*
844 961 * If we are asked to switch the console to the hypervisor, that
845 962 * really means to switch the console to whichever device the
846 963 * hypervisor is/was using.
847 964 */
848 965 if (new_console == CONS_HYPERVISOR)
849 966 new_console = console_hypervisor_device;
850 967
851 968 console = new_console;
852 969
853 970 if (new_console == CONS_TTY) {
854 971 tty_num = console_hypervisor_tty_num;
855 972 serial_init();
856 973 }
857 974 }
858 975 #endif /* __xpv */
859 976
860 977 static void
861 978 defcons_putchar(int c)
862 979 {
863 980 if (defcons_buf != NULL &&
864 981 defcons_cur + 1 - defcons_buf < MMU_PAGESIZE) {
865 982 *defcons_cur++ = c;
866 983 *defcons_cur = 0;
867 984 }
868 985 }
869 986 #endif /* _BOOT */
870 987
871 988 static void
872 989 serial_putchar(int c)
873 990 {
874 991 int checks = 10000;
875 992
876 993 while (((inb(port + LSR) & XHRE) == 0) && checks--)
877 994 ;
878 995 outb(port + DAT, (char)c);
879 996 }
880 997
881 998 static int
882 999 serial_getchar(void)
883 1000 {
884 1001 uchar_t lsr;
885 1002
886 1003 while (serial_ischar() == 0)
887 1004 ;
888 1005
889 1006 lsr = inb(port + LSR);
890 1007 if (lsr & (SERIAL_BREAK | SERIAL_FRAME |
891 1008 SERIAL_PARITY | SERIAL_OVERRUN)) {
892 1009 if (lsr & SERIAL_OVERRUN) {
893 1010 return (inb(port + DAT));
894 1011 } else {
895 1012 /* Toss the garbage */
896 1013 (void) inb(port + DAT);
897 1014 return (0);
898 1015 }
899 1016 }
|
↓ open down ↓ |
148 lines elided |
↑ open up ↑ |
900 1017 return (inb(port + DAT));
901 1018 }
902 1019
903 1020 static int
904 1021 serial_ischar(void)
905 1022 {
906 1023 return (inb(port + LSR) & RCA);
907 1024 }
908 1025
909 1026 static void
910 -_doputchar(int c)
1027 +btem_control(btem_state_t *btem, int c)
911 1028 {
912 - switch (console) {
1029 + int y, rows, cols;
1030 +
1031 + rows = fb_info.cursor.pos.y;
1032 + cols = fb_info.cursor.pos.x;
1033 +
1034 + btem->btem_state = A_STATE_START;
1035 + switch (c) {
1036 + case A_BS:
1037 + bcons_dev.bd_setpos(rows, cols - 1);
1038 + break;
1039 +
1040 + case A_HT:
1041 + cols += 8 - (cols % 8);
1042 + if (cols == fb_info.terminal.x)
1043 + cols = fb_info.terminal.x - 1;
1044 + bcons_dev.bd_setpos(rows, cols);
1045 + break;
1046 +
1047 + case A_CR:
1048 + bcons_dev.bd_setpos(rows, 0);
1049 + break;
1050 +
1051 + case A_FF:
1052 + for (y = 0; y < fb_info.terminal.y; y++) {
1053 + bcons_dev.bd_setpos(y, 0);
1054 + bcons_dev.bd_eraseline();
1055 + }
1056 + bcons_dev.bd_setpos(0, 0);
1057 + break;
1058 +
1059 + case A_ESC:
1060 + btem->btem_state = A_STATE_ESC;
1061 + break;
1062 +
1063 + default:
1064 + bcons_dev.bd_putchar(c);
1065 + break;
1066 + }
1067 +}
1068 +
1069 +/*
1070 + * if parameters [0..count - 1] are not set, set them to the value
1071 + * of newparam.
1072 + */
1073 +static void
1074 +btem_setparam(btem_state_t *btem, int count, int newparam)
1075 +{
1076 + int i;
1077 +
1078 + for (i = 0; i < count; i++) {
1079 + if (btem->btem_params[i] == -1)
1080 + btem->btem_params[i] = newparam;
1081 + }
1082 +}
1083 +
1084 +static void
1085 +btem_chkparam(btem_state_t *btem, int c)
1086 +{
1087 + int rows, cols;
1088 +
1089 + rows = fb_info.cursor.pos.y;
1090 + cols = fb_info.cursor.pos.x;
1091 + switch (c) {
1092 + case '@': /* insert char */
1093 + btem_setparam(btem, 1, 1);
1094 + bcons_dev.bd_shift(btem->btem_params[0]);
1095 + break;
1096 +
1097 + case 'A': /* cursor up */
1098 + btem_setparam(btem, 1, 1);
1099 + bcons_dev.bd_setpos(rows - btem->btem_params[0], cols);
1100 + break;
1101 +
1102 + case 'B': /* cursor down */
1103 + btem_setparam(btem, 1, 1);
1104 + bcons_dev.bd_setpos(rows + btem->btem_params[0], cols);
1105 + break;
1106 +
1107 + case 'C': /* cursor right */
1108 + btem_setparam(btem, 1, 1);
1109 + bcons_dev.bd_setpos(rows, cols + btem->btem_params[0]);
1110 + break;
1111 +
1112 + case 'D': /* cursor left */
1113 + btem_setparam(btem, 1, 1);
1114 + bcons_dev.bd_setpos(rows, cols - btem->btem_params[0]);
1115 + break;
1116 +
1117 + case 'K':
1118 + bcons_dev.bd_eraseline();
1119 + break;
1120 + default:
1121 + /* bcons_dev.bd_putchar(c); */
1122 + break;
1123 + }
1124 + btem->btem_state = A_STATE_START;
1125 +}
1126 +
1127 +static void
1128 +btem_getparams(btem_state_t *btem, int c)
1129 +{
1130 + if (c >= '0' && c <= '9') {
1131 + btem->btem_paramval = btem->btem_paramval * 10 + c - '0';
1132 + btem->btem_gotparam = B_TRUE;
1133 + return;
1134 + }
1135 +
1136 + if (btem->btem_curparam < BTEM_MAXPARAMS) {
1137 + if (btem->btem_gotparam == B_TRUE) {
1138 + btem->btem_params[btem->btem_curparam] =
1139 + btem->btem_paramval;
1140 + }
1141 + btem->btem_curparam++;
1142 + }
1143 +
1144 + if (c == ';') {
1145 + /* Restart parameter search */
1146 + btem->btem_gotparam = B_FALSE;
1147 + btem->btem_paramval = 0;
1148 + } else {
1149 + btem_chkparam(btem, c);
1150 + }
1151 +}
1152 +
1153 +/* Simple boot terminal parser. */
1154 +static void
1155 +btem_parse(btem_state_t *btem, int c)
1156 +{
1157 + int i;
1158 +
1159 + /* Normal state? */
1160 + if (btem->btem_state == A_STATE_START) {
1161 + if (c == A_CSI || c < ' ')
1162 + btem_control(btem, c);
1163 + else
1164 + bcons_dev.bd_putchar(c);
1165 + return;
1166 + }
1167 +
1168 + /* In <ESC> sequence */
1169 + if (btem->btem_state != A_STATE_ESC) {
1170 + btem_getparams(btem, c);
1171 + return;
1172 + }
1173 +
1174 + /* Previous char was <ESC> */
1175 + switch (c) {
1176 + case '[':
1177 + btem->btem_curparam = 0;
1178 + btem->btem_paramval = 0;
1179 + btem->btem_gotparam = B_FALSE;
1180 + /* clear the parameters */
1181 + for (i = 0; i < BTEM_MAXPARAMS; i++)
1182 + btem->btem_params[i] = -1;
1183 + btem->btem_state = A_STATE_CSI;
1184 + return;
1185 +
1186 + case 'Q': /* <ESC>Q */
1187 + case 'C': /* <ESC>C */
1188 + btem->btem_state = A_STATE_START;
1189 + return;
1190 +
1191 + default:
1192 + btem->btem_state = A_STATE_START;
1193 + break;
1194 + }
1195 +
1196 + if (c < ' ')
1197 + btem_control(btem, c);
1198 + else
1199 + bcons_dev.bd_putchar(c);
1200 +}
1201 +
1202 +static void
1203 +_doputchar(int device, int c)
1204 +{
1205 + switch (device) {
913 1206 case CONS_TTY:
914 1207 serial_putchar(c);
915 1208 return;
916 1209 case CONS_SCREEN_TEXT:
917 - screen_putchar(c);
1210 + case CONS_FRAMEBUFFER:
1211 + bcons_dev.bd_cursor(B_FALSE);
1212 + btem_parse(&boot_tem, c);
1213 + bcons_dev.bd_cursor(B_TRUE);
918 1214 return;
919 1215 case CONS_SCREEN_GRAPHICS:
920 1216 #if !defined(_BOOT)
921 1217 case CONS_USBSER:
922 1218 defcons_putchar(c);
923 1219 #endif /* _BOOT */
1220 + default:
924 1221 return;
925 1222 }
926 1223 }
927 1224
928 1225 void
929 1226 bcons_putchar(int c)
930 1227 {
931 - static int bhcharpos = 0;
932 -
933 1228 #if defined(__xpv)
934 1229 if (!DOMAIN_IS_INITDOMAIN(xen_info) ||
935 1230 console == CONS_HYPERVISOR) {
936 1231 bcons_putchar_xen(c);
937 1232 return;
938 1233 }
939 1234 #endif /* __xpv */
940 1235
941 - if (c == '\t') {
942 - do {
943 - _doputchar(' ');
944 - } while (++bhcharpos % 8);
945 - return;
946 - } else if (c == '\n' || c == '\r') {
947 - bhcharpos = 0;
948 - _doputchar('\r');
949 - _doputchar(c);
950 - return;
951 - } else if (c == '\b') {
952 - if (bhcharpos)
953 - bhcharpos--;
954 - _doputchar(c);
955 - return;
1236 + if (c == '\n') {
1237 + _doputchar(console, '\r');
1238 + if (diag != console)
1239 + _doputchar(diag, '\r');
956 1240 }
957 -
958 - bhcharpos++;
959 - _doputchar(c);
1241 + _doputchar(console, c);
1242 + if (diag != console)
1243 + _doputchar(diag, c);
960 1244 }
961 1245
962 1246 /*
963 1247 * kernel character input functions
964 1248 */
965 1249 int
966 1250 bcons_getchar(void)
967 1251 {
968 1252 #if defined(__xpv)
969 1253 if (!DOMAIN_IS_INITDOMAIN(xen_info) ||
970 1254 console == CONS_HYPERVISOR)
971 1255 return (bcons_getchar_xen());
972 1256 #endif /* __xpv */
973 1257
974 - switch (console) {
975 - case CONS_TTY:
976 - return (serial_getchar());
977 - default:
978 - return (kb_getchar());
1258 + for (;;) {
1259 + if (console == CONS_TTY || diag == CONS_TTY) {
1260 + if (serial_ischar())
1261 + return (serial_getchar());
1262 + }
1263 + if (console != CONS_INVALID || diag != CONS_INVALID) {
1264 + if (kb_ischar())
1265 + return (kb_getchar());
1266 + }
979 1267 }
980 1268 }
981 1269
982 1270 #if !defined(_BOOT)
983 1271
984 1272 int
985 1273 bcons_ischar(void)
986 1274 {
1275 + int c = 0;
987 1276
988 1277 #if defined(__xpv)
989 1278 if (!DOMAIN_IS_INITDOMAIN(xen_info) ||
990 1279 console == CONS_HYPERVISOR)
991 1280 return (bcons_ischar_xen());
992 1281 #endif /* __xpv */
993 1282
994 1283 switch (console) {
995 1284 case CONS_TTY:
1285 + c = serial_ischar();
1286 + break;
1287 +
1288 + case CONS_INVALID:
1289 + break;
1290 +
1291 + default:
1292 + c = kb_ischar();
1293 + }
1294 + if (c != 0)
1295 + return (c);
1296 +
1297 + switch (diag) {
1298 + case CONS_TTY:
996 1299 return (serial_ischar());
1300 +
1301 + case CONS_INVALID:
1302 + break;
1303 +
997 1304 default:
998 1305 return (kb_ischar());
999 1306 }
1307 +
1308 + return (c);
1000 1309 }
1001 1310
1002 1311 #endif /* _BOOT */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX