Bug 91025

Summary: nouveau fails to run with NV5 [Riva TNT2 / TNT2 Pro]
Product: xorg Reporter: anonymissimus
Component: Driver/nouveauAssignee: Nouveau Project <nouveau>
Status: RESOLVED FIXED QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium    
Version: unspecified   
Hardware: x86 (IA32)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments:
Description Flags
dmesg > kernel_log.txt
none
sudo dd if=/dev/mem of=vbios.rom bs=1k skip=768 count=64
none
"fixed" vbios
none
dmesg > kernel_log.txt with kernel boot parameters log_buf_len=1M nouveau.config=NvBios=vbios-bug-91025-fixed.rom none

Description anonymissimus 2015-06-19 02:09:39 UTC
Created attachment 116588 [details]
dmesg > kernel_log.txt

sudo lspci -vnn:

01:00.0 VGA compatible controller [0300]: NVIDIA Corporation NV5 [Riva TNT2 / TNT2 Pro] [10de:0028] (rev 11) (prog-if 00 [VGA controller])
	Subsystem: Elsa AG Erazor III [1048:0c28]
	Flags: 66MHz, medium devsel, IRQ 11
	Memory at f4000000 (32-bit, non-prefetchable) [size=16M]
	Memory at f6000000 (32-bit, prefetchable) [size=32M]
	Expansion ROM at f5ff0000 [disabled] [size=64K]
	Capabilities: [60] Power Management version 1
	Capabilities: [44] AGP version 2.0

AFAICT there should be a "kernel driver in use: nouveau" line here, but I didn't overlook/forget to copy it. That's probably why xrandr doesn't let me set anything better than 1024x768.

log according to http://nouveau.freedesktop.org/wiki/Bugs/ attached, notice the nouveau error messages at ~12.xx.

The only way of dumping the video bios that worked for me was dd according to http://nouveau.freedesktop.org/wiki/DumpingVideoBios/.
vbtracetool didn't work due to not finding pci.h even after installing linux-headers while compiling.

OS/packages:
No clue about needed stuff here or how to find out versions. OS is fresh debian-8.1.0-i386-lxde-CD1.iso. All packages up to date according to synaptic and the normal update repos of this distro (current stable, stretch) as of 19.06.2015.

uname -r:
3.16.0-4-686-pae

Passing nouveau.agpmode=0 (or 1 or 2) in grub didn't help. (I think I did this correctly, as it seems I was correct with log_buf_len=1M too.)
Comment 1 anonymissimus 2015-06-19 02:13:10 UTC
Created attachment 116589 [details]
sudo dd if=/dev/mem of=vbios.rom bs=1k skip=768 count=64
Comment 2 Ilia Mirkin 2015-06-19 02:35:52 UTC
Hm fun, a non-M64 TNT2. I looked at the vbios dump you attached, and it indeed has the unknown opcodes. I tried flipping some bits to get it to parse, but it'd take a lot of manipulation to fix it.

Would you mind extracting the vbios using envytools's nvagetbios? It should have 2 diff methods, please try both of them. You can also look at the output with the nvbios tool.

Looks like 0x59 and 0x5a have 6 bytes worth of arguments each. And we have a hole there (i.e. 0x58 and 0x5b are both known) so it makes sense that they're real opcodes... should try decoding the asm...

Short-term you can add entries in the table in subdev/bios/init.c and have the function skip 7 bytes each (6 byte arg + 1 byte op).
Comment 3 Ilia Mirkin 2015-06-19 03:04:15 UTC
OK, looks like they're real opcodes, and not identical to other ones (at least not obviously so):

udcli -16 -s 2032 vbios.rom

The relevant code is:

000000000000015c 3c5a             cmp al, 0x5a            
000000000000015e 745b             jz 0x1bb                

000000000000016a 3c59             cmp al, 0x59            
000000000000016c 0f84a700         jz word 0x217           

00000000000001bb 53               push bx                 
00000000000001bc 662e8b37         mov esi, [cs:bx]        
00000000000001c0 2e8b5f04         mov bx, [cs:bx+0x4]     
00000000000001c4 662e8b07         mov eax, [cs:bx]        
00000000000001c8 0bff             or di, di               
00000000000001ca 7503             jnz 0x1cf               
00000000000001cc e8113e           call 0x3fe0             
00000000000001cf 5b               pop bx                  
00000000000001d0 83c306           add bx, 0x6             
00000000000001d3 e978ff           jmp 0x14e               

