ok yasuoka The diff speeded up boot time 32.5 sec => 18.0 sec (with -s, until appearing prompt of single user mode).
On Sun, 6 Sep 2015 00:49:09 +0200 (CEST) Mark Kettenis <mark.kette...@xs4all.nl> wrote: > On most modern hardware reading from a framebuffer is much slower than > writing to it. This is why when I added code to the rasops code to > remember the characters written and simply redraw them when we scroll > the console. That code only works when RI_VCONS was specified, > because that code already had the backing store for the characters to > support switching between multiple screens. > > Unfortunately the RI_VCONS code doesn't work early on in the boot > process. We need to allocate memory for the screen and the backing > store and that isn't going to work if we haven't initialized uvm yet. > > Enter the diff below. This makes it possible for the early console > initialization code to pass a buffer for storing the all characters on > the framebuffer, and set the RI_WRONLY flag. This makes efifb(4) on > my laptop quite a bit faster. And it will be even faster when we make > the framebuffer write-combining. > > There is a bit of code duplication between the rasops_vcons_* and > rasops_wronly_* functions. I probably should refactor things a bit to > remove the code duplication for at least the *_copycols() and > *_compyrows() functions. I can do that now or later. > > ok? > > > Index: arch/amd64/amd64/efifb.c > =================================================================== > RCS file: /cvs/src/sys/arch/amd64/amd64/efifb.c,v > retrieving revision 1.4 > diff -u -p -r1.4 efifb.c > --- arch/amd64/amd64/efifb.c 5 Sep 2015 08:21:27 -0000 1.4 > +++ arch/amd64/amd64/efifb.c 5 Sep 2015 22:31:56 -0000 > @@ -121,7 +121,7 @@ efifb_attach(struct device *parent, stru > > efifb_rasops_preinit(fb); > ri->ri_flg &= ~RI_CLEAR; > - ri->ri_flg |= RI_VCONS; > + ri->ri_flg |= RI_VCONS | RI_WRONLY; > > rasops_init(ri, efifb_std_descr.nrows, efifb_std_descr.ncols); > } > @@ -264,6 +264,8 @@ efifb_list_font(void *v, struct wsdispla > return (rasops_list_font(ri, font)); > } > > +struct wsdisplay_charcell efifb_bs[EFIFB_HEIGHT * EFIFB_WIDTH]; > + > int > efifb_cnattach(void) > { > @@ -289,7 +291,8 @@ efifb_cnattach(void) > > efifb_rasops_preinit(fb); > > - ri->ri_flg = RI_CLEAR | RI_CENTER; > + ri->ri_bs = efifb_bs; > + ri->ri_flg = RI_CLEAR | RI_CENTER | RI_WRONLY; > rasops_init(ri, EFIFB_HEIGHT, EFIFB_WIDTH); > efifb_std_descr.ncols = ri->ri_cols; > efifb_std_descr.nrows = ri->ri_rows; > Index: dev/rasops/rasops.c > =================================================================== > RCS file: /cvs/src/sys/dev/rasops/rasops.c,v > retrieving revision 1.41 > diff -u -p -r1.41 rasops.c > --- dev/rasops/rasops.c 1 Sep 2015 01:54:04 -0000 1.41 > +++ dev/rasops/rasops.c 5 Sep 2015 22:31:56 -0000 > @@ -174,6 +174,12 @@ int rasops_vcons_eraserows(void *, int, > int rasops_vcons_alloc_attr(void *, int, int, int, long *); > void rasops_vcons_unpack_attr(void *, long, int *, int *, int *); > > +int rasops_wronly_putchar(void *, int, int, u_int, long); > +int rasops_wronly_copycols(void *, int, int, int, int); > +int rasops_wronly_erasecols(void *, int, int, int, long); > +int rasops_wronly_copyrows(void *, int, int, int); > +int rasops_wronly_eraserows(void *, int, int, long); > + > int rasops_add_font(struct rasops_info *, struct wsdisplay_font *); > int rasops_use_font(struct rasops_info *, struct wsdisplay_font *); > int rasops_list_font_cb(void *, struct wsdisplay_font *); > @@ -271,6 +277,21 @@ rasops_init(struct rasops_info *ri, int > ri->ri_ops.eraserows = rasops_vcons_eraserows; > ri->ri_ops.alloc_attr = rasops_vcons_alloc_attr; > ri->ri_ops.unpack_attr = rasops_vcons_unpack_attr; > + } else if ((ri->ri_flg & RI_WRONLY) && ri->ri_bs != NULL) { > + long attr; > + int i; > + > + ri->ri_ops.putchar = rasops_wronly_putchar; > + ri->ri_ops.copycols = rasops_wronly_copycols; > + ri->ri_ops.erasecols = rasops_wronly_erasecols; > + ri->ri_ops.copyrows = rasops_wronly_copyrows; > + ri->ri_ops.eraserows = rasops_wronly_eraserows; > + > + ri->ri_alloc_attr(ri, 0, 0, 0, &attr); > + for (i = 0; i < ri->ri_rows * ri->ri_cols; i++) { > + ri->ri_bs[i].uc = ' '; > + ri->ri_bs[i].attr = attr; > + } > } > > task_set(&ri->ri_switchtask, rasops_doswitch, ri); > @@ -1368,7 +1389,6 @@ rasops_alloc_screen(void *v, void **cook > { > struct rasops_info *ri = v; > struct rasops_screen *scr; > - size_t size; > int i; > > scr = malloc(sizeof(*scr), M_DEVBUF, M_NOWAIT); > @@ -1382,7 +1402,6 @@ rasops_alloc_screen(void *v, void **cook > free(scr, M_DEVBUF, sizeof(*scr)); > return (ENOMEM); > } > - size = ri->ri_rows * ri->ri_cols * sizeof(struct wsdisplay_charcell); > > *cookiep = scr; > *curxp = 0; > @@ -1394,9 +1413,14 @@ rasops_alloc_screen(void *v, void **cook > scr->rs_crow = -1; > scr->rs_ccol = -1; > > - for (i = 0; i < ri->ri_rows * ri->ri_cols; i++) { > - scr->rs_bs[i].uc = ' '; > - scr->rs_bs[i].attr = *attrp; > + if (ri->ri_bs) { > + memcpy(scr->rs_bs, ri->ri_bs, ri->ri_rows * ri->ri_cols * > + sizeof(struct wsdisplay_charcell)); > + } else { > + for (i = 0; i < ri->ri_rows * ri->ri_cols; i++) { > + scr->rs_bs[i].uc = ' '; > + scr->rs_bs[i].attr = *attrp; > + } > } > > LIST_INSERT_HEAD(&ri->ri_screens, scr, rs_next); > @@ -1628,6 +1652,95 @@ rasops_vcons_unpack_attr(void *cookie, l > > rasops_unpack_attr(scr->rs_ri, attr, fg, bg, underline); > } > + > +int > +rasops_wronly_putchar(void *cookie, int row, int col, u_int uc, long attr) > +{ > + struct rasops_info *ri = cookie; > + int off = row * ri->ri_cols + col; > + > + ri->ri_bs[off].uc = uc; > + ri->ri_bs[off].attr = attr; > + > + return ri->ri_putchar(ri, row, col, uc, attr); > +} > + > +int > +rasops_wronly_copycols(void *cookie, int row, int src, int dst, int num) > +{ > + struct rasops_info *ri = cookie; > + int cols = ri->ri_cols; > + int col, rc; > + > + memmove(&ri->ri_bs[row * cols + dst], &ri->ri_bs[row * cols + src], > + num * sizeof(struct wsdisplay_charcell)); > + > + for (col = dst; col < dst + num; col++) { > + int off = row * cols + col; > + > + rc = ri->ri_putchar(ri, row, col, > + ri->ri_bs[off].uc, ri->ri_bs[off].attr); > + if (rc != 0) > + return rc; > + } > + > + return 0; > +} > + > +int > +rasops_wronly_erasecols(void *cookie, int row, int col, int num, long attr) > +{ > + struct rasops_info *ri = cookie; > + int cols = ri->ri_cols; > + int i; > + > + for (i = 0; i < num; i++) { > + ri->ri_bs[row * cols + col + i].uc = ' '; > + ri->ri_bs[row * cols + col + i].attr = attr; > + } > + > + return ri->ri_erasecols(ri, row, col, num, attr); > +} > + > +int > +rasops_wronly_copyrows(void *cookie, int src, int dst, int num) > +{ > + struct rasops_info *ri = cookie; > + int cols = ri->ri_cols; > + int row, col, rc; > + > + memmove(&ri->ri_bs[dst * cols], &ri->ri_bs[src * cols], > + num * cols * sizeof(struct wsdisplay_charcell)); > + > + for (row = dst; row < dst + num; row++) { > + for (col = 0; col < cols; col++) { > + int off = row * cols + col; > + > + rc = ri->ri_putchar(ri, row, col, > + ri->ri_bs[off].uc, ri->ri_bs[off].attr); > + if (rc != 0) > + return rc; > + } > + } > + > + return 0; > +} > + > +int > +rasops_wronly_eraserows(void *cookie, int row, int num, long attr) > +{ > + struct rasops_info *ri = cookie; > + int cols = ri->ri_cols; > + int i; > + > + for (i = 0; i < num * cols; i++) { > + ri->ri_bs[row * cols + i].uc = ' '; > + ri->ri_bs[row * cols + i].attr = attr; > + } > + > + return ri->ri_eraserows(ri, row, num, attr); > +} > + > > /* > * Font management. > Index: dev/rasops/rasops.h > =================================================================== > RCS file: /cvs/src/sys/dev/rasops/rasops.h,v > retrieving revision 1.16 > diff -u -p -r1.16 rasops.h > --- dev/rasops/rasops.h 22 Dec 2014 20:08:05 -0000 1.16 > +++ dev/rasops/rasops.h 5 Sep 2015 22:31:56 -0000 > @@ -74,6 +74,7 @@ struct rasops_info { > struct wsdisplay_font *ri_font; > int ri_wsfcookie; /* wsfont cookie */ > void *ri_hw; /* driver private data; ignored by rasops */ > + struct wsdisplay_charcell *ri_bs; /* character backing store */ > int ri_crow; /* cursor row */ > int ri_ccol; /* cursor column */ > int ri_flg; /* various operational flags */ >