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 */
> 

Reply via email to