boot_fb.c (8e6d016f) boot_fb.c (29a77b73)
1/*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at

--- 17 unchanged lines hidden (view full) ---

26
27#include <sys/types.h>
28#include <sys/systm.h>
29#include <sys/multiboot2.h>
30#include <sys/framebuffer.h>
31#include <sys/bootinfo.h>
32#include <sys/boot_console.h>
33#include <sys/bootconf.h>
1/*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at

--- 17 unchanged lines hidden (view full) ---

26
27#include <sys/types.h>
28#include <sys/systm.h>
29#include <sys/multiboot2.h>
30#include <sys/framebuffer.h>
31#include <sys/bootinfo.h>
32#include <sys/boot_console.h>
33#include <sys/bootconf.h>
34#include "boot_console_impl.h"
34
35#define P2ROUNDUP(x, align) (-(-(x) & -(align)))
36#define MIN(a, b) ((a) < (b) ? (a) : (b))
37
38/*
39 * Simplified visual_io data structures from visual_io.h
40 */
41

--- 14 unchanged lines hidden (view full) ---

56 uint16_t t_col; /* Col to move to */
57};
58
59/* we have built in fonts 12x22, 6x10, 7x14 and depth 32. */
60#define MAX_GLYPH (12 * 22 * 4)
61
62static struct font boot_fb_font; /* set by set_font() */
63static uint8_t glyph[MAX_GLYPH];
35
36#define P2ROUNDUP(x, align) (-(-(x) & -(align)))
37#define MIN(a, b) ((a) < (b) ? (a) : (b))
38
39/*
40 * Simplified visual_io data structures from visual_io.h
41 */
42

--- 14 unchanged lines hidden (view full) ---

57 uint16_t t_col; /* Col to move to */
58};
59
60/* we have built in fonts 12x22, 6x10, 7x14 and depth 32. */
61#define MAX_GLYPH (12 * 22 * 4)
62
63static struct font boot_fb_font; /* set by set_font() */
64static uint8_t glyph[MAX_GLYPH];
64static uint32_t last_line_size;
65static fb_info_pixel_coord_t last_line;
66
67/* color translation */
68typedef struct {
69 uint8_t red[16];
70 uint8_t green[16];
71 uint8_t blue[16];
72} text_cmap_t;
73

--- 8 unchanged lines hidden (view full) ---

82/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
83 Wh+ Bk Bl Gr Cy Rd Mg Br Wh Bk+ Bl+ Gr+ Cy+ Rd+ Mg+ Yw */
84 0xff,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x40,0x00,0x00,0x00,0xff,0xff,0xff,
85 0xff,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x40,0x00,0xff,0xff,0x00,0x00,0xff,
86 0xff,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x40,0xff,0x00,0xff,0x00,0xff,0x00
87/* END CSTYLED */
88};
89
65
66/* color translation */
67typedef struct {
68 uint8_t red[16];
69 uint8_t green[16];
70 uint8_t blue[16];
71} text_cmap_t;
72

--- 8 unchanged lines hidden (view full) ---

