Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 8 Feb 2019 14:19:23 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        int19h@gmail.com
Cc:        bugs@freebsd.org
Subject:   Re: [Bug 230172] FreeBSD 11.2 fails to boot on Celeron J1900 after upgrade from 11.1
Message-ID:  <20190208123810.P1035@besplex.bde.org>
In-Reply-To: <bug-230172-227-O8veQUFmUq@https.bugs.freebsd.org/bugzilla/>
References:  <bug-230172-227@https.bugs.freebsd.org/bugzilla/> <bug-230172-227-O8veQUFmUq@https.bugs.freebsd.org/bugzilla/>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 7 Feb 2019 a bug that doesn't want replies@freebsd.org wrote:

> https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=230172
>
> --- Comment #30 from Pavel Minaev <int19h@gmail.com> ---
> To use X, you'll need to kldload drm_next_kmod. If you do that with sc driver
> in effect, your screen will go blank the moment you do it. But the system is
> still alive, and if you then run X, it'll work. I just made a little script
> that does both.

To fix sc, just sync its mode with the drm mode using vidcontrol
MODE_xxx if you can find such a mode.  Mode 280 (1024x768x32 graphics)
works on 3 systems with Intel graphics here using the non-port i915kms
module, except for 16 lines of corrupt pixels near the top of the screen,
and that can be fixed by higher magic.

sc then works better than vt even with the module loaded, at least in
-current.  It allows switching to all old vga and vesa modes, and
unloading i915kms, and restoring video after resume.

After loading i915kms, it doesn't work so well to switch the sc mode to
24 (80x25 VGA text).  First switch a mode compatible with the module.
sc uses the VESA BIOS to switch.  I use a vga utility to check that this
mode switch doesn't change any standard vga registers, but it is easy to
see if too much changed -- the screen will be garbage or remain black.
Switching to all other modes supported by sc (see vidcontrol -i mode for
the list) then works the same as without the module, except for the 16
lines of corruption.  Better switch back the common mode before using X.

Unloading i915kms corrupts leaves much more than 16 lines in graphics
modes corrupted.  Mode 24 still works but may take first switching to
another mode to reach.  For vt, unloading i915kms gives a black screen
and there is no way to recover since vt can't switch modes dynamically
except for the initial switch to use the module.

Loading i915kms again reduces the corruption left by unloading it by a
bit, but it is much more than on the first load.  It affects vt too
(but vt doesn't have the 16 lines of corruption after the first load).
The smaller corruption is that writing a pixel to any one of the 16
lines appears to write the same pixel to them all.

To restore video after resume, loading and unloading i915kms works for
me, after fixing resume for the new pae_mode = 1 case and working
around a bug in the VESA BIOS.  The bug is the same in 2 7-8 year old
Sandybridge laptops (HP 8460p and HP 8570p)and 1 4 year old Haswell
desktop.  To fix it, change vesa_state in kernel memory from 15 to 7.
Otherwise the bug gives a trap on a garbage pointer in the VESA BIOS.
This is only necessary using sc.  Video usually doesn't come back after
fixing this bug.  It comes back only on HP 8570p asnd this may depend
on a BIOS update (HP 8460p is similar but doesn't have BIOS update).

To fix the i915kms corruption, some magic order of i915kms loads and
unloads and suspends and resumes works for me.  I forget if this only
works on HP 8570p.  Since unloading i915kms leaves corruption, this
probably only does work on HP 8570p.  Useful orders on HP 8570p:
- start with bad corruption in graphics modes from i915kms load and unload
- switch mode to 24
- suspend.  Here is a script that edits vesa_state (it is missing error
   checking.  Don't run it if you don't have a kernel with vesa_state in
   it, but vesa_state is standard with sc):

     addr=0x$(nm /kernel|grep ' b vesa_state$' | cut -c1-8)
     echo $addr
     echo -n 7 | tr 7 '\007' | dd of=/dev/kmem bs=1 oseek=$addr count=1
- resume (video comes back)
- switch to a VESA graphics mode to verify that the corruption is fixed
- switch in advance to the mode that i915kms will set
- load i915kms (sc keeps working throughout).  You can also switch in advance
   at boot time using a tunable (?) to set the default mode.  Also load
   i915kms in the loader.  sc then again works better than vt since it
   starts in the right mode.
- oops, this only fixed the bad corruption.  The 16-line corruption is back.
- so we must be in the i915kms mode before suspend/resume.  We are in it now.
- suspend
- resume (video comes back).  All the corruption is fixed now.  Video comes
   back almost instantly and the corruption is fixed then.  USB and em take
   a long time to come back on this system (10-20 seconds).  Video only
   comes back visibly in normal syscons modes (text or graphics).  In libvgl
   graphics modes, the screen remains black and libvgl seems to be hung
   waiting for screen access.  Actually, it seems to have crashed.  It needs
   some fixes to not crash on startup in newer graphics modes.  It and old
   X using similar methods are good for showing the corruption.
- after doing this in libvgl, mode switches don't work to bring video back.
   So start another cycle.  Unload i1915kms to get video the its usual
   corruption from load/unload...

On a Haswell desktop:
- first load of i915kms followed by vidcontrol MODE_280 gives the 16 lines
   of corruption
- suspend (1 error writing a register from i915kms).  Oops, then a long
   timeout and GEM idle failure.  The suspend is aborted and video is never
   lost
- but this fixes the corruption!  Maybe a suspend bounce would do it even
   better
- after running libgvl in an unchanged mode to test this, libvgl works
   perfectly until exit when it leaves a black screen.  vidcontrol MODE_280
   then crashes due to a known bug in vidcontrol (libvgl didn't switch the
   mode back completely, so the font height is 0 and vidcontrol divides by
   this).
- vidcontrol MODE_24 to get a working mode (any text mode forces the
   height to nonzero)
- vidcontrol MODE_280 to get a working desired mode
- unload i915kms (gives full corruption)
- vidcontrol MODE_24 to try the suspend/resume from there
- suspend (works)
- resume (works except no video.  The external LED monitor shows the state
   of the video signal better than a laptop)
- load i915kms (still no video)
- unload i915kms (restores video according to monitor.  Screen is still
   black)
- vidcontrol MODE_280 (restores video fully corrupted to graphics screen)
- vidcontrol MODE_24 (restores video uncorrupted to text screen).

So the load/unload trick only works for restoring video in text modes
after suspend/resume loses video, but when suspend/resume doesn't lose
video it fixes bugs in load and load/unload of i915kms for all modes.

Hopefully the i915kms port works better, but I don't like to use even
non-port modules.

The i915kms non-port module fails a little differently in FreeBSD-11:
- it fails just like in -current with pae_mode = 0.  Same corruption.
   It tends to hang on unload, so the load/unload trick doesn't work.
   Worse than the hang, it tends to panic for something to do with
   fictitious pages on the second load.  pae_mode = 1 somehow fixes this.
- resume was broken in -current before yesterdy with pae_mode = 1,
   so the suspend/resume trick didn't work.

i915kms maps the frame buffer, and sc maps it again in graphics modes at
a different address.  Both mappings seem to have the 16-line corruption.
I didn't look at the corruption after unload.  sc remaps the frame buffer
on every non-null mode switch, so the corruption seems to be from a
hardwre mapping.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20190208123810.P1035>