Commit 37a6d0a3 authored by Joe Rayhawk's avatar Joe Rayhawk

NVC0_Firmware: markdown cleanup

parent c6f5db1b
......@@ -5,132 +5,117 @@
## Status
[[A list of which cards do and don't need to load blob firmware at this point.|InstallDRM]]
[[A list of which cards do and don't need to load blob firmware at this point.|InstallDRM]]
## Instructions
do an [[mmio trace|MmioTrace]] of the blob (version < 270.xx preferred)
* Ensure that your kernel has MMIO tracing enabled
[[!format txt """
Kernel Hacking -> Tracers -> Memory mapped IO tracing
"""]]
* Boot up the system, without loading the blob or nouveau
* Mount debugfs and start the tracer
[[!format txt """
mount -t debugfs debugfs /sys/kernel/debug
echo mmiotrace > /sys/kernel/debug/tracing/current_tracer
cat /sys/kernel/debug/tracing/trace_pipe > mydump.txt &
"""]]
* Load the blob kernel module (insmod nvidia)
* run X or a CUDA application
* Stop the tracer
[[!format txt """
echo nop > /sys/kernel/debug/tracing/current_tracer
"""]]
Extract register writes from the trace and put them in binary files:
* 41a1c4 -> fuc41ad
* 4091c4 -> fuc409d
* 41a184 -> fuc41ac
* 409184 -> fuc409c
The important lines in the trace will look like this:
[[!format txt """
W 4 433.851950 1 0xXX41a1c4 0x2072614d 0x0 0
"""]]
where 0xXX41a1c4 is the register and 0x2072614d the value written
and put them in binary files in /lib/firmware/nouveau/
For Kepler, prefix the file names with "nvXX_", XX being the chipset id (so, nve4_fuc409c, for example).
[[!format txt """
#!/usr/bin/python
import struct, sys, re
# substitute the correct value for XX
registers = {
'XX41a1c4': 'fuc41ad',
'XX4091c4': 'fuc409d',
'XX41a184': 'fuc41ac',
'XX409184': 'fuc409c',
}
firmwares = dict((register, open(registers[register], 'wb')) for register in registers)
for line in open(sys.argv[1]):
line = line.split()
if len(line) < 5:
continue
for register in registers:
if not re.match(r'0x%s' % register, line[4]):
continue
if not line[5].startswith('0x'):
break
firmwares[register].write(struct.pack('@I', int(line[5][2:], 16)))
"""]]
do an [[MmioTrace]] of the blob (version < 270.xx preferred)
* Ensure that your kernel has MMIO tracing enabled
---
Kernel Hacking -> Tracers -> Memory mapped IO tracing
* Boot up the system, without loading the blob or nouveau
* Mount debugfs and start the tracer
mount -t debugfs debugfs /sys/kernel/debug
echo mmiotrace > /sys/kernel/debug/tracing/current_tracer
cat /sys/kernel/debug/tracing/trace_pipe > mydump.txt &
# Video firmware
* Load the blob kernel module (insmod nvidia)
* run X or a CUDA application
* Stop the tracer
Unlike the firmware you need above, there is no requirement on version. Up to nvidia 310.* will likely work. Newer versions are untested, but should still work.
echo nop > /sys/kernel/debug/tracing/current_tracer
Extract register writes from the trace and put them in binary files:
## Extracting kernel video firmware on fermi and kepler.
* 41a1c4 -> fuc41ad
* 4091c4 -> fuc409d
* 41a184 -> fuc41ac
* 409184 -> fuc409c
The important lines in the trace will look like this:
There are 2 sets of firmware for video decoding, one for kernel and one for userspace. Only nvc0 series need the userspace firmware. Kepler, and also nvd9 do **NOT** have userspace firmware.
W 4 433.851950 1 0xXX41a1c4 0x2072614d 0x0 0
The kernel parts can be obtained by doing a mmiotrace of a program using vdpau for video decoding, for example mplayer -vc ffmpeg12vdpau,ffh264vdpau,ffwmv3vdpau,ffvc1vdpau,ffodivxvdpau, somefile.mkv
where 0xXX41a1c4 is the register and 0x2072614d the value written
After you obtained the mmiotrace, look for the base offsets used by the firmware:
and put them in binary files in /lib/firmware/nouveau/
For Kepler, prefix the file names with "nvXX_", XX being the chipset id (so, nve4_fuc409c, for example).
[[!format txt """
$ demmio vdpau-mmiotrace | grep P.*P.*XFER_EXT_BASE
[0] 437.753081 MMIO32 W 0x084110 0x004de400 PBSP.XFER_EXT_BASE <= 0x4de40000
[0] 445.278672 MMIO32 W 0x085110 0x004dde00 PVP.XFER_EXT_BASE <= 0x4dde0000
[0] 445.938745 MMIO32 W 0x086110 0x004dd800 PPPP.XFER_EXT_BASE <= 0x4dd80000
#!/usr/bin/python
import struct, sys, re
$ demmio vdpau-mmiotrace | less
/RAMIN32.*4de40000 would get you to the start of the mmiotrace, from my log I could see the RAMIN32 writes end at 4de50918, so I need to grab 4de[45].* for BSP firmware:
# substitute the correct value for XX
registers = {
'XX41a1c4': 'fuc41ad',
'XX4091c4': 'fuc409d',
'XX41a184': 'fuc41ac',
'XX409184': 'fuc409c',
}
$ demmio vd-trace.xz 2>&1 | grep 'RAMIN32 .* 4de[45].* <=' | awk '{ print $7 }' | python -c \
"
import struct; import sys; fd = open(\"fuc084\", \"wb\");
for line in sys.stdin:
fd.write(struct.pack(\"@I\", int(line.rstrip(), 16)))
"
"""]]
This was just for PBSP, but the same applies to PVP with fuc085, and PPPP with fuc086. Put the resulting files in /lib/firmware/nouveau/
firmwares = dict((register, open(registers[register], 'wb')) for register in registers)
Offsets may differ, and it is recommended to check you don't end up with too big or too small a file. It *looks* like mine are multiples of 1000 bytes, on the nvidia 310 drivers.
for line in open(sys.argv[1]):
line = line.split()
if len(line) < 5:
continue
for register in registers:
if not re.match(r'0x%s' % register, line[4]):
continue
if not line[5].startswith('0x'):
break
firmwares[register].write(struct.pack('@I', int(line[5][2:], 16)))
---
# Video firmware
Unlike the firmware you need above, there is no requirement on version. Up to nvidia 310.* will likely work. Newer versions are untested, but should still work.
## Extracting kernel video firmware on fermi and kepler.
There are 2 sets of firmware for video decoding, one for kernel and one for userspace. Only nvc0 series need the userspace firmware. Kepler, and also nvd9 do **NOT** have userspace firmware.
The kernel parts can be obtained by doing a mmiotrace of a program using vdpau for video decoding, for example mplayer -vc ffmpeg12vdpau,ffh264vdpau,ffwmv3vdpau,ffvc1vdpau,ffodivxvdpau, somefile.mkv
After you obtained the mmiotrace, look for the base offsets used by the firmware:
$ demmio vdpau-mmiotrace | grep P.*P.*XFER_EXT_BASE
[0] 437.753081 MMIO32 W 0x084110 0x004de400 PBSP.XFER_EXT_BASE <= 0x4de40000
[0] 445.278672 MMIO32 W 0x085110 0x004dde00 PVP.XFER_EXT_BASE <= 0x4dde0000
[0] 445.938745 MMIO32 W 0x086110 0x004dd800 PPPP.XFER_EXT_BASE <= 0x4dd80000
$ demmio vdpau-mmiotrace | less
/RAMIN32.*4de40000 would get you to the start of the mmiotrace, from my log I could see the RAMIN32 writes end at 4de50918, so I need to grab 4de[45].* for BSP firmware:
$ demmio vd-trace.xz 2>&1 | grep 'RAMIN32 .* 4de[45].* <=' | awk '{ print $7 }' | python -c \
"
import struct; import sys; fd = open(\"fuc084\", \"wb\");
for line in sys.stdin:
fd.write(struct.pack(\"@I\", int(line.rstrip(), 16)))
"
This was just for PBSP, but the same applies to PVP with fuc085, and PPPP with fuc086. Put the resulting files in /lib/firmware/nouveau/
Offsets may differ, and it is recommended to check you don't end up with too big or too small a file. It *looks* like mine are multiples of 1000 bytes, on the nvidia 310 drivers.
---
## Extracting userspace video firmware on nvc0 series (fermi) (NOT NVD9!!)
Requirements:
Requirements:
* libvdpau-dev, libpciaccess-dev, libx11-dev
* [[valgrind-mmt|Valgrind-mmt]]
* build a recent envytools.git, and go to envytools.git/vdpow directory
* with nvidia drivers enabled and X server running, do:
* ` /usr/local/bin/valgrind --tool=mmt --mmt-trace-file=/dev/nvidia0 --mmt-trace-file=/dev/dri/card0 --mmt-trace-nvidia-ioctls --mmt-trace-nouveau-ioctls ./mmt_ufw 2>&1 | ./dumpstruct -m 10 `
Copy the resulting vuc-* files to /lib/firmware/nouveau/
* libvdpau-dev, libpciaccess-dev, libx11-dev
* [[Valgrind-mmt]]
* build a recent envytools.git, and go to envytools.git/vdpow directory
* with nvidia drivers enabled and X server running, do:
* ` /usr/local/bin/valgrind --tool=mmt --mmt-trace-file=/dev/nvidia0 --mmt-trace-file=/dev/dri/card0 --mmt-trace-nvidia-ioctls --mmt-trace-nouveau-ioctls ./mmt_ufw 2>&1 | ./dumpstruct -m 10 `
Copy the resulting vuc-* files to /lib/firmware/nouveau/
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment