Commit 8e8289df authored by Joe Rayhawk's avatar Joe Rayhawk

moin2mdwn: convert page NVC0_Firmware

parent 81bf222f
= Firmware =
== Status ==
[[InstallDRM#Firmware|A list of which cards do and don't need to load blob firmware at this point.]]
== Instructions ==
do an [[MmioTrace|mmio trace]] 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 &
}}}
* Load the blob kernel module (insmod nvidia)
* run X or a CUDA application
* Stop the tracer
{{{
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:
{{{
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).
{{{
#!/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)))
}}}
----
= 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:
* 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/
# Firmware
## Status
[[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)))
"""]]
---
# 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:
[[!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
$ 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:
* 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/
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