> Date: Mon, 16 Apr 2018 10:45:52 -0500
> From: joshua stein <j...@openbsd.org>

Does this do the right thing for early consoles?  The initial
efifb_bs[] doesn't have space for the scrollback.  At the point where
the scrollback code gets code, we've replaced that with a malloc'ed
buffer?

> Index: arch/amd64/amd64/efifb.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/amd64/efifb.c,v
> retrieving revision 1.12
> diff -u -p -u -p -r1.12 efifb.c
> --- arch/amd64/amd64/efifb.c  28 Oct 2017 01:48:03 -0000      1.12
> +++ arch/amd64/amd64/efifb.c  16 Apr 2018 15:40:22 -0000
> @@ -101,6 +101,7 @@ int        efifb_show_screen(void *, void *, i
>           void *);
>  int   efifb_list_font(void *, struct wsdisplay_font *);
>  int   efifb_load_font(void *, void *, struct wsdisplay_font *);
> +void  efifb_scrollback(void *, void *, int lines);
>  void  efifb_efiinfo_init(struct efifb *);
>  void  efifb_cnattach_common(void);
>  
> @@ -133,7 +134,8 @@ struct wsdisplay_accessops efifb_accesso
>       .free_screen = efifb_free_screen,
>       .show_screen = efifb_show_screen,
>       .load_font = efifb_load_font,
> -     .list_font = efifb_list_font
> +     .list_font = efifb_list_font,
> +     .scrollback = efifb_scrollback,
>  };
>  
>  struct cfdriver efifb_cd = {
> @@ -397,6 +399,15 @@ efifb_list_font(void *v, struct wsdispla
>       struct rasops_info      *ri = &sc->sc_fb->rinfo;
>  
>       return (rasops_list_font(ri, font));
> +}
> +
> +void
> +efifb_scrollback(void *v, void *cookie, int lines)
> +{
> +     struct efifb_softc      *sc = v;
> +     struct rasops_info      *ri = &sc->sc_fb->rinfo;
> +
> +     rasops_scrollback(ri, cookie, lines);
>  }
>  
>  int
> Index: dev/rasops/rasops.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/rasops/rasops.c,v
> retrieving revision 1.50
> diff -u -p -u -p -r1.50 rasops.c
> --- dev/rasops/rasops.c       23 Jan 2018 10:10:32 -0000      1.50
> +++ dev/rasops/rasops.c       16 Apr 2018 15:40:22 -0000
> @@ -1373,8 +1373,13 @@ struct rasops_screen {
>       int rs_visible;
>       int rs_crow;
>       int rs_ccol;
> +
> +     int rs_dispoffset;      /* rs_bs index, start of our actual screen */
> +     int rs_visibleoffset;   /* rs_bs index, current scrollback screen */
>  };
>  
> +#define RS_SCROLLBACK_SCREENS 5
> +
>  int
>  rasops_alloc_screen(void *v, void **cookiep,
>      int *curxp, int *curyp, long *attrp)
> @@ -1387,13 +1392,15 @@ rasops_alloc_screen(void *v, void **cook
>       if (scr == NULL)
>               return (ENOMEM);
>  
> -     scr->rs_bs = mallocarray(ri->ri_rows,
> +     scr->rs_bs = mallocarray(ri->ri_rows * RS_SCROLLBACK_SCREENS,
>           ri->ri_cols * sizeof(struct wsdisplay_charcell), M_DEVBUF,
>           M_NOWAIT);
>       if (scr->rs_bs == NULL) {
>               free(scr, M_DEVBUF, sizeof(*scr));
>               return (ENOMEM);
>       }
> +     scr->rs_visibleoffset = scr->rs_dispoffset = ri->ri_rows *
> +         (RS_SCROLLBACK_SCREENS - 1) * ri->ri_cols;
>  
>       *cookiep = scr;
>       *curxp = 0;
> @@ -1405,13 +1412,19 @@ rasops_alloc_screen(void *v, void **cook
>       scr->rs_crow = -1;
>       scr->rs_ccol = -1;
>  
> +     for (i = 0; i < scr->rs_dispoffset; i++) {
> +             scr->rs_bs[i].uc = ' ';
> +             scr->rs_bs[i].attr = *attrp;
> +     }
> +
>       if (ri->ri_bs && scr->rs_visible) {
> -             memcpy(scr->rs_bs, ri->ri_bs, ri->ri_rows * ri->ri_cols *
> +             memcpy(scr->rs_bs + scr->rs_dispoffset, 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;
> +                     scr->rs_bs[scr->rs_dispoffset + i].uc = ' ';
> +                     scr->rs_bs[scr->rs_dispoffset + i].attr = *attrp;
>               }
>       }
>  
> @@ -1431,7 +1444,8 @@ rasops_free_screen(void *v, void *cookie
>       ri->ri_nscreens--;
>  
>       free(scr->rs_bs, M_DEVBUF,
> -         ri->ri_rows * ri->ri_cols * sizeof(struct wsdisplay_charcell));
> +         ri->ri_rows * RS_SCROLLBACK_SCREENS * ri->ri_cols *
> +         sizeof(struct wsdisplay_charcell));
>       free(scr, M_DEVBUF, sizeof(*scr));
>  }
>  
> @@ -1467,9 +1481,11 @@ rasops_doswitch(void *v)
>       ri->ri_eraserows(ri, 0, ri->ri_rows, attr);
>       ri->ri_active = scr;
>       ri->ri_active->rs_visible = 1;
> +     ri->ri_active->rs_visibleoffset = ri->ri_active->rs_dispoffset;
>       for (row = 0; row < ri->ri_rows; row++) {
>               for (col = 0; col < ri->ri_cols; col++) {
> -                     int off = row * scr->rs_ri->ri_cols + col;
> +                     int off = row * scr->rs_ri->ri_cols + col +
> +                         scr->rs_visibleoffset;
>  
>                       ri->ri_putchar(ri, row, col, scr->rs_bs[off].uc,
>                           scr->rs_bs[off].attr);
> @@ -1491,7 +1507,7 @@ rasops_getchar(void *v, int row, int col
>       if (scr == NULL || scr->rs_bs == NULL)
>               return (1);
>  
> -     *cell = scr->rs_bs[row * ri->ri_cols + col];
> +     *cell = scr->rs_bs[row * ri->ri_cols + col + scr->rs_dispoffset];
>       return (0);
>  }
>  
> @@ -1521,7 +1537,10 @@ int
>  rasops_vcons_putchar(void *cookie, int row, int col, u_int uc, long attr)
>  {
>       struct rasops_screen *scr = cookie;
> -     int off = row * scr->rs_ri->ri_cols + col;
> +     int off = row * scr->rs_ri->ri_cols + col + scr->rs_dispoffset;
> +
> +     if (scr->rs_visible && scr->rs_visibleoffset != scr->rs_dispoffset)
> +             rasops_scrollback(scr->rs_ri, scr, 0);
>  
>       scr->rs_bs[off].uc = uc;
>       scr->rs_bs[off].attr = attr;
> @@ -1540,7 +1559,8 @@ rasops_vcons_copycols(void *cookie, int 
>       int cols = scr->rs_ri->ri_cols;
>       int col, rc;
>  
> -     memmove(&scr->rs_bs[row * cols + dst], &scr->rs_bs[row * cols + src],
> +     memmove(&scr->rs_bs[row * cols + dst + scr->rs_dispoffset],
> +         &scr->rs_bs[row * cols + src + scr->rs_dispoffset],
>           num * sizeof(struct wsdisplay_charcell));
>  
>       if (!scr->rs_visible)
> @@ -1550,7 +1570,7 @@ rasops_vcons_copycols(void *cookie, int 
>               return ri->ri_copycols(ri, row, src, dst, num);
>  
>       for (col = dst; col < dst + num; col++) {
> -             int off = row * cols + col;
> +             int off = row * cols + col + scr->rs_dispoffset;
>  
>               rc = ri->ri_putchar(ri, row, col,
>                   scr->rs_bs[off].uc, scr->rs_bs[off].attr);
> @@ -1569,7 +1589,7 @@ rasops_vcons_erasecols(void *cookie, int
>       int i;
>  
>       for (i = 0; i < num; i++) {
> -             int off = row * cols + col + i;
> +             int off = row * cols + col + i + scr->rs_dispoffset;
>  
>               scr->rs_bs[off].uc = ' ';
>               scr->rs_bs[off].attr = attr;
> @@ -1589,8 +1609,15 @@ rasops_vcons_copyrows(void *cookie, int 
>       int cols = ri->ri_cols;
>       int row, col, rc;
>  
> -     memmove(&scr->rs_bs[dst * cols], &scr->rs_bs[src * cols],
> -         num * cols * sizeof(struct wsdisplay_charcell));
> +     if (dst == 0 && (src + num == ri->ri_rows))
> +             memmove(&scr->rs_bs[dst],
> +                 &scr->rs_bs[src * cols],
> +                 ((ri->ri_rows * RS_SCROLLBACK_SCREENS * cols) -
> +                 (src * cols)) * sizeof(struct wsdisplay_charcell));
> +     else
> +             memmove(&scr->rs_bs[dst * cols + scr->rs_dispoffset],
> +                 &scr->rs_bs[src * cols + scr->rs_dispoffset],
> +                 num * cols * sizeof(struct wsdisplay_charcell));
>  
>       if (!scr->rs_visible)
>               return 0;
> @@ -1600,7 +1627,7 @@ rasops_vcons_copyrows(void *cookie, int 
>  
>       for (row = dst; row < dst + num; row++) {
>               for (col = 0; col < cols; col++) {
> -                     int off = row * cols + col;
> +                     int off = row * cols + col + scr->rs_dispoffset;
>  
>                       rc = ri->ri_putchar(ri, row, col,
>                           scr->rs_bs[off].uc, scr->rs_bs[off].attr);
> @@ -1620,7 +1647,7 @@ rasops_vcons_eraserows(void *cookie, int
>       int i;
>  
>       for (i = 0; i < num * cols; i++) {
> -             int off = row * cols + i;
> +             int off = row * cols + i + scr->rs_dispoffset;
>  
>               scr->rs_bs[off].uc = ' ';
>               scr->rs_bs[off].attr = attr;
> @@ -1871,4 +1898,46 @@ rasops_list_font(void *v, struct wsdispl
>       font->index = idx;
>       font->cookie = font->data = NULL;       /* don't leak kernel pointers */
>       return 0;
> +}
> +
> +void
> +rasops_scrollback(void *v, void *cookie, int lines)
> +{
> +     struct rasops_info *ri = v;
> +     struct rasops_screen *scr = cookie;
> +     int row, col, oldvoff;
> +     long attr;
> +
> +     oldvoff = scr->rs_visibleoffset;
> +
> +     if (lines == 0)
> +             scr->rs_visibleoffset = scr->rs_dispoffset;
> +     else {
> +             int off = scr->rs_visibleoffset + (lines * ri->ri_cols);
> +
> +             if (off < 0)
> +                     off = 0;
> +             else if (off > scr->rs_dispoffset)
> +                     off = scr->rs_dispoffset;
> +
> +             scr->rs_visibleoffset = off;
> +     }
> +
> +     if (scr->rs_visibleoffset == oldvoff)
> +             return;
> +
> +     rasops_cursor(ri, 0, 0, 0);
> +     ri->ri_eraserows(ri, 0, ri->ri_rows, attr);
> +     for (row = 0; row < ri->ri_rows; row++) {
> +             for (col = 0; col < ri->ri_cols; col++) {
> +                     int off = row * scr->rs_ri->ri_cols + col +
> +                         scr->rs_visibleoffset;
> +
> +                     ri->ri_putchar(ri, row, col, scr->rs_bs[off].uc,
> +                         scr->rs_bs[off].attr);
> +             }
> +     }
> +
> +     if (scr->rs_crow != -1 && scr->rs_visibleoffset == scr->rs_dispoffset)
> +             rasops_cursor(ri, 1, scr->rs_crow, scr->rs_ccol);
>  }
> Index: dev/rasops/rasops.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/rasops/rasops.h,v
> retrieving revision 1.19
> diff -u -p -u -p -r1.19 rasops.h
> --- dev/rasops/rasops.h       17 Aug 2017 20:21:53 -0000      1.19
> +++ dev/rasops/rasops.h       16 Apr 2018 15:40:22 -0000
> @@ -178,6 +178,7 @@ int       rasops_show_screen(void *, void *, i
>  int  rasops_load_font(void *, void *, struct wsdisplay_font *);
>  int  rasops_list_font(void *, struct wsdisplay_font *);
>  int  rasops_getchar(void *, int, int, struct wsdisplay_charcell *);
> +void rasops_scrollback(void *, void *, int);
>  
>  extern const u_char  rasops_isgray[16];
>  extern const u_char  rasops_cmap[256*3];
> Index: dev/pci/drm/i915/i915_drv.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/i915/i915_drv.c,v
> retrieving revision 1.109
> diff -u -p -u -p -r1.109 i915_drv.c
> --- dev/pci/drm/i915/i915_drv.c       22 Jan 2018 02:28:09 -0000      1.109
> +++ dev/pci/drm/i915/i915_drv.c       16 Apr 2018 15:40:23 -0000
> @@ -1925,6 +1925,7 @@ int     inteldrm_list_font(void *, struct ws
>  int  inteldrm_getchar(void *, int, int, struct wsdisplay_charcell *);
>  void inteldrm_burner(void *, u_int, u_int);
>  void inteldrm_burner_cb(void *);
> +void inteldrm_scrollback(void *, void *, int lines);
>  
>  struct wsscreen_descr inteldrm_stdscreen = {
>       "std",
> @@ -1953,6 +1954,7 @@ struct wsdisplay_accessops inteldrm_acce
>       .getchar = inteldrm_getchar,
>       .load_font = inteldrm_load_font,
>       .list_font = inteldrm_list_font,
> +     .scrollback = inteldrm_scrollback,
>       .burn_screen = inteldrm_burner
>  };
>  
> @@ -2173,6 +2175,15 @@ const struct backlight_ops inteldrm_back
>       .update_status = inteldrm_backlight_update_status,
>       .get_brightness = inteldrm_backlight_get_brightness
>  };
> +
> +void
> +inteldrm_scrollback(void *v, void *cookie, int lines)
> +{
> +     struct inteldrm_softc *dev_priv = v;
> +     struct rasops_info *ri = &dev_priv->ro;
> +
> +     rasops_scrollback(ri, cookie, lines);
> +}
>  
>  int  inteldrm_match(struct device *, void *, void *);
>  void inteldrm_attach(struct device *, struct device *, void *);
> 
> 

Reply via email to