Author: tsoome Date: Mon Nov 30 11:45:47 2020 New Revision: 368184 URL: https://svnweb.freebsd.org/changeset/base/368184
Log: 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. Modified: head/sys/dev/vt/vt_core.c head/sys/kern/subr_module.c head/sys/sys/font.h head/sys/sys/linker.h Modified: head/sys/dev/vt/vt_core.c ============================================================================== --- head/sys/dev/vt/vt_core.c Mon Nov 30 10:58:06 2020 (r368183) +++ head/sys/dev/vt/vt_core.c Mon Nov 30 11:45:47 2020 (r368184) @@ -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,7 +1454,131 @@ 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) { struct vt_driver *vtd, **vtdlist, *vtdbest = NULL; @@ -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 @@ skip_thunk: } 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 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 */ Modified: head/sys/kern/subr_module.c ============================================================================== --- head/sys/kern/subr_module.c Mon Nov 30 10:58:06 2020 (r368183) +++ head/sys/kern/subr_module.c Mon Nov 30 11:45:47 2020 (r368184) @@ -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)); Modified: head/sys/sys/font.h ============================================================================== --- head/sys/sys/font.h Mon Nov 30 10:58:06 2020 (r368183) +++ head/sys/sys/font.h Mon Nov 30 11:45:47 2020 (r368184) @@ -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; Modified: head/sys/sys/linker.h ============================================================================== --- head/sys/sys/linker.h Mon Nov 30 10:58:06 2020 (r368183) +++ head/sys/sys/linker.h Mon Nov 30 11:45:47 2020 (r368184) @@ -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 */ _______________________________________________ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"