33a34
> #include "boot_console_impl.h"
64,65d64
< static uint32_t last_line_size;
< static fb_info_pixel_coord_t last_line;
89a89,94
> static void boot_fb_putchar(int);
> static void boot_fb_eraseline(void);
> static void boot_fb_setpos(int, int);
> static void boot_fb_shiftline(int);
> static void boot_fb_eraseline_impl(uint16_t, uint16_t);
>
94c99
< xbi_fb_init(struct xboot_info *xbi)
---
> xbi_fb_init(struct xboot_info *xbi, bcons_dev_t *bcons_dev)
124a130,135
> bcons_dev->bd_putchar = boot_fb_putchar;
> bcons_dev->bd_eraseline = boot_fb_eraseline;
> bcons_dev->bd_cursor = boot_fb_cursor;
> bcons_dev->bd_setpos = boot_fb_setpos;
> bcons_dev->bd_shift = boot_fb_shiftline;
>
190c201
< for (i = 0; i < len; i++) {
---
> for (i = 0; i < len; i++)
192d202
< }
197c207
< for (i = 0; i < len; i++) {
---
> for (i = 0; i < len; i++)
199d208
< }
210d218
< uint32_t i;
215,216c223,234
< for (i = 0; i < len; i++)
< dst[i] = src[i];
---
> default:
> if (dst <= src) {
> do {
> *dst++ = *src++;
> } while (--len != 0);
> } else {
> dst += len;
> src += len;
> do {
> *--dst = *--src;
> } while (--len != 0);
> }
222,223c240,250
< for (i = 0; i < len >> 1; i++) {
< dst16[i] = src16[i];
---
> len /= 2;
> if (dst16 <= src16) {
> do {
> *dst16++ = *src16++;
> } while (--len != 0);
> } else {
> dst16 += len;
> src16 += len;
> do {
> *--dst16 = *--src16;
> } while (--len != 0);
229,230c256,266
< for (i = 0; i < len >> 2; i++) {
< dst32[i] = src32[i];
---
> len /= 4;
> if (dst32 <= src32) {
> do {
> *dst32++ = *src32++;
> } while (--len != 0);
> } else {
> dst32 += len;
> src32 += len;
> do {
> *--dst32 = *--src32;
> } while (--len != 0);
259c295
< static void
---
> void
366,370c402,404
< fb_info.cursor.pos.x = fb_info.cursor.pos.y = 0;
< if (console == CONS_FRAMEBUFFER &&
< fb_info.cursor.pos.x == 0 && fb_info.cursor.pos.y == 0) {
< uint32_t fg, bg;
< int i;
---
> if (fb_info.cursor.pos.x == 0 && fb_info.cursor.pos.y == 0) {
> uint32_t fg, bg, toffset;
> uint16_t y;
375,376c409,412
< for (i = 0; i < fb_info.screen.y; i++) {
< uint8_t *dest = fb_info.fb + i * fb_info.pitch;
---
> toffset = 0;
> for (y = 0; y < fb_info.screen.y; y++) {
> uint8_t *dest = fb_info.fb + toffset;
>
377a414
> toffset += fb_info.pitch;
381,386d417
< /* set up pre-calculated last line */
< last_line_size = fb_info.terminal.x * boot_fb_font.width *
< fb_info.bpp;
< last_line.x = window.x;
< last_line.y = window.y + (fb_info.terminal.y - 1) * boot_fb_font.height;
<
393,394c424,425
< uint32_t size; /* write size per scanline */
< uint8_t *fbp, *sfbp; /* fb + calculated offset */
---
> uint32_t offset, size; /* write size per scanline */
> uint8_t *fbp, *sfbp = NULL; /* fb + calculated offset */
405,412c436,439
< fbp = fb_info.fb + rect->col * fb_info.bpp +
< rect->row * fb_info.pitch;
< if (fb_info.shadow_fb != NULL) {
< sfbp = fb_info.shadow_fb + rect->col * fb_info.bpp +
< rect->row * fb_info.pitch;
< } else {
< sfbp = NULL;
< }
---
> offset = rect->col * fb_info.bpp + rect->row * fb_info.pitch;
> fbp = fb_info.fb + offset;
> if (fb_info.shadow_fb != NULL)
> sfbp = fb_info.shadow_fb + offset;
453,455d479
< /*
< * move the terminal window lines [1..y] to [0..y-1] and clear last line.
< */
457c481
< boot_fb_scroll(void)
---
> boot_fb_eraseline_impl(uint16_t x, uint16_t y)
459,461c483
< struct vis_conscopy c_copy;
< uint32_t soffset, toffset;
< uint32_t width, height;
---
> uint32_t toffset, size;
463c485
< uint8_t *src, *dst, *sdst;
---
> uint8_t *dst, *sdst;
469,475c491
< /* support for scrolling. set up the console copy data and last line */
< c_copy.s_row = fb_info.terminal_origin.y + boot_fb_font.height;
< c_copy.s_col = fb_info.terminal_origin.x;
< c_copy.e_row = fb_info.screen.y - fb_info.terminal_origin.y;
< c_copy.e_col = fb_info.screen.x - fb_info.terminal_origin.x;
< c_copy.t_row = fb_info.terminal_origin.y;
< c_copy.t_col = fb_info.terminal_origin.x;
---
> size = fb_info.terminal.x * boot_fb_font.width * fb_info.bpp;
477,478c493,536
< soffset = c_copy.s_col * fb_info.bpp + c_copy.s_row * fb_info.pitch;
< toffset = c_copy.t_col * fb_info.bpp + c_copy.t_row * fb_info.pitch;
---
> toffset = x * fb_info.bpp + y * fb_info.pitch;
> dst = fb_info.fb + toffset;
> if (fb_info.shadow_fb != NULL)
> sdst = fb_info.shadow_fb + toffset;
>
> for (i = 0; i < boot_fb_font.height; i++) {
> uint8_t *dest = dst + i * fb_info.pitch;
> if (fb_info.fb + fb_info.fb_size >= dest + size)
> boot_fb_fill(dest, bg, size);
> if (fb_info.shadow_fb != NULL) {
> dest = sdst + i * fb_info.pitch;
> if (fb_info.shadow_fb + fb_info.fb_size >=
> dest + size) {
> boot_fb_fill(dest, bg, size);
> }
> }
> }
> }
>
> static void
> boot_fb_eraseline(void)
> {
> boot_fb_eraseline_impl(fb_info.cursor.origin.x,
> fb_info.cursor.origin.y);
> }
>
> /*
> * Copy rectangle from console to console.
> * If shadow buffer is available, use shadow as source.
> */
> static void
> boot_fb_conscopy(struct vis_conscopy *c_copy)
> {
> uint32_t soffset, toffset;
> uint32_t width, height, increment;
> uint8_t *src, *dst, *sdst = NULL;
> int i;
>
> soffset = c_copy->s_col * fb_info.bpp + c_copy->s_row * fb_info.pitch;
> toffset = c_copy->t_col * fb_info.bpp + c_copy->t_row * fb_info.pitch;
>
> src = fb_info.fb + soffset;
> dst = fb_info.fb + toffset;
>
482,484d539
< } else {
< src = fb_info.fb + soffset;
< sdst = NULL;
486d540
< dst = fb_info.fb + toffset;
488,489c542,544
< width = (c_copy.e_col - c_copy.s_col + 1) * fb_info.bpp;
< height = c_copy.e_row - c_copy.s_row + 1;
---
> width = (c_copy->e_col - c_copy->s_col + 1) * fb_info.bpp;
> height = c_copy->e_row - c_copy->s_row + 1;
>
491c546,552
< uint32_t increment = i * fb_info.pitch;
---
> increment = i * fb_info.pitch;
>
> /* Make sure we fit into FB size. */
> if (soffset + increment + width >= fb_info.fb_size ||
> toffset + increment + width >= fb_info.fb_size)
> break;
>
492a554
>
495a558
> }
497,501c560,564
< /* now clean up the last line */
< toffset = last_line.x * fb_info.bpp + last_line.y * fb_info.pitch;
< dst = fb_info.fb + toffset;
< if (fb_info.shadow_fb != NULL)
< sdst = fb_info.shadow_fb + toffset;
---
> /* Shift the line content by chars. */
> static void
> boot_fb_shiftline(int chars)
> {
> struct vis_conscopy c_copy;
503,514c566,576
< for (i = 0; i < boot_fb_font.height; i++) {
< uint8_t *dest = dst + i * fb_info.pitch;
< if (fb_info.fb + fb_info.fb_size >= dest + last_line_size)
< boot_fb_fill(dest, bg, last_line_size);
< if (sdst != NULL) {
< dest = sdst + i * fb_info.pitch;
< if (fb_info.shadow_fb + fb_info.fb_size >=
< dest + last_line_size) {
< boot_fb_fill(dest, bg, last_line_size);
< }
< }
< }
---
> c_copy.s_col = fb_info.cursor.origin.x;
> c_copy.s_row = fb_info.cursor.origin.y;
>
> c_copy.e_col = (fb_info.terminal.x - chars) * boot_fb_font.width;
> c_copy.e_col += fb_info.terminal_origin.x;
> c_copy.e_row = c_copy.s_row + boot_fb_font.height;
>
> c_copy.t_col = fb_info.cursor.origin.x + chars * boot_fb_font.width;
> c_copy.t_row = fb_info.cursor.origin.y;
>
> boot_fb_conscopy(&c_copy);
517a580,603
> * move the terminal window lines [1..y] to [0..y-1] and clear last line.
> */
> static void
> boot_fb_scroll(void)
> {
> struct vis_conscopy c_copy;
>
> /* support for scrolling. set up the console copy data and last line */
> c_copy.s_row = fb_info.terminal_origin.y + boot_fb_font.height;
> c_copy.s_col = fb_info.terminal_origin.x;
> c_copy.e_row = fb_info.screen.y - fb_info.terminal_origin.y;
> c_copy.e_col = fb_info.screen.x - fb_info.terminal_origin.x;
> c_copy.t_row = fb_info.terminal_origin.y;
> c_copy.t_col = fb_info.terminal_origin.x;
>
> boot_fb_conscopy(&c_copy);
>
> /* now clean up the last line */
> boot_fb_eraseline_impl(fb_info.terminal_origin.x,
> fb_info.terminal_origin.y +
> (fb_info.terminal.y - 1) * boot_fb_font.height);
> }
>
> /*
629c715
< set_cursor_row(void)
---
> boot_fb_setpos(int row, int col)
631,633c717,724
< fb_info.cursor.pos.y++;
< fb_info.cursor.pos.x = 0;
< fb_info.cursor.origin.x = fb_info.terminal_origin.x;
---
> if (row < 0)
> row = 0;
> if (row >= fb_info.terminal.y)
> row = fb_info.terminal.y - 1;
> if (col < 0)
> col = 0;
> if (col >= fb_info.terminal.x)
> col = fb_info.terminal.x - 1;
635,644c726,731
< if (fb_info.cursor.pos.y < fb_info.terminal.y &&
< fb_info.cursor.origin.y + boot_fb_font.height < fb_info.screen.y) {
< fb_info.cursor.origin.y += boot_fb_font.height;
< } else {
< fb_info.cursor.pos.y = fb_info.terminal.y - 1;
< /* fix the cursor origin y */
< fb_info.cursor.origin.y = fb_info.terminal_origin.y +
< boot_fb_font.height * fb_info.cursor.pos.y;
< boot_fb_scroll();
< }
---
> fb_info.cursor.pos.x = col;
> fb_info.cursor.pos.y = row;
> fb_info.cursor.origin.x = fb_info.terminal_origin.x;
> fb_info.cursor.origin.x += col * boot_fb_font.width;
> fb_info.cursor.origin.y = fb_info.terminal_origin.y;
> fb_info.cursor.origin.y += row * boot_fb_font.height;
648c735
< set_cursor_col(void)
---
> boot_fb_putchar(int c)
650,663d736
< fb_info.cursor.pos.x++;
< if (fb_info.cursor.pos.x < fb_info.terminal.x &&
< fb_info.cursor.origin.x + boot_fb_font.width < fb_info.screen.x) {
< fb_info.cursor.origin.x += boot_fb_font.width;
< } else {
< fb_info.cursor.pos.x = 0;
< fb_info.cursor.origin.x = fb_info.terminal_origin.x;
< set_cursor_row();
< }
< }
<
< void
< boot_fb_putchar(uint8_t c)
< {
665c738
< boolean_t bs = B_FALSE;
---
> int rows, cols;
667,672c740,747
< /* early tem startup will switch cursor off, if so, keep it off */
< boot_fb_cursor(B_FALSE); /* cursor off */
< switch (c) {
< case '\n':
< set_cursor_row();
< boot_fb_cursor(B_TRUE);
---
> rows = fb_info.cursor.pos.y;
> cols = fb_info.cursor.pos.x;
>
> if (c == '\n') {
> if (rows < fb_info.terminal.y - 1)
> boot_fb_setpos(rows + 1, cols);
> else
> boot_fb_scroll();
674,686d748
< case '\r':
< fb_info.cursor.pos.x = 0;
< fb_info.cursor.origin.x = fb_info.terminal_origin.x;
< boot_fb_cursor(B_TRUE);
< return;
< case '\b':
< if (fb_info.cursor.pos.x > 0) {
< fb_info.cursor.pos.x--;
< fb_info.cursor.origin.x -= boot_fb_font.width;
< }
< c = ' ';
< bs = B_TRUE;
< break;
697,699c759,766
< if (bs == B_FALSE)
< set_cursor_col();
< boot_fb_cursor(B_TRUE);
---
> if (cols < fb_info.terminal.x - 1)
> boot_fb_setpos(rows, cols + 1);
> else if (rows < fb_info.terminal.y - 1)
> boot_fb_setpos(rows + 1, 0);
> else {
> boot_fb_setpos(rows, 0);
> boot_fb_scroll();
> }