0000000000000217 662e8b37         mov esi, [cs:bx]        
000000000000021b 83c304           add bx, 0x4             
000000000000021e 53               push bx                 
000000000000021f 2e8b1f           mov bx, [cs:bx]         
0000000000000222 2e8b07           mov ax, [cs:bx]         
0000000000000225 bb6400           mov bx, 0x64            
0000000000000228 f7e3             mul bx                  
000000000000022a 5b               pop bx                  
000000000000022b 0bff             or di, di               
000000000000022d 7513             jnz 0x242               
000000000000022f 53               push bx                 
0000000000000230 e80842           call 0x443b             
0000000000000233 5b               pop bx                  
0000000000000234 32f6             xor dh, dh              
0000000000000236 66c1e210         shl edx, 0x10           
000000000000023a 8bd0             mov dx, ax              
000000000000023c 668bc2           mov eax, edx            
000000000000023f e89e3d           call 0x3fe0             
0000000000000242 83c302           add bx, 0x2             

Where 0x3fe0 is a write of eax to mmio reg esi. Not sure what the function at 0x443b does. Nothing simple though... something PLL-related, I think.

So looks like 0x5a is R[0..3] = VBIOS[4..5]. And 0x59 is... R[0..3] = who knows.
Comment 4 Ilia Mirkin 2015-06-19 05:34:31 UTC
OK, there are two patches available at

http://cgit.freedesktop.org/~darktama/nouveau/commit/?id=ca8fe8c9f37a56391fc83449af92088a2a38f3ea
http://cgit.freedesktop.org/~darktama/nouveau/commit/?id=a182357ef44bef38f0d42e0934f9fbc401761e8d

which add support for those 2 opcodes, based on my analysis of the assembly. Looking at other NV05 scripts, my decoding of it seems reasonable.

Those patches won't apply directly to a kernel tree, but it should be moderately easy to figure out what file those patches apply to. Give them a shot.
Comment 5 anonymissimus 2015-06-19 09:54:14 UTC
Sorry, I only know how to apply git c source code patches onto a git repository, not a Linux OS.
What I was expecting needing to do is to checkout nouveau's fixed code, build it and somehow install it over the version in the package manager/this distribution, at which point I would hopefully have a working driver.

In my first post I of course meant "jessie", not "stretch" (testing).

I succeeded at building nvagetbios and nvbios, but both fail:

anonymissimus@debian:/media/HD3_SOURCE/envytools/nva$ ./nvagetbios
WARN: Can't probe 0000:01:00.0
PCI init failure!

anonymissimus@debian:/media/HD3_SOURCE/envytools/nvbios$ ./nvbios mybios.rom
warning: No strap specified
fopen: No such file or directory
Failed to read VBIOS!
Comment 6 Ilia Mirkin 2015-06-19 15:21:37 UTC
(In reply to anonymissimus from comment #5)
> Sorry, I only know how to apply git c source code patches onto a git
> repository, not a Linux OS.

What is linux, but a git repository :) Anyways, if you're not comfortable building your own kernel, I guess you'll have to wait until these patches hit mainline and make it into pre-built kernels.

I didn't mark them for backporting since I didn't have a positive test result, but if you can test a kernel once these make it upstream (for linux kernel 4.2 I'd guess), we can then mark it for backports.

I can also give you a modified vbios image that uses other opcodes to achieve the same results if you like. You'd have to stick it in your initrd and add a kernel parameter to read from it instead of from the GPU. Let me know if you're interested.
Comment 7 Ilia Mirkin 2015-06-19 16:45:04 UTC
Created attachment 116600 [details]
"fixed" vbios

OK, so I've manually touched up the vbios. I had to do one slightly dodgy thing, but... it should probably be fine. In any case, the vbios is only executed on resume (or if it's a secondary GPU), so even if I messed it up, should be mostly fine.

In order to use it, put it in /lib/firmware (and make sure it's accessible when nouveau loads, so if it's a module loaded from initrd, it must be in the initrd), and then boot with

nouveau.config=NvBios=vbios-bug-91025-fixed.rom
Comment 8 anonymissimus 2015-06-19 21:13:10 UTC
Created attachment 116602 [details]
dmesg > kernel_log.txt with kernel boot parameters log_buf_len=1M nouveau.config=NvBios=vbios-bug-91025-fixed.rom
Comment 9 Ilia Mirkin 2015-06-19 21:15:08 UTC
(In reply to anonymissimus from comment #8)
> Created attachment 116602 [details]
> dmesg > kernel_log.txt with kernel boot parameters log_buf_len=1M
> nouveau.config=NvBios=vbios-bug-91025-fixed.rom

Seems happy enough. Any issues?
Comment 10 anonymissimus 2015-06-19 21:51:26 UTC
I'm kind of used to building applications such as envytools, but a kernel is likely too much (for the CPU/RAM especially).

Yes, thanks a lot, much better. nouveau is in use according to lspci and I can set the desired 1600x900 with xrandr (still 3 lines of shell script).
No issues for now, bug report can be closed.
Comment 11 Ilia Mirkin 2015-08-03 02:13:10 UTC
These patches are all now upstream (in 4.2-rc5), you should be able to drop the nouveau.config=NvBios=bla thing once you update your kernel.

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.