vt: if loader did pass the font via metadata, use it
The built in 8x16 font may be way too small with large framebuffer resolutions, to improve readability, use loader provied font.
This commit is contained in:
parent
ed2b70e8af
commit
93b18e3730
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=368184
@ -39,9 +39,11 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/consio.h>
|
||||
#include <sys/eventhandler.h>
|
||||
#include <sys/fbio.h>
|
||||
#include <sys/font.h>
|
||||
#include <sys/kbio.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/linker.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
@ -163,8 +165,15 @@ extern unsigned char vt_logo_image[];
|
||||
const unsigned int vt_logo_sprite_height;
|
||||
#endif
|
||||
|
||||
/* Font. */
|
||||
/*
|
||||
* Console font. vt_font_loader will be filled with font data passed
|
||||
* by loader. If there is no font passed by boot loader, we use built in
|
||||
* default.
|
||||
*/
|
||||
extern struct vt_font vt_font_default;
|
||||
static struct vt_font vt_font_loader;
|
||||
static struct vt_font *vt_font_assigned = &vt_font_default;
|
||||
|
||||
#ifndef SC_NO_CUTPASTE
|
||||
extern struct vt_mouse_cursor vt_default_mouse_pointer;
|
||||
#endif
|
||||
@ -1445,6 +1454,130 @@ vtterm_splash(struct vt_device *vd)
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct vt_font *
|
||||
parse_font_info_static(struct font_info *fi)
|
||||
{
|
||||
struct vt_font *vfp;
|
||||
uintptr_t ptr;
|
||||
uint32_t checksum;
|
||||
|
||||
if (fi == NULL)
|
||||
return (NULL);
|
||||
|
||||
ptr = (uintptr_t)fi;
|
||||
/*
|
||||
* Compute and verify checksum. The total sum of all the fields
|
||||
* must be 0.
|
||||
*/
|
||||
checksum = fi->fi_width;
|
||||
checksum += fi->fi_height;
|
||||
checksum += fi->fi_bitmap_size;
|
||||
for (unsigned i = 0; i < VFNT_MAPS; i++)
|
||||
checksum += fi->fi_map_count[i];
|
||||
|
||||
if (checksum + fi->fi_checksum != 0)
|
||||
return (NULL);
|
||||
|
||||
ptr += sizeof(struct font_info);
|
||||
ptr = roundup2(ptr, 8);
|
||||
|
||||
vfp = &vt_font_loader;
|
||||
vfp->vf_height = fi->fi_height;
|
||||
vfp->vf_width = fi->fi_width;
|
||||
for (unsigned i = 0; i < VFNT_MAPS; i++) {
|
||||
if (fi->fi_map_count[i] == 0)
|
||||
continue;
|
||||
vfp->vf_map_count[i] = fi->fi_map_count[i];
|
||||
vfp->vf_map[i] = (vfnt_map_t *)ptr;
|
||||
ptr += (fi->fi_map_count[i] * sizeof(vfnt_map_t));
|
||||
ptr = roundup2(ptr, 8);
|
||||
}
|
||||
vfp->vf_bytes = (uint8_t *)ptr;
|
||||
return (vfp);
|
||||
}
|
||||
|
||||
static struct vt_font *
|
||||
parse_font_info(struct font_info *fi)
|
||||
{
|
||||
struct vt_font *vfp;
|
||||
uintptr_t ptr;
|
||||
uint32_t checksum;
|
||||
size_t size;
|
||||
|
||||
if (fi == NULL)
|
||||
return (NULL);
|
||||
|
||||
ptr = (uintptr_t)fi;
|
||||
/*
|
||||
* Compute and verify checksum. The total sum of all the fields
|
||||
* must be 0.
|
||||
*/
|
||||
checksum = fi->fi_width;
|
||||
checksum += fi->fi_height;
|
||||
checksum += fi->fi_bitmap_size;
|
||||
for (unsigned i = 0; i < VFNT_MAPS; i++)
|
||||
checksum += fi->fi_map_count[i];
|
||||
|
||||
if (checksum + fi->fi_checksum != 0)
|
||||
return (NULL);
|
||||
|
||||
ptr += sizeof(struct font_info);
|
||||
ptr = roundup2(ptr, 8);
|
||||
|
||||
vfp = &vt_font_loader;
|
||||
vfp->vf_height = fi->fi_height;
|
||||
vfp->vf_width = fi->fi_width;
|
||||
for (unsigned i = 0; i < VFNT_MAPS; i++) {
|
||||
if (fi->fi_map_count[i] == 0)
|
||||
continue;
|
||||
vfp->vf_map_count[i] = fi->fi_map_count[i];
|
||||
size = fi->fi_map_count[i] * sizeof(vfnt_map_t);
|
||||
vfp->vf_map[i] = malloc(size, M_VT, M_WAITOK | M_ZERO);
|
||||
bcopy((vfnt_map_t *)ptr, vfp->vf_map[i], size);
|
||||
ptr += size;
|
||||
ptr = roundup2(ptr, 8);
|
||||
}
|
||||
vfp->vf_bytes = malloc(fi->fi_bitmap_size, M_VT, M_WAITOK | M_ZERO);
|
||||
bcopy((uint8_t *)ptr, vfp->vf_bytes, fi->fi_bitmap_size);
|
||||
return (vfp);
|
||||
}
|
||||
|
||||
static void
|
||||
vt_init_font(void *arg)
|
||||
{
|
||||
caddr_t kmdp;
|
||||
struct font_info *fi;
|
||||
struct vt_font *font;
|
||||
|
||||
kmdp = preload_search_by_type("elf kernel");
|
||||
if (kmdp == NULL)
|
||||
kmdp = preload_search_by_type("elf64 kernel");
|
||||
fi = MD_FETCH(kmdp, MODINFOMD_FONT, struct font_info *);
|
||||
|
||||
font = parse_font_info(fi);
|
||||
if (font != NULL)
|
||||
vt_font_assigned = font;
|
||||
}
|
||||
|
||||
SYSINIT(vt_init_font, SI_SUB_KMEM, SI_ORDER_ANY, vt_init_font, &vt_consdev);
|
||||
|
||||
static void
|
||||
vt_init_font_static(void)
|
||||
{
|
||||
caddr_t kmdp;
|
||||
struct font_info *fi;
|
||||
struct vt_font *font;
|
||||
|
||||
kmdp = preload_search_by_type("elf kernel");
|
||||
if (kmdp == NULL)
|
||||
kmdp = preload_search_by_type("elf64 kernel");
|
||||
fi = MD_FETCH(kmdp, MODINFOMD_FONT, struct font_info *);
|
||||
|
||||
font = parse_font_info_static(fi);
|
||||
if (font != NULL)
|
||||
vt_font_assigned = font;
|
||||
}
|
||||
|
||||
static void
|
||||
vtterm_cnprobe(struct terminal *tm, struct consdev *cp)
|
||||
{
|
||||
@ -1491,9 +1624,11 @@ vtterm_cnprobe(struct terminal *tm, struct consdev *cp)
|
||||
vd->vd_windows[VT_CONSWINDOW] = vw;
|
||||
sprintf(cp->cn_name, "ttyv%r", VT_UNIT(vw));
|
||||
|
||||
vt_init_font_static();
|
||||
|
||||
/* Attach default font if not in TEXTMODE. */
|
||||
if ((vd->vd_flags & VDF_TEXTMODE) == 0) {
|
||||
vw->vw_font = vtfont_ref(&vt_font_default);
|
||||
vw->vw_font = vtfont_ref(vt_font_assigned);
|
||||
vt_compute_drawable_area(vw);
|
||||
}
|
||||
|
||||
@ -2431,7 +2566,7 @@ vtterm_ioctl(struct terminal *tm, u_long cmd, caddr_t data,
|
||||
}
|
||||
case PIO_VFONT_DEFAULT: {
|
||||
/* Reset to default font. */
|
||||
error = vt_change_font(vw, &vt_font_default);
|
||||
error = vt_change_font(vw, vt_font_assigned);
|
||||
return (error);
|
||||
}
|
||||
case GIO_SCRNMAP: {
|
||||
@ -2691,7 +2826,7 @@ vt_allocate_window(struct vt_device *vd, unsigned int window)
|
||||
vw->vw_kbdmode = K_XLATE;
|
||||
|
||||
if ((vd->vd_flags & VDF_TEXTMODE) == 0) {
|
||||
vw->vw_font = vtfont_ref(&vt_font_default);
|
||||
vw->vw_font = vtfont_ref(vt_font_assigned);
|
||||
vt_compute_drawable_area(vw);
|
||||
}
|
||||
|
||||
@ -2788,7 +2923,7 @@ vt_resize(struct vt_device *vd)
|
||||
VT_LOCK(vd);
|
||||
/* Assign default font to window, if not textmode. */
|
||||
if (!(vd->vd_flags & VDF_TEXTMODE) && vw->vw_font == NULL)
|
||||
vw->vw_font = vtfont_ref(&vt_font_default);
|
||||
vw->vw_font = vtfont_ref(vt_font_assigned);
|
||||
VT_UNLOCK(vd);
|
||||
|
||||
/* Resize terminal windows */
|
||||
|
@ -295,6 +295,7 @@ preload_bootstrap_relocate(vm_offset_t offset)
|
||||
/* Deal with the ones that we know we have to fix */
|
||||
switch (hdr[0]) {
|
||||
case MODINFO_ADDR:
|
||||
case MODINFO_METADATA|MODINFOMD_FONT:
|
||||
case MODINFO_METADATA|MODINFOMD_SSYM:
|
||||
case MODINFO_METADATA|MODINFOMD_ESYM:
|
||||
ptr = (vm_offset_t *)(curp + (sizeof(uint32_t) * 2));
|
||||
|
@ -57,6 +57,14 @@ enum vfnt_map_type {
|
||||
VFNT_MAPS /* Number of maps. */
|
||||
};
|
||||
|
||||
struct font_info {
|
||||
int32_t fi_checksum;
|
||||
uint32_t fi_width;
|
||||
uint32_t fi_height;
|
||||
uint32_t fi_bitmap_size;
|
||||
uint32_t fi_map_count[VFNT_MAPS];
|
||||
};
|
||||
|
||||
struct vfnt_map {
|
||||
uint32_t vfm_src;
|
||||
uint16_t vfm_dst;
|
||||
|
@ -226,6 +226,7 @@ void *linker_hwpmc_list_objects(void);
|
||||
#define MODINFOMD_CTORS_SIZE 0x000b /* size of .ctors */
|
||||
#define MODINFOMD_FW_HANDLE 0x000c /* Firmware dependent handle */
|
||||
#define MODINFOMD_KEYBUF 0x000d /* Crypto key intake buffer */
|
||||
#define MODINFOMD_FONT 0x000e /* Console font */
|
||||
#define MODINFOMD_NOCOPY 0x8000 /* don't copy this metadata to the kernel */
|
||||
|
||||
#define MODINFOMD_DEPLIST (0x4001 | MODINFOMD_NOCOPY) /* depends on */
|
||||
|
Loading…
Reference in New Issue
Block a user