Re: Speed up UEFI framebuffer console

2018-09-19 Thread Mark Kettenis
> Date: Sat, 25 Aug 2018 17:38:12 +0200 (CEST)
> From: Mark Kettenis 
> 
> Here is a diff to speed up the initial framebuffer console on amd64.
> It remaps the framebuffer write-combining early on, which speeds up
> writing to the framebuffer considerably.
> 
> Remapping is done using _bus_space_map().  Otherwise inteldrm(4) and
> radeondrm(4) will fail to attach (or even panic) because the graphics
> aperture can't be mapped.  This mapping stays around even if efifb(4)
> doesn't attach.  There is no good place to unmap it without risking
> some random kernel printf causing a fault.
> 
> The rasops(4) bit is a bugfix that probably should go in regardless.
> It makes sure we don't clear the character mapping if the RI_CLEAR
> flag isn't set.
> 
> Can somebody with a UEFI machine that has radeondrm(4) test this for
> me?

I've had some test reports, and it has been in snaps for quite a while.

ok?


> Index: arch/amd64/amd64/efifb.c
> ===
> RCS file: /cvs/src/sys/arch/amd64/amd64/efifb.c,v
> retrieving revision 1.17
> diff -u -p -r1.17 efifb.c
> --- arch/amd64/amd64/efifb.c  12 Jul 2018 12:47:57 -  1.17
> +++ arch/amd64/amd64/efifb.c  25 Aug 2018 15:27:43 -
> @@ -215,11 +215,6 @@ efifb_attach(struct device *parent, stru
>   ccol = ri->ri_ccol;
>   crow = ri->ri_crow;
>  
> - if (bus_space_map(iot, fb->paddr, fb->psize,
> - BUS_SPACE_MAP_PREFETCHABLE | BUS_SPACE_MAP_LINEAR,
> - ) == 0)
> - ri->ri_origbits = bus_space_vaddr(iot, ioh);
> -
>   efifb_rasops_preinit(fb);
>   ri->ri_flg &= ~RI_CLEAR;
>   ri->ri_flg |= RI_VCONS | RI_WRONLY;
> @@ -428,6 +423,7 @@ efifb_efiinfo_init(struct efifb *fb)
>   fb->psize = bios_efiinfo->fb_height *
>   bios_efiinfo->fb_pixpsl * (fb->depth / 8);
>  }
> +
>  void
>  efifb_cnattach_common(void)
>  {
> @@ -450,6 +446,28 @@ efifb_cnattach_common(void)
>  
>   ri->ri_ops.alloc_attr(ri, 0, 0, 0, );
>   wsdisplay_cnattach(_std_descr, ri, 0, 0, defattr);
> +}
> +
> +void
> +efifb_cnremap(void)
> +{
> + struct efifb*fb = _console;
> + struct rasops_info  *ri = >rinfo;
> + bus_space_tag_t  iot = X86_BUS_SPACE_MEM;
> + bus_space_handle_t   ioh;
> +
> + if (fb->paddr == 0)
> + return;
> +
> + if (_bus_space_map(iot, fb->paddr, fb->psize,
> + BUS_SPACE_MAP_PREFETCHABLE | BUS_SPACE_MAP_LINEAR, ) == 0)
> + ri->ri_origbits = bus_space_vaddr(iot, ioh);
> +
> + efifb_rasops_preinit(fb);
> + ri->ri_flg &= ~RI_CLEAR;
> + ri->ri_flg |= RI_CENTER | RI_WRONLY;
> +
> + rasops_init(ri, efifb_std_descr.nrows, efifb_std_descr.ncols);
>  }
>  
>  int
> Index: arch/amd64/amd64/mainbus.c
> ===
> RCS file: /cvs/src/sys/arch/amd64/amd64/mainbus.c,v
> retrieving revision 1.44
> diff -u -p -r1.44 mainbus.c
> --- arch/amd64/amd64/mainbus.c13 Jul 2018 08:30:34 -  1.44
> +++ arch/amd64/amd64/mainbus.c25 Aug 2018 15:27:43 -
> @@ -171,6 +171,10 @@ mainbus_attach(struct device *parent, st
>   pvbus_identify();
>  #endif
>  
> +#if NEFIFB > 0
> + efifb_cnremap();
> +#endif
> +
>  #if NBIOS > 0
>   {
>   mba.mba_bios.ba_name = "bios";
> Index: arch/amd64/include/efifbvar.h
> ===
> RCS file: /cvs/src/sys/arch/amd64/include/efifbvar.h,v
> retrieving revision 1.7
> diff -u -p -r1.7 efifbvar.h
> --- arch/amd64/include/efifbvar.h 25 Apr 2018 00:46:28 -  1.7
> +++ arch/amd64/include/efifbvar.h 25 Aug 2018 15:27:43 -
> @@ -26,6 +26,7 @@ struct efifb_attach_args {
>  struct pci_attach_args;
>  
>  int efifb_cnattach(void);
> +void efifb_cnremap(void);
>  int efifb_is_console(struct pci_attach_args *);
>  void efifb_cndetach(void);
>  void efifb_cnreattach(void);
> Index: dev/rasops/rasops.c
> ===
> RCS file: /cvs/src/sys/dev/rasops/rasops.c,v
> retrieving revision 1.54
> diff -u -p -r1.54 rasops.c
> --- dev/rasops/rasops.c   3 May 2018 10:05:47 -   1.54
> +++ dev/rasops/rasops.c   25 Aug 2018 15:27:43 -
> @@ -288,10 +288,12 @@ rasops_init(struct rasops_info *ri, int 
>   ri->ri_ops.copyrows = rasops_wronly_copyrows;
>   ri->ri_ops.eraserows = rasops_wronly_eraserows;
>  
> - ri->ri_alloc_attr(ri, 0, 0, 0, );
> - for (i = 0; i < ri->ri_rows * ri->ri_cols; i++) {
> - ri->ri_bs[i].uc = ' ';
> - ri->ri_bs[i].attr = attr;
> + if (ri->ri_flg & RI_CLEAR) {
> + ri->ri_alloc_attr(ri, 0, 0, 0, );
> + for (i = 0; i < ri->ri_rows * ri->ri_cols; i++) {
> + 

Re: Speed up UEFI framebuffer console

2018-08-26 Thread Kevin Lo
On Sat, Aug 25, 2018 at 05:38:12PM +0200, Mark Kettenis wrote:
> 
> Here is a diff to speed up the initial framebuffer console on amd64.
> It remaps the framebuffer write-combining early on, which speeds up
> writing to the framebuffer considerably.
> 
> Remapping is done using _bus_space_map().  Otherwise inteldrm(4) and
> radeondrm(4) will fail to attach (or even panic) because the graphics
> aperture can't be mapped.  This mapping stays around even if efifb(4)
> doesn't attach.  There is no good place to unmap it without risking
> some random kernel printf causing a fault.
> 
> The rasops(4) bit is a bugfix that probably should go in regardless.
> It makes sure we don't clear the character mapping if the RI_CLEAR
> flag isn't set.
> 
> Can somebody with a UEFI machine that has radeondrm(4) test this for
> me?

Works for me.  Tested with:

$ dmesg | grep radeondrm
radeondrm0 at pci1 dev 0 function 0 vendor "ATI", unknown product 0x665f rev 
0x81
drm0 at radeondrm0
radeondrm0: msi
radeondrm0: 1024x768, 32bpp
wsdisplay0 at radeondrm0 mux 1: console (std, vt100 emulation), using wskbd0



Speed up UEFI framebuffer console

2018-08-25 Thread Mark Kettenis
Here is a diff to speed up the initial framebuffer console on amd64.
It remaps the framebuffer write-combining early on, which speeds up
writing to the framebuffer considerably.

Remapping is done using _bus_space_map().  Otherwise inteldrm(4) and
radeondrm(4) will fail to attach (or even panic) because the graphics
aperture can't be mapped.  This mapping stays around even if efifb(4)
doesn't attach.  There is no good place to unmap it without risking
some random kernel printf causing a fault.

The rasops(4) bit is a bugfix that probably should go in regardless.
It makes sure we don't clear the character mapping if the RI_CLEAR
flag isn't set.

Can somebody with a UEFI machine that has radeondrm(4) test this for
me?


Index: arch/amd64/amd64/efifb.c
===
RCS file: /cvs/src/sys/arch/amd64/amd64/efifb.c,v
retrieving revision 1.17
diff -u -p -r1.17 efifb.c
--- arch/amd64/amd64/efifb.c12 Jul 2018 12:47:57 -  1.17
+++ arch/amd64/amd64/efifb.c25 Aug 2018 15:27:43 -
@@ -215,11 +215,6 @@ efifb_attach(struct device *parent, stru
ccol = ri->ri_ccol;
crow = ri->ri_crow;
 
-   if (bus_space_map(iot, fb->paddr, fb->psize,
-   BUS_SPACE_MAP_PREFETCHABLE | BUS_SPACE_MAP_LINEAR,
-   ) == 0)
-   ri->ri_origbits = bus_space_vaddr(iot, ioh);
-
efifb_rasops_preinit(fb);
ri->ri_flg &= ~RI_CLEAR;
ri->ri_flg |= RI_VCONS | RI_WRONLY;
@@ -428,6 +423,7 @@ efifb_efiinfo_init(struct efifb *fb)
fb->psize = bios_efiinfo->fb_height *
bios_efiinfo->fb_pixpsl * (fb->depth / 8);
 }
+
 void
 efifb_cnattach_common(void)
 {
@@ -450,6 +446,28 @@ efifb_cnattach_common(void)
 
ri->ri_ops.alloc_attr(ri, 0, 0, 0, );
wsdisplay_cnattach(_std_descr, ri, 0, 0, defattr);
+}
+
+void
+efifb_cnremap(void)
+{
+   struct efifb*fb = _console;
+   struct rasops_info  *ri = >rinfo;
+   bus_space_tag_t  iot = X86_BUS_SPACE_MEM;
+   bus_space_handle_t   ioh;
+
+   if (fb->paddr == 0)
+   return;
+
+   if (_bus_space_map(iot, fb->paddr, fb->psize,
+   BUS_SPACE_MAP_PREFETCHABLE | BUS_SPACE_MAP_LINEAR, ) == 0)
+   ri->ri_origbits = bus_space_vaddr(iot, ioh);
+
+   efifb_rasops_preinit(fb);
+   ri->ri_flg &= ~RI_CLEAR;
+   ri->ri_flg |= RI_CENTER | RI_WRONLY;
+
+   rasops_init(ri, efifb_std_descr.nrows, efifb_std_descr.ncols);
 }
 
 int
Index: arch/amd64/amd64/mainbus.c
===
RCS file: /cvs/src/sys/arch/amd64/amd64/mainbus.c,v
retrieving revision 1.44
diff -u -p -r1.44 mainbus.c
--- arch/amd64/amd64/mainbus.c  13 Jul 2018 08:30:34 -  1.44
+++ arch/amd64/amd64/mainbus.c  25 Aug 2018 15:27:43 -
@@ -171,6 +171,10 @@ mainbus_attach(struct device *parent, st
pvbus_identify();
 #endif
 
+#if NEFIFB > 0
+   efifb_cnremap();
+#endif
+
 #if NBIOS > 0
{
mba.mba_bios.ba_name = "bios";
Index: arch/amd64/include/efifbvar.h
===
RCS file: /cvs/src/sys/arch/amd64/include/efifbvar.h,v
retrieving revision 1.7
diff -u -p -r1.7 efifbvar.h
--- arch/amd64/include/efifbvar.h   25 Apr 2018 00:46:28 -  1.7
+++ arch/amd64/include/efifbvar.h   25 Aug 2018 15:27:43 -
@@ -26,6 +26,7 @@ struct efifb_attach_args {
 struct pci_attach_args;
 
 int efifb_cnattach(void);
+void efifb_cnremap(void);
 int efifb_is_console(struct pci_attach_args *);
 void efifb_cndetach(void);
 void efifb_cnreattach(void);
Index: dev/rasops/rasops.c
===
RCS file: /cvs/src/sys/dev/rasops/rasops.c,v
retrieving revision 1.54
diff -u -p -r1.54 rasops.c
--- dev/rasops/rasops.c 3 May 2018 10:05:47 -   1.54
+++ dev/rasops/rasops.c 25 Aug 2018 15:27:43 -
@@ -288,10 +288,12 @@ rasops_init(struct rasops_info *ri, int 
ri->ri_ops.copyrows = rasops_wronly_copyrows;
ri->ri_ops.eraserows = rasops_wronly_eraserows;
 
-   ri->ri_alloc_attr(ri, 0, 0, 0, );
-   for (i = 0; i < ri->ri_rows * ri->ri_cols; i++) {
-   ri->ri_bs[i].uc = ' ';
-   ri->ri_bs[i].attr = attr;
+   if (ri->ri_flg & RI_CLEAR) {
+   ri->ri_alloc_attr(ri, 0, 0, 0, );
+   for (i = 0; i < ri->ri_rows * ri->ri_cols; i++) {
+   ri->ri_bs[i].uc = ' ';
+   ri->ri_bs[i].attr = attr;
+   }
}
}