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(); > }