81/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
82 Wh+ Bk Bl Gr Cy Rd Mg Br Wh Bk+ Bl+ Gr+ Cy+ Rd+ Mg+ Yw */
83 0xff,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x40,0x00,0x00,0x00,0xff,0xff,0xff,
84 0xff,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x40,0x00,0xff,0xff,0x00,0x00,0xff,
85 0xff,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x40,0xff,0x00,0xff,0x00,0xff,0x00
86/* END CSTYLED */
87};
88
89static void boot_fb_putchar(int);
90static void boot_fb_eraseline(void);
91static void boot_fb_setpos(int, int);
92static void boot_fb_shiftline(int);
93static void boot_fb_eraseline_impl(uint16_t, uint16_t);
94
90/*
91 * extract data from MB2 framebuffer tag and set up initial frame buffer.
92 */
93boolean_t
95/*
96 * extract data from MB2 framebuffer tag and set up initial frame buffer.
97 */
98boolean_t
94xbi_fb_init(struct xboot_info *xbi)
99xbi_fb_init(struct xboot_info *xbi, bcons_dev_t *bcons_dev)
95{
96 multiboot_tag_framebuffer_t *tag;
97 boot_framebuffer_t *xbi_fb;
98
99 xbi_fb = (boot_framebuffer_t *)(uintptr_t)xbi->bi_framebuffer;
100 if (xbi_fb == NULL)
101 return (B_FALSE);
102

--- 14 unchanged lines hidden (view full) ---

117 fb_info.paddr = tag->framebuffer_common.framebuffer_addr;
118 fb_info.pitch = tag->framebuffer_common.framebuffer_pitch;
119 fb_info.depth = tag->framebuffer_common.framebuffer_bpp;
120 fb_info.bpp = P2ROUNDUP(fb_info.depth, 8) >> 3;
121 fb_info.screen.x = tag->framebuffer_common.framebuffer_width;
122 fb_info.screen.y = tag->framebuffer_common.framebuffer_height;
123 fb_info.fb_size = fb_info.screen.y * fb_info.pitch;
124
100{
101 multiboot_tag_framebuffer_t *tag;
102 boot_framebuffer_t *xbi_fb;
103
104 xbi_fb = (boot_framebuffer_t *)(uintptr_t)xbi->bi_framebuffer;
105 if (xbi_fb == NULL)
106 return (B_FALSE);
107

--- 14 unchanged lines hidden (view full) ---

122 fb_info.paddr = tag->framebuffer_common.framebuffer_addr;
123 fb_info.pitch = tag->framebuffer_common.framebuffer_pitch;
124 fb_info.depth = tag->framebuffer_common.framebuffer_bpp;
125 fb_info.bpp = P2ROUNDUP(fb_info.depth, 8) >> 3;
126 fb_info.screen.x = tag->framebuffer_common.framebuffer_width;
127 fb_info.screen.y = tag->framebuffer_common.framebuffer_height;
128 fb_info.fb_size = fb_info.screen.y * fb_info.pitch;
129
130 bcons_dev->bd_putchar = boot_fb_putchar;
131 bcons_dev->bd_eraseline = boot_fb_eraseline;
132 bcons_dev->bd_cursor = boot_fb_cursor;
133 bcons_dev->bd_setpos = boot_fb_setpos;
134 bcons_dev->bd_shift = boot_fb_shiftline;
135
125 if (fb_info.paddr == 0)
126 fb_info.fb_type = FB_TYPE_UNKNOWN;
127
128 switch (tag->framebuffer_common.framebuffer_type) {
129 case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
130 fb_info.fb_type = FB_TYPE_EGA_TEXT;
131 return (B_FALSE);
132

--- 49 unchanged lines hidden (view full) ---

182 case 8:
183 for (i = 0; i < len; i++)
184 dst[i] = (uint8_t)data;
185 break;
186 case 15:
187 case 16:
188 dst16 = (uint16_t *)dst;
189 len /= 2;
136 if (fb_info.paddr == 0)
137 fb_info.fb_type = FB_TYPE_UNKNOWN;
138
139 switch (tag->framebuffer_common.framebuffer_type) {
140 case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
141 fb_info.fb_type = FB_TYPE_EGA_TEXT;
142 return (B_FALSE);
143

--- 49 unchanged lines hidden (view full) ---

193 case 8:
194 for (i = 0; i < len; i++)
195 dst[i] = (uint8_t)data;
196 break;
197 case 15:
198 case 16:
199 dst16 = (uint16_t *)dst;
200 len /= 2;
190 for (i = 0; i < len; i++) {
201 for (i = 0; i < len; i++)
191 dst16[i] = (uint16_t)data;
202 dst16[i] = (uint16_t)data;
192 }
193 break;
194 case 32:
195 dst32 = (uint32_t *)dst;
196 len /= 4;
203 break;
204 case 32:
205 dst32 = (uint32_t *)dst;
206 len /= 4;
197 for (i = 0; i < len; i++) {
207 for (i = 0; i < len; i++)
198 dst32[i] = data;
208 dst32[i] = data;
199 }
200 break;
201 }
202}
203
204/* copy data to framebuffer */
205static void
206boot_fb_cpy(uint8_t *dst, uint8_t *src, uint32_t len)
207{
208 uint16_t *dst16, *src16;
209 uint32_t *dst32, *src32;
209 break;
210 }
211}
212
213/* copy data to framebuffer */
214static void
215boot_fb_cpy(uint8_t *dst, uint8_t *src, uint32_t len)
216{
217 uint16_t *dst16, *src16;
218 uint32_t *dst32, *src32;
210 uint32_t i;
211
212 switch (fb_info.depth) {
213 case 24:
214 case 8:
219
220 switch (fb_info.depth) {
221 case 24:
222 case 8:
215 for (i = 0; i < len; i++)
216 dst[i] = src[i];
223 default:
224 if (dst <= src) {
225 do {
226 *dst++ = *src++;
227 } while (--len != 0);
228 } else {
229 dst += len;
230 src += len;
231 do {
232 *--dst = *--src;
233 } while (--len != 0);
234 }
217 break;
218 case 15:
219 case 16:
220 dst16 = (uint16_t *)dst;
221 src16 = (uint16_t *)src;
235 break;
236 case 15:
237 case 16:
238 dst16 = (uint16_t *)dst;
239 src16 = (uint16_t *)src;
222 for (i = 0; i < len >> 1; i++) {
223 dst16[i] = src16[i];
240 len /= 2;
241 if (dst16 <= src16) {
242 do {
243 *dst16++ = *src16++;
244 } while (--len != 0);
245 } else {
246 dst16 += len;
247 src16 += len;
248 do {
249 *--dst16 = *--src16;
250 } while (--len != 0);
224 }
225 break;
226 case 32:
227 dst32 = (uint32_t *)dst;
228 src32 = (uint32_t *)src;
251 }
252 break;
253 case 32:
254 dst32 = (uint32_t *)dst;
255 src32 = (uint32_t *)src;
229 for (i = 0; i < len >> 2; i++) {
230 dst32[i] = src32[i];
256 len /= 4;
257 if (dst32 <= src32) {
258 do {
259 *dst32++ = *src32++;
260 } while (--len != 0);
261 } else {
262 dst32 += len;
263 src32 += len;
264 do {
265 *--dst32 = *--src32;
266 } while (--len != 0);
231 }
232 break;
233 }
234}
235
236/*
237 * Allocate shadow frame buffer, called from fakebop.c when early boot
238 * allocator is ready.

--- 12 unchanged lines hidden (view full) ---

251
252 /* Copy FB to shadow */
253 boot_fb_cpy(fb_info.shadow_fb, fb_info.fb, fb_info.fb_size);
254}
255
256/*
257 * Translate ansi color based on inverses and brightness.
258 */
267 }
268 break;
269 }
270}
271
272/*
273 * Allocate shadow frame buffer, called from fakebop.c when early boot
274 * allocator is ready.

--- 12 unchanged lines hidden (view full) ---

287
288 /* Copy FB to shadow */
289 boot_fb_cpy(fb_info.shadow_fb, fb_info.fb, fb_info.fb_size);
290}
291
292/*
293 * Translate ansi color based on inverses and brightness.
294 */
259static void
295void
260boot_get_color(uint32_t *fg, uint32_t *bg)
261{
262 /* ansi to solaris colors, see also boot_console.c */
263 if (fb_info.inverse == B_TRUE ||
264 fb_info.inverse_screen == B_TRUE) {
265 *bg = dim_xlate[fb_info.fg_color];
266 *fg = brt_xlate[fb_info.bg_color];
267 } else {

--- 90 unchanged lines hidden (view full) ---

358 fb_info.cursor.origin.x = window.x;
359 fb_info.cursor.origin.y = window.y;
360 fb_info.cursor.pos.x = 0;
361 fb_info.cursor.pos.y = 0;
362 }
363
364#if defined(_BOOT)
365 /* clear the screen if cursor is set to 0,0 */
296boot_get_color(uint32_t *fg, uint32_t *bg)
297{
298 /* ansi to solaris colors, see also boot_console.c */
299 if (fb_info.inverse == B_TRUE ||
300 fb_info.inverse_screen == B_TRUE) {
301 *bg = dim_xlate[fb_info.fg_color];
302 *fg = brt_xlate[fb_info.bg_color];
303 } else {

--- 90 unchanged lines hidden (view full) ---

394 fb_info.cursor.origin.x = window.x;
395 fb_info.cursor.origin.y = window.y;
396 fb_info.cursor.pos.x = 0;
397 fb_info.cursor.pos.y = 0;
398 }
399
400#if defined(_BOOT)
401 /* clear the screen if cursor is set to 0,0 */
366 fb_info.cursor.pos.x = fb_info.cursor.pos.y = 0;
367 if (console == CONS_FRAMEBUFFER &&
368 fb_info.cursor.pos.x == 0 && fb_info.cursor.pos.y == 0) {
369 uint32_t fg, bg;
370 int i;
402 if (fb_info.cursor.pos.x == 0 && fb_info.cursor.pos.y == 0) {
403 uint32_t fg, bg, toffset;
404 uint16_t y;
371
372 boot_get_color(&fg, &bg);
373 bg = boot_color_map(bg);
374
405
406 boot_get_color(&fg, &bg);
407 bg = boot_color_map(bg);
408
375 for (i = 0; i < fb_info.screen.y; i++) {
376 uint8_t *dest = fb_info.fb + i * fb_info.pitch;
409 toffset = 0;
410 for (y = 0; y < fb_info.screen.y; y++) {
411 uint8_t *dest = fb_info.fb + toffset;
412
377 boot_fb_fill(dest, bg, fb_info.pitch);
413 boot_fb_fill(dest, bg, fb_info.pitch);
414 toffset += fb_info.pitch;
378 }
379 }
380#endif
415 }
416 }
417#endif
381 /* set up pre-calculated last line */
382 last_line_size = fb_info.terminal.x * boot_fb_font.width *
383 fb_info.bpp;
384 last_line.x = window.x;
385 last_line.y = window.y + (fb_info.terminal.y - 1) * boot_fb_font.height;
386
387}
388
389/* copy rectangle to framebuffer. */
390static void
391boot_fb_blit(struct vis_consdisplay *rect)
392{
418}
419
420/* copy rectangle to framebuffer. */
421static void
422boot_fb_blit(struct vis_consdisplay *rect)
423{
393 uint32_t size; /* write size per scanline */
394 uint8_t *fbp, *sfbp; /* fb + calculated offset */
424 uint32_t offset, size; /* write size per scanline */
425 uint8_t *fbp, *sfbp = NULL; /* fb + calculated offset */
395 int i;
396
397 /* make sure we will not write past FB */
398 if (rect->col >= fb_info.screen.x ||
399 rect->row >= fb_info.screen.y ||
400 rect->col + rect->width >= fb_info.screen.x ||
401 rect->row + rect->height >= fb_info.screen.y)
402 return;
403
404 size = rect->width * fb_info.bpp;
426 int i;
427
428 /* make sure we will not write past FB */
429 if (rect->col >= fb_info.screen.x ||
430 rect->row >= fb_info.screen.y ||
431 rect->col + rect->width >= fb_info.screen.x ||
432 rect->row + rect->height >= fb_info.screen.y)
433 return;
434
435 size = rect->width * fb_info.bpp;
405 fbp = fb_info.fb + rect->col * fb_info.bpp +
406 rect->row * fb_info.pitch;
407 if (fb_info.shadow_fb != NULL) {
408 sfbp = fb_info.shadow_fb + rect->col * fb_info.bpp +
409 rect->row * fb_info.pitch;
410 } else {
411 sfbp = NULL;
412 }
436 offset = rect->col * fb_info.bpp + rect->row * fb_info.pitch;
437 fbp = fb_info.fb + offset;
438 if (fb_info.shadow_fb != NULL)
439 sfbp = fb_info.shadow_fb + offset;
413
414 /* write all scanlines in rectangle */
415 for (i = 0; i < rect->height; i++) {
416 uint8_t *dest = fbp + i * fb_info.pitch;
417 uint8_t *src = rect->data + i * size;
418 boot_fb_cpy(dest, src, size);
419 if (sfbp != NULL) {
420 dest = sfbp + i * fb_info.pitch;

--- 24 unchanged lines hidden (view full) ---

445 font_bit_to_pix24(&boot_fb_font, (uint8_t *)glyph, c, fg, bg);
446 break;
447 case 32:
448 font_bit_to_pix32(&boot_fb_font, (uint32_t *)glyph, c, fg, bg);
449 break;
450 }
451}
452
440
441 /* write all scanlines in rectangle */
442 for (i = 0; i < rect->height; i++) {
443 uint8_t *dest = fbp + i * fb_info.pitch;
444 uint8_t *src = rect->data + i * size;
445 boot_fb_cpy(dest, src, size);
446 if (sfbp != NULL) {
447 dest = sfbp + i * fb_info.pitch;

--- 24 unchanged lines hidden (view full) ---

472 font_bit_to_pix24(&boot_fb_font, (uint8_t *)glyph, c, fg, bg);
473 break;
474 case 32:
475 font_bit_to_pix32(&boot_fb_font, (uint32_t *)glyph, c, fg, bg);
476 break;
477 }
478}
479
453/*
454 * move the terminal window lines [1..y] to [0..y-1] and clear last line.
455 */
456static void
480static void
457boot_fb_scroll(void)
481boot_fb_eraseline_impl(uint16_t x, uint16_t y)
458{
482{
459 struct vis_conscopy c_copy;
460 uint32_t soffset, toffset;
461 uint32_t width, height;
483 uint32_t toffset, size;
462 uint32_t fg, bg;
484 uint32_t fg, bg;
463 uint8_t *src, *dst, *sdst;
485 uint8_t *dst, *sdst;
464 int i;
465
466 boot_get_color(&fg, &bg);
467 bg = boot_color_map(bg);
468
486 int i;
487
488 boot_get_color(&fg, &bg);
489 bg = boot_color_map(bg);
490
469 /* support for scrolling. set up the console copy data and last line */
470 c_copy.s_row = fb_info.terminal_origin.y + boot_fb_font.height;
471 c_copy.s_col = fb_info.terminal_origin.x;
472 c_copy.e_row = fb_info.screen.y - fb_info.terminal_origin.y;
473 c_copy.e_col = fb_info.screen.x - fb_info.terminal_origin.x;
474 c_copy.t_row = fb_info.terminal_origin.y;
475 c_copy.t_col = fb_info.terminal_origin.x;
491 size = fb_info.terminal.x * boot_fb_font.width * fb_info.bpp;
476
492
477 soffset = c_copy.s_col * fb_info.bpp + c_copy.s_row * fb_info.pitch;
478 toffset = c_copy.t_col * fb_info.bpp + c_copy.t_row * fb_info.pitch;
493 toffset = x * fb_info.bpp + y * fb_info.pitch;
494 dst = fb_info.fb + toffset;
495 if (fb_info.shadow_fb != NULL)
496 sdst = fb_info.shadow_fb + toffset;
497
498 for (i = 0; i < boot_fb_font.height; i++) {
499 uint8_t *dest = dst + i * fb_info.pitch;
500 if (fb_info.fb + fb_info.fb_size >= dest + size)
501 boot_fb_fill(dest, bg, size);
502 if (fb_info.shadow_fb != NULL) {
503 dest = sdst + i * fb_info.pitch;
504 if (fb_info.shadow_fb + fb_info.fb_size >=
505 dest + size) {
506 boot_fb_fill(dest, bg, size);
507 }
508 }
509 }
510}
511
512static void
513boot_fb_eraseline(void)
514{
515 boot_fb_eraseline_impl(fb_info.cursor.origin.x,
516 fb_info.cursor.origin.y);
517}
518
519/*
520 * Copy rectangle from console to console.
521 * If shadow buffer is available, use shadow as source.
522 */
523static void
524boot_fb_conscopy(struct vis_conscopy *c_copy)
525{
526 uint32_t soffset, toffset;
527 uint32_t width, height, increment;
528 uint8_t *src, *dst, *sdst = NULL;
529 int i;
530
531 soffset = c_copy->s_col * fb_info.bpp + c_copy->s_row * fb_info.pitch;
532 toffset = c_copy->t_col * fb_info.bpp + c_copy->t_row * fb_info.pitch;
533
534 src = fb_info.fb + soffset;
535 dst = fb_info.fb + toffset;
536
479 if (fb_info.shadow_fb != NULL) {
480 src = fb_info.shadow_fb + soffset;
481 sdst = fb_info.shadow_fb + toffset;
537 if (fb_info.shadow_fb != NULL) {
538 src = fb_info.shadow_fb + soffset;
539 sdst = fb_info.shadow_fb + toffset;
482 } else {
483 src = fb_info.fb + soffset;
484 sdst = NULL;
485 }
540 }
486 dst = fb_info.fb + toffset;
487
541
488 width = (c_copy.e_col - c_copy.s_col + 1) * fb_info.bpp;
489 height = c_copy.e_row - c_copy.s_row + 1;
542 width = (c_copy->e_col - c_copy->s_col + 1) * fb_info.bpp;
543 height = c_copy->e_row - c_copy->s_row + 1;
544
490 for (i = 0; i < height; i++) {
545 for (i = 0; i < height; i++) {
491 uint32_t increment = i * fb_info.pitch;
546 increment = i * fb_info.pitch;
547
548 /* Make sure we fit into FB size. */
549 if (soffset + increment + width >= fb_info.fb_size ||
550 toffset + increment + width >= fb_info.fb_size)
551 break;
552
492 boot_fb_cpy(dst + increment, src + increment, width);
553 boot_fb_cpy(dst + increment, src + increment, width);
554
493 if (sdst != NULL)
494 boot_fb_cpy(sdst + increment, src + increment, width);
495 }
555 if (sdst != NULL)
556 boot_fb_cpy(sdst + increment, src + increment, width);
557 }
558}
496
559
497 /* now clean up the last line */
498 toffset = last_line.x * fb_info.bpp + last_line.y * fb_info.pitch;
499 dst = fb_info.fb + toffset;
500 if (fb_info.shadow_fb != NULL)
501 sdst = fb_info.shadow_fb + toffset;
560/* Shift the line content by chars. */
561static void
562boot_fb_shiftline(int chars)
563{
564 struct vis_conscopy c_copy;
502
565
503 for (i = 0; i < boot_fb_font.height; i++) {
504 uint8_t *dest = dst + i * fb_info.pitch;
505 if (fb_info.fb + fb_info.fb_size >= dest + last_line_size)
506 boot_fb_fill(dest, bg, last_line_size);
507 if (sdst != NULL) {
508 dest = sdst + i * fb_info.pitch;
509 if (fb_info.shadow_fb + fb_info.fb_size >=
510 dest + last_line_size) {
511 boot_fb_fill(dest, bg, last_line_size);
512 }
513 }
514 }
566 c_copy.s_col = fb_info.cursor.origin.x;
567 c_copy.s_row = fb_info.cursor.origin.y;
568
569 c_copy.e_col = (fb_info.terminal.x - chars) * boot_fb_font.width;
570 c_copy.e_col += fb_info.terminal_origin.x;
571 c_copy.e_row = c_copy.s_row + boot_fb_font.height;
572
573 c_copy.t_col = fb_info.cursor.origin.x + chars * boot_fb_font.width;
574 c_copy.t_row = fb_info.cursor.origin.y;
575
576 boot_fb_conscopy(&c_copy);
515}
516
517/*
577}
578
579/*
580 * move the terminal window lines [1..y] to [0..y-1] and clear last line.
581 */
582static void
583boot_fb_scroll(void)
584{
585 struct vis_conscopy c_copy;
586
587 /* support for scrolling. set up the console copy data and last line */
588 c_copy.s_row = fb_info.terminal_origin.y + boot_fb_font.height;
589 c_copy.s_col = fb_info.terminal_origin.x;
590 c_copy.e_row = fb_info.screen.y - fb_info.terminal_origin.y;
591 c_copy.e_col = fb_info.screen.x - fb_info.terminal_origin.x;
592 c_copy.t_row = fb_info.terminal_origin.y;
593 c_copy.t_col = fb_info.terminal_origin.x;
594
595 boot_fb_conscopy(&c_copy);
596
597 /* now clean up the last line */
598 boot_fb_eraseline_impl(fb_info.terminal_origin.x,
599 fb_info.terminal_origin.y +
600 (fb_info.terminal.y - 1) * boot_fb_font.height);
601}
602
603/*
518 * Very simple block cursor. Save space below the cursor and restore
519 * when cursor is invisible.
520 */
521void
522boot_fb_cursor(boolean_t visible)
523{
524 uint32_t offset, size;
525 uint32_t *fb32, *sfb32 = NULL;

--- 95 unchanged lines hidden (view full) ---

621 sfb32[j] = (sfb32[j] ^ fg) ^ bg;
622 }
623 }
624 break;
625 }
626}
627
628static void
604 * Very simple block cursor. Save space below the cursor and restore
605 * when cursor is invisible.
606 */
607void
608boot_fb_cursor(boolean_t visible)
609{
610 uint32_t offset, size;
611 uint32_t *fb32, *sfb32 = NULL;

--- 95 unchanged lines hidden (view full) ---

707 sfb32[j] = (sfb32[j] ^ fg) ^ bg;
708 }
709 }
710 break;
711 }
712}
713
714static void
629set_cursor_row(void)
715boot_fb_setpos(int row, int col)
630{
716{
631 fb_info.cursor.pos.y++;
632 fb_info.cursor.pos.x = 0;
633 fb_info.cursor.origin.x = fb_info.terminal_origin.x;
717 if (row < 0)
718 row = 0;
719 if (row >= fb_info.terminal.y)
720 row = fb_info.terminal.y - 1;
721 if (col < 0)
722 col = 0;
723 if (col >= fb_info.terminal.x)
724 col = fb_info.terminal.x - 1;
634
725
635 if (fb_info.cursor.pos.y < fb_info.terminal.y &&
636 fb_info.cursor.origin.y + boot_fb_font.height < fb_info.screen.y) {
637 fb_info.cursor.origin.y += boot_fb_font.height;
638 } else {
639 fb_info.cursor.pos.y = fb_info.terminal.y - 1;
640 /* fix the cursor origin y */
641 fb_info.cursor.origin.y = fb_info.terminal_origin.y +
642 boot_fb_font.height * fb_info.cursor.pos.y;
643 boot_fb_scroll();
644 }
726 fb_info.cursor.pos.x = col;
727 fb_info.cursor.pos.y = row;
728 fb_info.cursor.origin.x = fb_info.terminal_origin.x;
729 fb_info.cursor.origin.x += col * boot_fb_font.width;
730 fb_info.cursor.origin.y = fb_info.terminal_origin.y;
731 fb_info.cursor.origin.y += row * boot_fb_font.height;
645}
646
647static void
732}
733
734static void
648set_cursor_col(void)
735boot_fb_putchar(int c)
649{
736{
650 fb_info.cursor.pos.x++;
651 if (fb_info.cursor.pos.x < fb_info.terminal.x &&
652 fb_info.cursor.origin.x + boot_fb_font.width < fb_info.screen.x) {
653 fb_info.cursor.origin.x += boot_fb_font.width;
654 } else {
655 fb_info.cursor.pos.x = 0;
656 fb_info.cursor.origin.x = fb_info.terminal_origin.x;
657 set_cursor_row();
658 }
659}
660
661void
662boot_fb_putchar(uint8_t c)
663{
664 struct vis_consdisplay display;
737 struct vis_consdisplay display;
665 boolean_t bs = B_FALSE;
738 int rows, cols;
666
739
667 /* early tem startup will switch cursor off, if so, keep it off */
668 boot_fb_cursor(B_FALSE); /* cursor off */
669 switch (c) {
670 case '\n':
671 set_cursor_row();
672 boot_fb_cursor(B_TRUE);
740 rows = fb_info.cursor.pos.y;
741 cols = fb_info.cursor.pos.x;
742
743 if (c == '\n') {
744 if (rows < fb_info.terminal.y - 1)
745 boot_fb_setpos(rows + 1, cols);
746 else
747 boot_fb_scroll();
673 return;
748 return;
674 case '\r':
675 fb_info.cursor.pos.x = 0;
676 fb_info.cursor.origin.x = fb_info.terminal_origin.x;
677 boot_fb_cursor(B_TRUE);
678 return;
679 case '\b':
680 if (fb_info.cursor.pos.x > 0) {
681 fb_info.cursor.pos.x--;
682 fb_info.cursor.origin.x -= boot_fb_font.width;
683 }
684 c = ' ';
685 bs = B_TRUE;
686 break;
687 }
688
689 bit_to_pix(c);
690 display.col = fb_info.cursor.origin.x;
691 display.row = fb_info.cursor.origin.y;
692 display.width = boot_fb_font.width;
693 display.height = boot_fb_font.height;
694 display.data = glyph;
695
696 boot_fb_blit(&display);
749 }
750
751 bit_to_pix(c);
752 display.col = fb_info.cursor.origin.x;
753 display.row = fb_info.cursor.origin.y;
754 display.width = boot_fb_font.width;
755 display.height = boot_fb_font.height;
756 display.data = glyph;
757
758 boot_fb_blit(&display);
697 if (bs == B_FALSE)
698 set_cursor_col();
699 boot_fb_cursor(B_TRUE);
759 if (cols < fb_info.terminal.x - 1)
760 boot_fb_setpos(rows, cols + 1);
761 else if (rows < fb_info.terminal.y - 1)
762 boot_fb_setpos(rows + 1, 0);
763 else {
764 boot_fb_setpos(rows, 0);
765 boot_fb_scroll();
766 }
700}
767}