mirror of
https://github.com/ipxe/ipxe
synced 2025-12-21 04:20:17 +03:00
[fbcon] Remove userptr_t from framebuffer console drivers
Simplify the framebuffer console drivers by assuming that the raw framebuffer, character cell array, background picture, and glyph data are all directly accessible via pointer dereferences. In particular, this avoids the need to copy each glyph during drawing: the VESA framebuffer driver can simply return a pointer to the glyph data stored in the video ROM. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -103,7 +103,7 @@ struct vesafb {
|
|||||||
/** Font definition */
|
/** Font definition */
|
||||||
struct fbcon_font font;
|
struct fbcon_font font;
|
||||||
/** Character glyphs */
|
/** Character glyphs */
|
||||||
struct segoff glyphs;
|
const uint8_t *glyphs;
|
||||||
/** Saved VGA mode */
|
/** Saved VGA mode */
|
||||||
uint8_t saved_mode;
|
uint8_t saved_mode;
|
||||||
};
|
};
|
||||||
@@ -140,11 +140,10 @@ static int vesafb_rc ( unsigned int status ) {
|
|||||||
* Get character glyph
|
* Get character glyph
|
||||||
*
|
*
|
||||||
* @v character Unicode character
|
* @v character Unicode character
|
||||||
* @v glyph Character glyph to fill in
|
* @ret glyph Character glyph
|
||||||
*/
|
*/
|
||||||
static void vesafb_glyph ( unsigned int character, uint8_t *glyph ) {
|
static const uint8_t * vesafb_glyph ( unsigned int character ) {
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
size_t offset;
|
|
||||||
|
|
||||||
/* Identify glyph */
|
/* Identify glyph */
|
||||||
if ( character < VESAFB_ASCII ) {
|
if ( character < VESAFB_ASCII ) {
|
||||||
@@ -155,10 +154,8 @@ static void vesafb_glyph ( unsigned int character, uint8_t *glyph ) {
|
|||||||
index = VESAFB_UNKNOWN;
|
index = VESAFB_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy glyph from BIOS font table */
|
/* Return glyph in BIOS font table */
|
||||||
offset = ( index * VESAFB_CHAR_HEIGHT );
|
return &vesafb.glyphs[ index * VESAFB_CHAR_HEIGHT ];
|
||||||
copy_from_real ( glyph, vesafb.glyphs.segment,
|
|
||||||
( vesafb.glyphs.offset + offset ), VESAFB_CHAR_HEIGHT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -166,6 +163,7 @@ static void vesafb_glyph ( unsigned int character, uint8_t *glyph ) {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void vesafb_font ( void ) {
|
static void vesafb_font ( void ) {
|
||||||
|
struct segoff glyphs;
|
||||||
|
|
||||||
/* Get font information
|
/* Get font information
|
||||||
*
|
*
|
||||||
@@ -186,12 +184,13 @@ static void vesafb_font ( void ) {
|
|||||||
"movw %%es, %%cx\n\t"
|
"movw %%es, %%cx\n\t"
|
||||||
"movw %%bp, %%dx\n\t"
|
"movw %%bp, %%dx\n\t"
|
||||||
"popw %%bp\n\t" /* gcc bug */ )
|
"popw %%bp\n\t" /* gcc bug */ )
|
||||||
: "=c" ( vesafb.glyphs.segment ),
|
: "=c" ( glyphs.segment ),
|
||||||
"=d" ( vesafb.glyphs.offset )
|
"=d" ( glyphs.offset )
|
||||||
: "a" ( VBE_GET_FONT ),
|
: "a" ( VBE_GET_FONT ),
|
||||||
"b" ( VESAFB_FONT ) );
|
"b" ( VESAFB_FONT ) );
|
||||||
DBGC ( &vbe_buf, "VESAFB has font %04x at %04x:%04x\n",
|
DBGC ( &vbe_buf, "VESAFB has font %04x at %04x:%04x\n",
|
||||||
VESAFB_FONT, vesafb.glyphs.segment, vesafb.glyphs.offset );
|
VESAFB_FONT, glyphs.segment, glyphs.offset );
|
||||||
|
vesafb.glyphs = real_to_virt ( glyphs.segment, glyphs.offset );
|
||||||
vesafb.font.height = VESAFB_CHAR_HEIGHT;
|
vesafb.font.height = VESAFB_CHAR_HEIGHT;
|
||||||
vesafb.font.glyph = vesafb_glyph;
|
vesafb.font.glyph = vesafb_glyph;
|
||||||
}
|
}
|
||||||
@@ -206,8 +205,8 @@ static void vesafb_font ( void ) {
|
|||||||
*/
|
*/
|
||||||
static int vesafb_mode_list ( uint16_t **mode_numbers ) {
|
static int vesafb_mode_list ( uint16_t **mode_numbers ) {
|
||||||
struct vbe_controller_info *controller = &vbe_buf.controller;
|
struct vbe_controller_info *controller = &vbe_buf.controller;
|
||||||
userptr_t video_mode_ptr;
|
const uint16_t *video_mode_ptr;
|
||||||
uint16_t mode_number;
|
const uint16_t *mode_number;
|
||||||
uint16_t status;
|
uint16_t status;
|
||||||
size_t len;
|
size_t len;
|
||||||
int rc;
|
int rc;
|
||||||
@@ -245,18 +244,16 @@ static int vesafb_mode_list ( uint16_t **mode_numbers ) {
|
|||||||
/* Calculate length of mode list */
|
/* Calculate length of mode list */
|
||||||
video_mode_ptr = real_to_virt ( controller->video_mode_ptr.segment,
|
video_mode_ptr = real_to_virt ( controller->video_mode_ptr.segment,
|
||||||
controller->video_mode_ptr.offset );
|
controller->video_mode_ptr.offset );
|
||||||
len = 0;
|
mode_number = video_mode_ptr;
|
||||||
do {
|
while ( *(mode_number++) != VBE_MODE_END ) {}
|
||||||
copy_from_user ( &mode_number, video_mode_ptr, len,
|
len = ( ( ( const void * ) mode_number ) -
|
||||||
sizeof ( mode_number ) );
|
( ( const void * ) video_mode_ptr ) );
|
||||||
len += sizeof ( mode_number );
|
|
||||||
} while ( mode_number != VBE_MODE_END );
|
|
||||||
|
|
||||||
/* Allocate and fill mode list */
|
/* Allocate and fill mode list */
|
||||||
*mode_numbers = malloc ( len );
|
*mode_numbers = malloc ( len );
|
||||||
if ( ! *mode_numbers )
|
if ( ! *mode_numbers )
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
copy_from_user ( *mode_numbers, video_mode_ptr, 0, len );
|
memcpy ( *mode_numbers, video_mode_ptr, len );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
133
src/core/fbcon.c
133
src/core/fbcon.c
@@ -102,6 +102,23 @@ static void fbcon_set_default_background ( struct fbcon *fbcon ) {
|
|||||||
fbcon->background = FBCON_TRANSPARENT;
|
fbcon->background = FBCON_TRANSPARENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get character cell
|
||||||
|
*
|
||||||
|
* @v fbcon Frame buffer console
|
||||||
|
* @v xpos X position
|
||||||
|
* @v ypos Y position
|
||||||
|
* @ret cell Text cell
|
||||||
|
*/
|
||||||
|
static inline struct fbcon_text_cell * fbcon_cell ( struct fbcon *fbcon,
|
||||||
|
unsigned int xpos,
|
||||||
|
unsigned int ypos ) {
|
||||||
|
unsigned int index;
|
||||||
|
|
||||||
|
index = ( ( ypos * fbcon->character.width ) + xpos );
|
||||||
|
return &fbcon->text.cells[index];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear rows of characters
|
* Clear rows of characters
|
||||||
*
|
*
|
||||||
@@ -109,43 +126,21 @@ static void fbcon_set_default_background ( struct fbcon *fbcon ) {
|
|||||||
* @v ypos Starting Y position
|
* @v ypos Starting Y position
|
||||||
*/
|
*/
|
||||||
static void fbcon_clear ( struct fbcon *fbcon, unsigned int ypos ) {
|
static void fbcon_clear ( struct fbcon *fbcon, unsigned int ypos ) {
|
||||||
struct fbcon_text_cell cell = {
|
struct fbcon_text_cell *cell;
|
||||||
.foreground = fbcon->foreground,
|
|
||||||
.background = fbcon->background,
|
|
||||||
.character = ' ',
|
|
||||||
};
|
|
||||||
size_t offset;
|
|
||||||
unsigned int xpos;
|
unsigned int xpos;
|
||||||
|
|
||||||
/* Clear stored character array */
|
/* Clear stored character array */
|
||||||
|
cell = fbcon_cell ( fbcon, 0, ypos );
|
||||||
for ( ; ypos < fbcon->character.height ; ypos++ ) {
|
for ( ; ypos < fbcon->character.height ; ypos++ ) {
|
||||||
offset = ( ypos * fbcon->character.width * sizeof ( cell ) );
|
|
||||||
for ( xpos = 0 ; xpos < fbcon->character.width ; xpos++ ) {
|
for ( xpos = 0 ; xpos < fbcon->character.width ; xpos++ ) {
|
||||||
copy_to_user ( fbcon->text.start, offset, &cell,
|
cell->foreground = fbcon->foreground;
|
||||||
sizeof ( cell ) );
|
cell->background = fbcon->background;
|
||||||
offset += sizeof ( cell );
|
cell->character = ' ';
|
||||||
|
cell++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Store character at specified position
|
|
||||||
*
|
|
||||||
* @v fbcon Frame buffer console
|
|
||||||
* @v cell Text cell
|
|
||||||
* @v xpos X position
|
|
||||||
* @v ypos Y position
|
|
||||||
*/
|
|
||||||
static void fbcon_store ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
|
|
||||||
unsigned int xpos, unsigned int ypos ) {
|
|
||||||
size_t offset;
|
|
||||||
|
|
||||||
/* Store cell */
|
|
||||||
offset = ( ( ( ypos * fbcon->character.width ) + xpos ) *
|
|
||||||
sizeof ( *cell ) );
|
|
||||||
copy_to_user ( fbcon->text.start, offset, cell, sizeof ( *cell ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw character at specified position
|
* Draw character at specified position
|
||||||
*
|
*
|
||||||
@@ -156,7 +151,7 @@ static void fbcon_store ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
|
|||||||
*/
|
*/
|
||||||
static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
|
static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
|
||||||
unsigned int xpos, unsigned int ypos ) {
|
unsigned int xpos, unsigned int ypos ) {
|
||||||
uint8_t glyph[fbcon->font->height];
|
const uint8_t *glyph;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
size_t pixel_len;
|
size_t pixel_len;
|
||||||
size_t skip_len;
|
size_t skip_len;
|
||||||
@@ -164,10 +159,10 @@ static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
|
|||||||
unsigned int column;
|
unsigned int column;
|
||||||
uint8_t bitmask;
|
uint8_t bitmask;
|
||||||
int transparent;
|
int transparent;
|
||||||
void *src;
|
const void *src;
|
||||||
|
|
||||||
/* Get font character */
|
/* Get font character */
|
||||||
fbcon->font->glyph ( cell->character, glyph );
|
glyph = fbcon->font->glyph ( cell->character );
|
||||||
|
|
||||||
/* Calculate pixel geometry */
|
/* Calculate pixel geometry */
|
||||||
offset = ( fbcon->indent +
|
offset = ( fbcon->indent +
|
||||||
@@ -204,7 +199,7 @@ static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
|
|||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
copy_to_user ( fbcon->start, offset, src, pixel_len );
|
memcpy ( ( fbcon->start + offset ), src, pixel_len );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move to next row */
|
/* Move to next row */
|
||||||
@@ -218,18 +213,16 @@ static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
|
|||||||
* @v fbcon Frame buffer console
|
* @v fbcon Frame buffer console
|
||||||
*/
|
*/
|
||||||
static void fbcon_redraw ( struct fbcon *fbcon ) {
|
static void fbcon_redraw ( struct fbcon *fbcon ) {
|
||||||
struct fbcon_text_cell cell;
|
struct fbcon_text_cell *cell;
|
||||||
size_t offset = 0;
|
|
||||||
unsigned int xpos;
|
unsigned int xpos;
|
||||||
unsigned int ypos;
|
unsigned int ypos;
|
||||||
|
|
||||||
/* Redraw characters */
|
/* Redraw characters */
|
||||||
|
cell = fbcon_cell ( fbcon, 0, 0 );
|
||||||
for ( ypos = 0 ; ypos < fbcon->character.height ; ypos++ ) {
|
for ( ypos = 0 ; ypos < fbcon->character.height ; ypos++ ) {
|
||||||
for ( xpos = 0 ; xpos < fbcon->character.width ; xpos++ ) {
|
for ( xpos = 0 ; xpos < fbcon->character.width ; xpos++ ) {
|
||||||
copy_from_user ( &cell, fbcon->text.start, offset,
|
fbcon_draw ( fbcon, cell, xpos, ypos );
|
||||||
sizeof ( cell ) );
|
cell++;
|
||||||
fbcon_draw ( fbcon, &cell, xpos, ypos );
|
|
||||||
offset += sizeof ( cell );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -246,8 +239,8 @@ static void fbcon_scroll ( struct fbcon *fbcon ) {
|
|||||||
assert ( fbcon->ypos == fbcon->character.height );
|
assert ( fbcon->ypos == fbcon->character.height );
|
||||||
|
|
||||||
/* Scroll up character array */
|
/* Scroll up character array */
|
||||||
row_len = ( fbcon->character.width * sizeof ( struct fbcon_text_cell ));
|
row_len = ( fbcon->character.width * sizeof ( fbcon->text.cells[0] ) );
|
||||||
memmove ( fbcon->text.start, ( fbcon->text.start + row_len ),
|
memmove ( fbcon_cell ( fbcon, 0, 0 ), fbcon_cell ( fbcon, 0, 1 ),
|
||||||
( row_len * ( fbcon->character.height - 1 ) ) );
|
( row_len * ( fbcon->character.height - 1 ) ) );
|
||||||
fbcon_clear ( fbcon, ( fbcon->character.height - 1 ) );
|
fbcon_clear ( fbcon, ( fbcon->character.height - 1 ) );
|
||||||
|
|
||||||
@@ -265,18 +258,19 @@ static void fbcon_scroll ( struct fbcon *fbcon ) {
|
|||||||
* @v show_cursor Show cursor
|
* @v show_cursor Show cursor
|
||||||
*/
|
*/
|
||||||
static void fbcon_draw_cursor ( struct fbcon *fbcon, int show_cursor ) {
|
static void fbcon_draw_cursor ( struct fbcon *fbcon, int show_cursor ) {
|
||||||
struct fbcon_text_cell cell;
|
struct fbcon_text_cell *cell;
|
||||||
size_t offset;
|
struct fbcon_text_cell cursor;
|
||||||
|
|
||||||
offset = ( ( ( fbcon->ypos * fbcon->character.width ) + fbcon->xpos ) *
|
cell = fbcon_cell ( fbcon, fbcon->xpos, fbcon->ypos );
|
||||||
sizeof ( cell ) );
|
|
||||||
copy_from_user ( &cell, fbcon->text.start, offset, sizeof ( cell ) );
|
|
||||||
if ( show_cursor ) {
|
if ( show_cursor ) {
|
||||||
cell.background = fbcon->foreground;
|
cursor.background = fbcon->foreground;
|
||||||
cell.foreground = ( ( fbcon->background == FBCON_TRANSPARENT ) ?
|
cursor.foreground =
|
||||||
|
( ( fbcon->background == FBCON_TRANSPARENT ) ?
|
||||||
0 : fbcon->background );
|
0 : fbcon->background );
|
||||||
|
cursor.character = cell->character;
|
||||||
|
cell = &cursor;
|
||||||
}
|
}
|
||||||
fbcon_draw ( fbcon, &cell, fbcon->xpos, fbcon->ypos );
|
fbcon_draw ( fbcon, cell, fbcon->xpos, fbcon->ypos );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -439,7 +433,7 @@ static struct ansiesc_handler fbcon_ansiesc_handlers[] = {
|
|||||||
* @v character Character
|
* @v character Character
|
||||||
*/
|
*/
|
||||||
void fbcon_putchar ( struct fbcon *fbcon, int character ) {
|
void fbcon_putchar ( struct fbcon *fbcon, int character ) {
|
||||||
struct fbcon_text_cell cell;
|
struct fbcon_text_cell *cell;
|
||||||
|
|
||||||
/* Intercept ANSI escape sequences */
|
/* Intercept ANSI escape sequences */
|
||||||
character = ansiesc_process ( &fbcon->ctx, character );
|
character = ansiesc_process ( &fbcon->ctx, character );
|
||||||
@@ -473,11 +467,11 @@ void fbcon_putchar ( struct fbcon *fbcon, int character ) {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Print character at current cursor position */
|
/* Print character at current cursor position */
|
||||||
cell.foreground = ( fbcon->foreground | fbcon->bold );
|
cell = fbcon_cell ( fbcon, fbcon->xpos, fbcon->ypos );
|
||||||
cell.background = fbcon->background;
|
cell->foreground = ( fbcon->foreground | fbcon->bold );
|
||||||
cell.character = character;
|
cell->background = fbcon->background;
|
||||||
fbcon_store ( fbcon, &cell, fbcon->xpos, fbcon->ypos );
|
cell->character = character;
|
||||||
fbcon_draw ( fbcon, &cell, fbcon->xpos, fbcon->ypos );
|
fbcon_draw ( fbcon, cell, fbcon->xpos, fbcon->ypos );
|
||||||
|
|
||||||
/* Advance cursor */
|
/* Advance cursor */
|
||||||
fbcon->xpos++;
|
fbcon->xpos++;
|
||||||
@@ -508,12 +502,9 @@ static int fbcon_picture_init ( struct fbcon *fbcon,
|
|||||||
struct fbcon_geometry *pixel = fbcon->pixel;
|
struct fbcon_geometry *pixel = fbcon->pixel;
|
||||||
struct fbcon_picture *picture = &fbcon->picture;
|
struct fbcon_picture *picture = &fbcon->picture;
|
||||||
size_t len;
|
size_t len;
|
||||||
size_t pixbuf_stride;
|
|
||||||
size_t indent;
|
size_t indent;
|
||||||
size_t pixbuf_indent;
|
|
||||||
size_t offset;
|
size_t offset;
|
||||||
size_t pixbuf_offset;
|
const uint32_t *rgb;
|
||||||
uint32_t rgb;
|
|
||||||
uint32_t raw;
|
uint32_t raw;
|
||||||
unsigned int x;
|
unsigned int x;
|
||||||
unsigned int y;
|
unsigned int y;
|
||||||
@@ -534,13 +525,10 @@ static int fbcon_picture_init ( struct fbcon *fbcon,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Centre picture on console */
|
/* Centre picture on console */
|
||||||
pixbuf_stride = ( pixbuf->width * sizeof ( rgb ) );
|
|
||||||
xgap = ( ( ( int ) ( pixel->width - pixbuf->width ) ) / 2 );
|
xgap = ( ( ( int ) ( pixel->width - pixbuf->width ) ) / 2 );
|
||||||
ygap = ( ( ( int ) ( pixel->height - pixbuf->height ) ) / 2 );
|
ygap = ( ( ( int ) ( pixel->height - pixbuf->height ) ) / 2 );
|
||||||
indent = ( ( ( ( ygap >= 0 ) ? ygap : 0 ) * pixel->stride ) +
|
indent = ( ( ( ( ygap >= 0 ) ? ygap : 0 ) * pixel->stride ) +
|
||||||
( ( ( xgap >= 0 ) ? xgap : 0 ) * pixel->len ) );
|
( ( ( xgap >= 0 ) ? xgap : 0 ) * pixel->len ) );
|
||||||
pixbuf_indent = ( ( ( ( ygap < 0 ) ? -ygap : 0 ) * pixbuf_stride ) +
|
|
||||||
( ( ( xgap < 0 ) ? -xgap : 0 ) * sizeof ( rgb ) ) );
|
|
||||||
width = pixbuf->width;
|
width = pixbuf->width;
|
||||||
if ( width > pixel->width )
|
if ( width > pixel->width )
|
||||||
width = pixel->width;
|
width = pixel->width;
|
||||||
@@ -555,15 +543,14 @@ static int fbcon_picture_init ( struct fbcon *fbcon,
|
|||||||
memset ( picture->start, 0, len );
|
memset ( picture->start, 0, len );
|
||||||
for ( y = 0 ; y < height ; y++ ) {
|
for ( y = 0 ; y < height ; y++ ) {
|
||||||
offset = ( indent + ( y * pixel->stride ) );
|
offset = ( indent + ( y * pixel->stride ) );
|
||||||
pixbuf_offset = ( pixbuf_indent + ( y * pixbuf_stride ) );
|
rgb = pixbuf_pixel ( pixbuf, ( ( xgap < 0 ) ? -xgap : 0 ),
|
||||||
|
( ( ( ygap < 0 ) ? -ygap : 0 ) + y ) );
|
||||||
for ( x = 0 ; x < width ; x++ ) {
|
for ( x = 0 ; x < width ; x++ ) {
|
||||||
copy_from_user ( &rgb, pixbuf->data, pixbuf_offset,
|
raw = fbcon_colour ( fbcon, *rgb );
|
||||||
sizeof ( rgb ) );
|
memcpy ( ( picture->start + offset ), &raw,
|
||||||
raw = fbcon_colour ( fbcon, rgb );
|
|
||||||
copy_to_user ( picture->start, offset, &raw,
|
|
||||||
pixel->len );
|
pixel->len );
|
||||||
offset += pixel->len;
|
offset += pixel->len;
|
||||||
pixbuf_offset += sizeof ( rgb );
|
rgb++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -585,7 +572,7 @@ static int fbcon_picture_init ( struct fbcon *fbcon,
|
|||||||
* @v config Console configuration
|
* @v config Console configuration
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
int fbcon_init ( struct fbcon *fbcon, userptr_t start,
|
int fbcon_init ( struct fbcon *fbcon, void *start,
|
||||||
struct fbcon_geometry *pixel,
|
struct fbcon_geometry *pixel,
|
||||||
struct fbcon_colour_map *map,
|
struct fbcon_colour_map *map,
|
||||||
struct fbcon_font *font,
|
struct fbcon_font *font,
|
||||||
@@ -674,10 +661,10 @@ int fbcon_init ( struct fbcon *fbcon, userptr_t start,
|
|||||||
fbcon_set_default_background ( fbcon );
|
fbcon_set_default_background ( fbcon );
|
||||||
|
|
||||||
/* Allocate and initialise stored character array */
|
/* Allocate and initialise stored character array */
|
||||||
fbcon->text.start = umalloc ( fbcon->character.width *
|
fbcon->text.cells = umalloc ( fbcon->character.width *
|
||||||
fbcon->character.height *
|
fbcon->character.height *
|
||||||
sizeof ( struct fbcon_text_cell ) );
|
sizeof ( fbcon->text.cells[0] ) );
|
||||||
if ( ! fbcon->text.start ) {
|
if ( ! fbcon->text.cells ) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto err_text;
|
goto err_text;
|
||||||
}
|
}
|
||||||
@@ -702,7 +689,7 @@ int fbcon_init ( struct fbcon *fbcon, userptr_t start,
|
|||||||
|
|
||||||
ufree ( fbcon->picture.start );
|
ufree ( fbcon->picture.start );
|
||||||
err_picture:
|
err_picture:
|
||||||
ufree ( fbcon->text.start );
|
ufree ( fbcon->text.cells );
|
||||||
err_text:
|
err_text:
|
||||||
err_margin:
|
err_margin:
|
||||||
return rc;
|
return rc;
|
||||||
@@ -715,6 +702,6 @@ int fbcon_init ( struct fbcon *fbcon, userptr_t start,
|
|||||||
*/
|
*/
|
||||||
void fbcon_fini ( struct fbcon *fbcon ) {
|
void fbcon_fini ( struct fbcon *fbcon ) {
|
||||||
|
|
||||||
ufree ( fbcon->text.start );
|
ufree ( fbcon->text.cells );
|
||||||
ufree ( fbcon->picture.start );
|
ufree ( fbcon->picture.start );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <ipxe/ansiesc.h>
|
#include <ipxe/ansiesc.h>
|
||||||
#include <ipxe/utf8.h>
|
#include <ipxe/utf8.h>
|
||||||
#include <ipxe/uaccess.h>
|
|
||||||
#include <ipxe/console.h>
|
#include <ipxe/console.h>
|
||||||
|
|
||||||
/** Character width, in pixels */
|
/** Character width, in pixels */
|
||||||
@@ -38,9 +37,9 @@ struct fbcon_font {
|
|||||||
* Get character glyph
|
* Get character glyph
|
||||||
*
|
*
|
||||||
* @v character Unicode character
|
* @v character Unicode character
|
||||||
* @v glyph Character glyph to fill in
|
* @ret glyph Character glyph
|
||||||
*/
|
*/
|
||||||
void ( * glyph ) ( unsigned int character, uint8_t *glyph );
|
const uint8_t * ( * glyph ) ( unsigned int character );
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A frame buffer geometry
|
/** A frame buffer geometry
|
||||||
@@ -100,19 +99,19 @@ struct fbcon_text_cell {
|
|||||||
/** A frame buffer text array */
|
/** A frame buffer text array */
|
||||||
struct fbcon_text {
|
struct fbcon_text {
|
||||||
/** Stored text cells */
|
/** Stored text cells */
|
||||||
userptr_t start;
|
struct fbcon_text_cell *cells;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A frame buffer background picture */
|
/** A frame buffer background picture */
|
||||||
struct fbcon_picture {
|
struct fbcon_picture {
|
||||||
/** Start address */
|
/** Start address */
|
||||||
userptr_t start;
|
void *start;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A frame buffer console */
|
/** A frame buffer console */
|
||||||
struct fbcon {
|
struct fbcon {
|
||||||
/** Start address */
|
/** Start address */
|
||||||
userptr_t start;
|
void *start;
|
||||||
/** Length of one complete displayed screen */
|
/** Length of one complete displayed screen */
|
||||||
size_t len;
|
size_t len;
|
||||||
/** Pixel geometry */
|
/** Pixel geometry */
|
||||||
@@ -149,7 +148,7 @@ struct fbcon {
|
|||||||
int show_cursor;
|
int show_cursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int fbcon_init ( struct fbcon *fbcon, userptr_t start,
|
extern int fbcon_init ( struct fbcon *fbcon, void *start,
|
||||||
struct fbcon_geometry *pixel,
|
struct fbcon_geometry *pixel,
|
||||||
struct fbcon_colour_map *map,
|
struct fbcon_colour_map *map,
|
||||||
struct fbcon_font *font,
|
struct fbcon_font *font,
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <ipxe/refcnt.h>
|
#include <ipxe/refcnt.h>
|
||||||
#include <ipxe/uaccess.h>
|
|
||||||
|
|
||||||
/** A pixel buffer */
|
/** A pixel buffer */
|
||||||
struct pixel_buffer {
|
struct pixel_buffer {
|
||||||
@@ -22,7 +21,7 @@ struct pixel_buffer {
|
|||||||
/** Height */
|
/** Height */
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
/** 32-bit (8:8:8:8) xRGB pixel data, in host-endian order */
|
/** 32-bit (8:8:8:8) xRGB pixel data, in host-endian order */
|
||||||
userptr_t data;
|
uint32_t *data;
|
||||||
/** Total length */
|
/** Total length */
|
||||||
size_t len;
|
size_t len;
|
||||||
};
|
};
|
||||||
@@ -49,6 +48,22 @@ pixbuf_put ( struct pixel_buffer *pixbuf ) {
|
|||||||
ref_put ( &pixbuf->refcnt );
|
ref_put ( &pixbuf->refcnt );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get pixel
|
||||||
|
*
|
||||||
|
* @v pixbuf Pixel buffer
|
||||||
|
* @v x X position
|
||||||
|
* @v y Y position
|
||||||
|
* @ret pixel Pixel
|
||||||
|
*/
|
||||||
|
static inline __attribute__ (( always_inline )) uint32_t *
|
||||||
|
pixbuf_pixel ( struct pixel_buffer *pixbuf, unsigned int x, unsigned int y ) {
|
||||||
|
unsigned int index;
|
||||||
|
|
||||||
|
index = ( ( y * pixbuf->width ) + x );
|
||||||
|
return &pixbuf->data[index];
|
||||||
|
}
|
||||||
|
|
||||||
extern struct pixel_buffer * alloc_pixbuf ( unsigned int width,
|
extern struct pixel_buffer * alloc_pixbuf ( unsigned int width,
|
||||||
unsigned int height );
|
unsigned int height );
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
#include <ipxe/ansicol.h>
|
#include <ipxe/ansicol.h>
|
||||||
#include <ipxe/fbcon.h>
|
#include <ipxe/fbcon.h>
|
||||||
#include <ipxe/console.h>
|
#include <ipxe/console.h>
|
||||||
|
#include <ipxe/uaccess.h>
|
||||||
#include <ipxe/umalloc.h>
|
#include <ipxe/umalloc.h>
|
||||||
#include <ipxe/rotate.h>
|
#include <ipxe/rotate.h>
|
||||||
#include <config/console.h>
|
#include <config/console.h>
|
||||||
@@ -91,7 +92,7 @@ struct efifb {
|
|||||||
/** Font definition */
|
/** Font definition */
|
||||||
struct fbcon_font font;
|
struct fbcon_font font;
|
||||||
/** Character glyph cache */
|
/** Character glyph cache */
|
||||||
userptr_t glyphs;
|
uint8_t *glyphs;
|
||||||
/** Dynamic characters in cache */
|
/** Dynamic characters in cache */
|
||||||
unsigned int dynamic[EFIFB_DYNAMIC];
|
unsigned int dynamic[EFIFB_DYNAMIC];
|
||||||
/** Next dynamic character cache entry to evict */
|
/** Next dynamic character cache entry to evict */
|
||||||
@@ -117,14 +118,14 @@ static int efifb_draw ( unsigned int character, unsigned int index,
|
|||||||
unsigned int height;
|
unsigned int height;
|
||||||
unsigned int x;
|
unsigned int x;
|
||||||
unsigned int y;
|
unsigned int y;
|
||||||
|
uint8_t *glyph;
|
||||||
uint8_t bitmask;
|
uint8_t bitmask;
|
||||||
size_t offset;
|
|
||||||
EFI_STATUS efirc;
|
EFI_STATUS efirc;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Clear existing glyph */
|
/* Clear existing glyph */
|
||||||
offset = ( index * efifb.font.height );
|
glyph = &efifb.glyphs[ index * efifb.font.height ];
|
||||||
memset ( ( efifb.glyphs + offset ), 0, efifb.font.height );
|
memset ( glyph, 0, efifb.font.height );
|
||||||
|
|
||||||
/* Get glyph */
|
/* Get glyph */
|
||||||
blt = NULL;
|
blt = NULL;
|
||||||
@@ -157,8 +158,7 @@ static int efifb_draw ( unsigned int character, unsigned int index,
|
|||||||
pixel++;
|
pixel++;
|
||||||
}
|
}
|
||||||
bitmask ^= toggle;
|
bitmask ^= toggle;
|
||||||
copy_to_user ( efifb.glyphs, offset++, &bitmask,
|
*(glyph++) = bitmask;
|
||||||
sizeof ( bitmask ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free glyph */
|
/* Free glyph */
|
||||||
@@ -223,11 +223,10 @@ static unsigned int efifb_dynamic ( unsigned int character ) {
|
|||||||
* Get character glyph
|
* Get character glyph
|
||||||
*
|
*
|
||||||
* @v character Unicode character
|
* @v character Unicode character
|
||||||
* @v glyph Character glyph to fill in
|
* @ret glyph Character glyph to fill in
|
||||||
*/
|
*/
|
||||||
static void efifb_glyph ( unsigned int character, uint8_t *glyph ) {
|
static const uint8_t * efifb_glyph ( unsigned int character ) {
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
size_t offset;
|
|
||||||
|
|
||||||
/* Identify glyph */
|
/* Identify glyph */
|
||||||
if ( character < EFIFB_ASCII ) {
|
if ( character < EFIFB_ASCII ) {
|
||||||
@@ -241,9 +240,8 @@ static void efifb_glyph ( unsigned int character, uint8_t *glyph ) {
|
|||||||
index = efifb_dynamic ( character );
|
index = efifb_dynamic ( character );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy cached glyph */
|
/* Return cached glyph */
|
||||||
offset = ( index * efifb.font.height );
|
return &efifb.glyphs[ index * efifb.font.height ];
|
||||||
copy_from_user ( glyph, efifb.glyphs, offset, efifb.font.height );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user