On my Panasonic R1N laptop (uses an i830 chip) mplayer causes an unhandled exception to be logged by the X server. This is the result (apparently) of a general protection fault handled by the linux int10 module due to a BIOS call to handle power management while the video overlay is active.
Created attachment 1866 [details] [review] Patch which fixes it The attached patch fixes the exception but doesn't do it in a particularly pretty way.
Just confirmed that this does -not- happen without dualhead enabled
Created attachment 1867 [details] [review] Do not disable all pipes patch Try this patch which should hopefully fix it.
(In reply to comment #3) > Created an attachment (id=1867) [edit] > Do not disable all pipes patch > > Try this patch which should hopefully fix it. Unfortunately it fixes nothing to do with this problem. If you look at the log after sticking a debug print at the top of the I830DisplayPowerManagementSet function, you'll see that the error happens when I830DisplayPowerManagementSet calls SetPipeAccess (which calls SetBIOSPipe), and later (in the same function) where it makes its own custom int10 call with ax=4f10 Then the error is repeated for the 2nd head.
Created attachment 1868 [details] Log with patches applied This is the log created with both of your patches applied and a debug print statement at the top of I830DisplayPowerManagementSet
David, Just because it calls SetBIOSPipe and that's where the crash happens, something before it causes the BIOS to get upset. The logic behind the patch is that the plane is being disabled in which the BIOS is being set to. So don't think it has nothing to do with it.
(In reply to comment #6) > David, Just because it calls SetBIOSPipe and that's where the crash happens, > something before it causes the BIOS to get upset. The logic behind the patch is > that the plane is being disabled in which the BIOS is being set to. Fair enough. I just wanted to make sure you had the largest possible amount of background information.
Right, so I need a little more information on what you are doing to trigger the problem. I can see you are playing a video, do you then do 'xset dpms ...' to force a DPMS mode or something else ?
(In reply to comment #8) Actually, I'm not doing anything. mplayer makes some kind of call (I gather when it starts) to prevent the screen from blanking when a video is playing. I'm guessing that when mplayer shuts down, it restores the previous blanking status, and this is when the bug is triggered.
Presumably the video is constantly on the first head and not being moved around to the second ?
Oh, can you attach your config too ?
Created attachment 1869 [details] Xorg configuration The video's always staying on the first head. I haven't been moving it back and forth or anything particularly strange. Driver options in config have been trimmed down to a minimum.
Created attachment 1870 [details] [review] Avoid unnecessary pipe switch This patch should avoid the problem for now, although I suspect it can re-occur if you moved the video to the second head. I'll need to dig deeper into this.
Hmm, that doesn't work. Instead of 2 exceptions, I now get 3. By the looks of the stack, it first calls GetBIOSPipe (this causes an exception), then calls SetBIOSPipe (which causes an exception), then calls the x86 emulator/vm86emu code with 4f10 in ax. Is there some way to set up some sane state on the card before making BIOS calls? Also, is there any other way to cause I830DisplayPowerManagementSet to be called? I've only found mplayer to do this... xset doesn't seem to.
Created attachment 1872 [details] [review] Dont switch pipe unnecessarily (replacement) Sorry, made an error on that last patch. This one should avoid the problem.
Having said that though. I think the BIOS got messed up well before the call to I830DisplayPowerManagementSet. And therefore even any other BIOS call might get to this exception crash. We might just be postponing the problem with that last patch. So we need to trace which BIOS call was issued last before getting to this stage and find out why it caused the BIOS to get confused.
OK this definitely happens without Xv active. Finally confirmed that. 'xset dpms force <anything>' certainly causes the same problem. So this is definitely a dualhead/dpms interaction. I've changed the summary appropriately.
Comment on attachment 1866 [details] [review] Patch which fixes it This doesn't fix the problem -- it only masks it in the case of mplayer
Can you think of any other functions that make BIOS calls on i830 while the card is in a fully initted state? I tried switching to console; but this first restores the HW state using VESA BIOS calls and such before it calls SetBIOSPipe. I'd like to see if there's another example of this (which I'll test); or if perhaps this is an isolated example of a function that makes a BIOS call during "normal" operation.
BIOS calls can happen at various times depending on what's happening. Your gonna have to trace the driver calls and find out which one is causing the BIOS to get messed up. You've already got the debug enabled, it's just a case of backtracking through it.
Comment on attachment 1872 [details] [review] Dont switch pipe unnecessarily (replacement) This causes dualhead to not function at all. The second head (in this case the LFP) displays nothing, and the first head is useless (can't pull up menu for window manager).
Created attachment 1873 [details] [review] Disable GetModeSupport and GetLFPCompMode Try this David. It disables two BIOS calls that are not required, but are used for informational purposes. I've had problems with these on other systems, so I may remove them altogether if it works for you.
Comment on attachment 1873 [details] [review] Disable GetModeSupport and GetLFPCompMode Don't use this. It's completely bogus. I'll go and grab a coffee :-)
Comment on attachment 1873 [details] [review] Disable GetModeSupport and GetLFPCompMode Argh, wrong patch. Definately use this.
Comment on attachment 1872 [details] [review] Dont switch pipe unnecessarily (replacement) This one is quite rightly bogus. This is where I go and get my coffee.
As for the confusion over the last few posts to this. Please let me know what happens with this patch David... https://bugs.freedesktop.org/attachment.cgi?id=1873
I tried with your patch to disable GetModeSupport and GetLFPComp; no difference. I disabled acceleration (Option "noaccel" on both heads) to eliminate possible interaction due to Xv init or other such things; no difference. This pretty much left me with the following running between the last SetBIOSPipe call that succeeded, and the one that failed: - ResetState - SetHWOperatingState - SetFenceRegs - I830InitHWCursor - I830BIOSAdjustFrame - I830BIOSScreenInit - Bunch of other cursor functions - and right before the SaveBIOSPipe calls, etc -- I830BIOSSaveScreen I haven't forgotten that your first patch dealt with this. What's the purpose of this function?
Created attachment 1874 [details] [review] Cleans up PM func This just cleans up the power management function. It eliminates redundant code copy-and-pasted from vbe.c and simplifies the checks for the function from whence the code was ripped. It's not pertinent to this per se, but it reduces the line count... and that's good IMO :)
OK more things I tried. 1) #if 0'd out the whole I830BIOSSaveScreen function -- no difference 2) put I830Sync and DO_RING_IDLE above all the BIOS calls in PM func -- no diff
You can use Option "swcursor" to remove all the cursor calls.
Also, I'd put the function call... SetPipeAccess(pScrn); at the start of each function that's called before the DPMS call. And see if that narrows down the functions to which the problem occurs.
OK, I enabled swcursor, I put SetPipeAccess at the top of every function except the init ones (sig11 if I did that). Result: Nothing blows up. No exceptions, no nothing. I put SetPipeAccess at the top of I830BIOSSaveScreen -- and X locks up immediately after displaying the crosshatch pattern and the X cursor. Nothing in the log about SetBIOSPipe either, interestingly enough, when that happens. This is total guesswork, but could it be something like a buffer offset being wrong with dualhead so that some scratch RAM or something used by the BIOS is stomped on when, say, an offscreen pixmap is allocated?
I doubt it. All my machines run dual head without this type of problem. So, you are using "noaccel" & "swcursor" and it still emits the same exception ? Can you post another log with these two options enabled ?
Created attachment 1881 [details] Xorg log, noaccel + swcursor Xorg log with noaccel and swcursor enabled; dualhead + xinerama (though with/without makes no difference)
Oh, another question -- do you end up with Xv corruption on your setup? Offscreen pixmaps seem to collide with the overlay. I do here; that's why I ask.
I did get corruption - yes, and I've fixed that in my driver. But it's not the cause of this problem. Can you try adding a 'return;' immediately in the function SetBIOSMemSize().
Added a 'return' at the top of SetBIOSMemSize; no difference. Do you have a patch ready for the Xv corruption fix?
I've just committed the Xv fix. As for the driver, Can you make sure that there are DPRINTF's at the start of every function to ensure the trace in the log file is accurate.
Another question. Once running X, and without running mplayer, essentially from a fresh startup, can you VT switch at all ?
I've tried switching VTs; this works fine, before and after running mplayer / whatever else. I'll play around with the driver some more tonight.
Ugh. I just tried pretty much everything I could think of, in rapid-fire succession. So far as I can tell, I modified every function that modified registers or sent stuff out via the ring buffer to print out when it was running. I got to the point where NOTHING was (apparently) running after the last SetBIOSPipe. I defanged LidTimer just in case, and put SetBIOSPipe at the top and bottom of I830BIOSSaveScreen. The story is -- as soon as the driver's done running the init function, SetBIOSPipe fails with the usual exception. At the top -and- bottom of I830BIOSSaveScreen -- so it has nothing to do with this function. So that leaves me with, well, nothing more to test. I even tried adjusting the base of memory forward by 256k or so, just to see if that did anything -- didn't seem to (pI830->LinearAddr = pI830->pEnt->device->MemBase + 0x40000). I limited VideoRAM to 4096kb, just for fun - no difference. Got any ideas? I'm totally out; and that's kind of remarkable.
OK I modified the register dumper to dump a few more registers; maybe you can make heads or tails out of the output. I don't know if I've thrown in i810 registers there, because i810_reg.h isn't particularly clear on what's what. I just threw in whatever looked relevant. As usual, this is with swcursor and noaccel 0x71400 == 0x8104008e DISPLAY_CNTL == 0x80000000 PIPEBCONF == 0x80000000 DISPLAY_BASE == 0x00000000 SWF0 == 0x00020801 SWF1 == 0x00001508 SWF2 == 0x00200155 SWF3 == 0x45450000 SWF4 == 0xc0000000 SWF5 == 0x00008249 SWF6 == 0x00000000 ADPA == 0x80000018 DVOA == 0xc000409c DVOA_SRCDIM == 0x00000000 DVOB == 0x00000000 DVOB_SRCDIM == 0x00000000 LVDS == 0x00000000 LP_RING TAIL == 0x00000000 LP_RING HEAD == 0x00000000 LP_RING START == 0x00000000 LP_RING LEN == 0x00000000 PGETBL_CTL == 0x0ff60001 FENCE == 0x00000000 HWSTAM == 0xffffffff The only thing I noticed is that SWF3 changes on its own. Modifying SWF3 manually results in some funny sync effects on the CRT (wiggling); so I suppose it has something to do with sync (duh).
Oh yeah. That register dump is the same before and after SetBIOSPipe starts causing exceptions.
Can you try this..... In the DPMS function at the top, add this... SetBIOSPipe(pScrn, 0); and leave the rest of the function as is, with no patches from either of us.
Just tried this. No difference. I've been looking at figuring out what code the int10 call actually executes; what would be the best procedure for going about this? I know enough x86 assembly to get by here; and I can always refer to a reference if I don't know. I'm thinking if I knew what code was actually executing, I might have more of a clue about how to go about solving the problem.
Use gdb to single step through the call from a remote ssh session.
Hmm, that'll work in the case of the vm86 calls? I was thinking more along the lines of dumping the BIOS to a file and printing out where the int10 code is calling in it. But I'm all for better ideas.
Go with what your comfortable with.
(In reply to comment #41) The thing is, if you are VT switching fine after the Xserver is up and running, then you should notice that SetBIOSPipe also gets called. That's why I asked if VT switching was working. So, if that is working, then it's very strange that the DPMS call into SetBIOSPipe would cause this exception, especially after the Xserver is up and running. I would probably step through what happens when the Xserver has finished initialization to the point where the DPMS function is called and see what really is going on. Use an Xserver with very limited clients. Just starting X with 'xinit' should just get you an xterm enough to run the 'xset dpms ...' command.
Also, Egbert (also monitoring this) might be able to provide help on debugging BIOS images. He's done it before.
Created attachment 1898 [details] xf86EnableAccess traces compared So I got my 2nd machine set up, etc, and tooled around in gdb a bit. The output shows some stuff here that looks a bit shaky to me. The BusAccess member of pScrn is initialized here, but access is not (in the dualhead case). However, when pciSetBusAccess is entered, nothing is done. This wouldn't -seem- to be the intent of these functions... I've been doing this all on 2.6.10-rc3; tried on 2.6.7-rc2 just recently, and no difference. This is to eliminate the possibility of a recent kernel change mucking things up.
Further explanation on the gdb output: This function is called when the dpms handler is set up to be executed. DPMSSet is called, it calls the xf86EnableAccess function, which calls I830BIOSSaveScreen; then the I830DisplayPowerManagementSet function is called. This is why I'm suspicious of this particular item. There doesn't seem to be anything else which would directly affect this in the trace I did. Mind you it was not exhaustive, and particularly in this "field" I seem to be more wrong than right.
David, Have you tried my recent driver ?? What's the status at your end on this ??
David - do you still have the machine for testing this ??
I'm closing this as FIXED now, as I'm pretty sure the driver in CVS as of today will have made an impact on this. Re-open if there's still troubles.
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.