From d2eb87c0674a281d1d3854b9c4fba0b7df215077 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Tue, 1 Jul 2025 00:31:45 +0200 Subject: console-client vga: Avoid using optimized string operations on vga_videomem The VGA boards may not like AVX-whatnot-optimized 512B accesses. E.g. qemu does not support it and raises an invalid opcode trap. --- console-client/Makefile | 1 + console-client/fb.c | 18 ++++++++-------- console-client/vga-support.c | 51 +++++++++++++++++++++++++++++++++++++++----- console-client/vga-support.h | 9 ++++++++ console-client/vga.c | 8 +++---- 5 files changed, 69 insertions(+), 18 deletions(-) diff --git a/console-client/Makefile b/console-client/Makefile index 711258c7..4972da4b 100644 --- a/console-client/Makefile +++ b/console-client/Makefile @@ -61,6 +61,7 @@ modules = vga pc_kbd generic_speaker pc_mouse current_vcs vga-CPPFLAGS = -DDEFAULT_VGA_FONT_DIR=\"${datadir}/hurd/\" fb-CPPFLAGS = -DDEFAULT_VGA_FONT_DIR=\"${datadir}/hurd/\" +vga-support-CFLAGS = -minline-all-stringops vga.so.$(hurd-version): $(patsubst %.c,%_pic.o,$(VGA_SO_SRCS)) pc_kbd.so.$(hurd-version): $(patsubst %.c,%_pic.o,$(PC_KBD_SO_SRCS)) \ kdioctlServer_pic.o diff --git a/console-client/fb.c b/console-client/fb.c index c93a6ae0..9c8d2680 100644 --- a/console-client/fb.c +++ b/console-client/fb.c @@ -228,7 +228,7 @@ fb_init(void) return err; /* Clear screen */ - memset (vga_videomem, 0, fb_width * fb_height * fb_bpp/8); + vga_memset (vga_videomem, 0, fb_width * fb_height * fb_bpp/8); return 0; } @@ -454,26 +454,26 @@ fb_display_scroll (void *handle, int delta) if (delta > 0) { - memmove (vga_videomem, vga_videomem + fb_bpp/8 * pixels, - fb_bpp/8 * disp->width * (disp->height - delta*fb_hc)); + vga_memmove (vga_videomem, vga_videomem + fb_bpp/8 * pixels, + fb_bpp/8 * disp->width * (disp->height - delta*fb_hc)); } else { - memmove (vga_videomem + fb_bpp/8 * pixels, vga_videomem, - fb_bpp/8 * disp->width * (disp->height + delta*fb_hc)); + vga_memmove (vga_videomem + fb_bpp/8 * pixels, vga_videomem, + fb_bpp/8 * disp->width * (disp->height + delta*fb_hc)); } if (delta > 0) { r = disp->height/fb_hc - delta; - memmove (&disp->refmatrix[0][0], &disp->refmatrix[0][0] + chars, - sizeof (struct fbchr) * disp->width/fb_wc * r); + vga_memmove (&disp->refmatrix[0][0], &disp->refmatrix[0][0] + chars, + sizeof (struct fbchr) * disp->width/fb_wc * r); } else { r = 0; - memmove (&disp->refmatrix[0][0] + chars, &disp->refmatrix[0][0], - sizeof (struct fbchr) * disp->width/fb_wc * (disp->height/fb_hc + delta)); + vga_memmove (&disp->refmatrix[0][0] + chars, &disp->refmatrix[0][0], + sizeof (struct fbchr) * disp->width/fb_wc * (disp->height/fb_hc + delta)); } return 0; diff --git a/console-client/vga-support.c b/console-client/vga-support.c index 32ede46d..c145cac4 100644 --- a/console-client/vga-support.c +++ b/console-client/vga-support.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "vga-hw.h" #include "vga-support.h" @@ -147,13 +148,13 @@ vga_init (void) outb (VGA_GFX_MODE_ADDR, VGA_GFX_ADDR_REG); outb (VGA_GFX_MODE_HOSTOE, VGA_GFX_DATA_REG); - memcpy (vga_state->videomem, vga_videomem, 2 * 80 * 25); + vga_memcpy (vga_state->videomem, vga_videomem, 2 * 80 * 25); vga_read_font_buffer (0, 0, vga_state->fontmem, 2 * VGA_FONT_SIZE * VGA_FONT_HEIGHT); /* 80 cols, 25 rows, two bytes per cell and twice because with lower max scan line we get more lines on the screen. */ - memset (vga_videomem, 0, 80 * 25 * 2 * 2); + vga_memset (vga_videomem, 0, 80 * 25 * 2 * 2); return 0; } @@ -167,7 +168,7 @@ vga_fini (void) /* Recover the saved state. */ vga_write_font_buffer (0, 0, vga_state->fontmem, 2 * VGA_FONT_SIZE * VGA_FONT_HEIGHT); - memcpy (vga_videomem, vga_state->videomem, 2 * 80 * 25); + vga_memcpy (vga_videomem, vga_state->videomem, 2 * 80 * 25); /* Restore the registers. */ outb (VGA_SEQ_CLOCK_MODE_ADDR, VGA_SEQ_ADDR_REG); @@ -210,6 +211,46 @@ vga_fini (void) munmap (vga_videomem, VGA_VIDEO_MEM_LENGTH); } + +/* VGA boards may not like AVX-whatnot-optimized 512B accesses, so use + non-optimized versions of string operations for vga_videomem. */ + +/* Non-optimized memset for vga_videomem */ +void vga_memset (void *__restrict _s, int c, size_t n) +{ + uint8_t * __restrict s = _s; + size_t i; + + for (i = 0; i < n; i++) + s[i] = c; +} + +/* Non-optimized memcpy for vga_videomem */ +void vga_memcpy (void *__restrict _dest, const void *__restrict _src, size_t n) +{ + uint8_t * __restrict dest = _dest; + const uint8_t * __restrict src = _src; + size_t i; + + for (i = 0; i < n; i++) + dest[i] = src[i]; +} + +/* Non-optimized memmove for vga_videomem */ +void vga_memmove (void *_dest, const void *_src, size_t n) +{ + uint8_t * dest = _dest; + const uint8_t * src = _src; + size_t i; + + if (dest <= src) + for (i = 0; i < n; i++) + dest[i] = src[i]; + else + for (i = 0; i < n; i++) + dest[n-1-i] = src[n-1-i]; +} + /* Access the font buffer BUFFER, starting from glyph INDEX, and either read DATALEN bytes into DATA (if WRITE is 0) or write @@ -249,9 +290,9 @@ vga_read_write_font_buffer (int write, int buffer, int index, outb (VGA_GFX_MISC_B8TOBF, VGA_GFX_DATA_REG); if (write) - memcpy (vga_videomem + offset, data, datalen); + vga_memcpy (vga_videomem + offset, data, datalen); else - memcpy (data, vga_videomem + offset, datalen); + vga_memcpy (data, vga_videomem + offset, datalen); /* Restore sequencer and graphic register values. */ outb (VGA_SEQ_MAP_ADDR, VGA_SEQ_ADDR_REG); diff --git a/console-client/vga-support.h b/console-client/vga-support.h index 17c0b5fd..c109bc6c 100644 --- a/console-client/vga-support.h +++ b/console-client/vga-support.h @@ -41,6 +41,15 @@ error_t vga_init (void); hardware access. */ void vga_fini (void); +/* Non-optimized memset for vga_videomem */ +void vga_memset (void *__restrict s, int c, size_t n); + +/* Non-optimized memcpy for vga_videomem */ +void vga_memcpy (void *__restrict dest, const void *__restrict src, size_t n); + +/* Non-optimized memmove for vga_videomem */ +void vga_memmove (void *dest, const void *src, size_t n); + /* Write DATALEN bytes from DATA to the font buffer BUFFER, starting from glyph index. */ void vga_write_font_buffer (int buffer, int index, diff --git a/console-client/vga.c b/console-client/vga.c index ec4f39dd..00860304 100644 --- a/console-client/vga.c +++ b/console-client/vga.c @@ -485,14 +485,14 @@ vga_display_scroll (void *handle, int delta) if (delta > 0) { - memmove (vga_videomem, vga_videomem + 2 * count, - 2 * disp->width * (disp->height - delta)); + vga_memmove (vga_videomem, vga_videomem + 2 * count, + 2 * disp->width * (disp->height - delta)); refpos = &disp->refmatrix[0][0]; } else { - memmove (vga_videomem + 2 * count, vga_videomem, - 2 * disp->width * (disp->height + delta)); + vga_memmove (vga_videomem + 2 * count, vga_videomem, + 2 * disp->width * (disp->height + delta)); refpos = &disp->refmatrix[disp->height + delta][0]; } -- cgit v1.2.3