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.c    12 Jul 2018 12:47:57 -0000      1.17
+++ arch/amd64/amd64/efifb.c    25 Aug 2018 15:27:43 -0000
@@ -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,
-                   &ioh) == 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, &defattr);
        wsdisplay_cnattach(&efifb_std_descr, ri, 0, 0, defattr);
+}
+
+void
+efifb_cnremap(void)
+{
+       struct efifb            *fb = &efifb_console;
+       struct rasops_info      *ri = &fb->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, &ioh) == 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 -0000      1.44
+++ arch/amd64/amd64/mainbus.c  25 Aug 2018 15:27:43 -0000
@@ -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 -0000      1.7
+++ arch/amd64/include/efifbvar.h       25 Aug 2018 15:27:43 -0000
@@ -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 -0000       1.54
+++ dev/rasops/rasops.c 25 Aug 2018 15:27:43 -0000
@@ -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, &attr);
-               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, &attr);
+                       for (i = 0; i < ri->ri_rows * ri->ri_cols; i++) {
+                               ri->ri_bs[i].uc = ' ';
+                               ri->ri_bs[i].attr = attr;
+                       }
                }
        }
 

Reply via email to